如何使用C#执行PowerShell脚本并设置执行策略?

4

我尝试结合stackoverflow的两个答案 (第一个 & 第二个)

InitialSessionState iss = InitialSessionState.CreateDefault();
// Override ExecutionPolicy

PropertyInfo execPolProp = iss.GetType().GetProperty(@"ExecutionPolicy");
if (execPolProp != null && execPolProp.CanWrite)
{
    execPolProp.SetValue(iss, ExecutionPolicy.Bypass, null);
}
Runspace runspace = RunspaceFactory.CreateRunspace(iss);
runspace.Open();

Pipeline pipeline = runspace.CreatePipeline();

//Here's how you add a new script with arguments
Command myCommand = new Command(scriptfile);
CommandParameter testParam = new CommandParameter("key","value");
myCommand.Parameters.Add(testParam);

pipeline.Commands.Add(myCommand);

// Execute PowerShell script
results = pipeline.Invoke(); 

在我的PowerShell脚本中,我有以下参数:
Param(
[String]$key
)

然而,当我执行此操作时,我会得到以下异常:

System.Management.Automation.CmdletInvocationException: Cannot validate argument on parameter 'Session'. 
The argument is null or empty. 
Provide an argument that is not null or empty, and then try the command again.
1个回答

6

在不知道你具体问题的情况下,需要注意的是,你的C#代码可以大大简化,这也可能解决你的问题:

  • 为了设置会话的执行策略,没有必要采用反射

  • 使用PowerShell类的实例大大简化了命令调用过程。

// Create an initial default session state.
var iss = InitialSessionState.CreateDefault2();
// Set its script-file execution policy (for the current session only).
iss.ExecutionPolicy = Microsoft.PowerShell.ExecutionPolicy.Bypass;

// Create a PowerShell instance with a runspace based on the 
// initial session state.
PowerShell ps = PowerShell.Create(iss);

// Add the command (script-file call) and its parameters, then invoke.
var results =
  ps
   .AddCommand(scriptfile)
   .AddParameter("key", "value")
   .Invoke();

注意:只有在执行PowerShell脚本期间发生终止错误时,.Invoke()方法才会抛出异常。相反,更典型的非终止错误是通过.Streams.Error报告的。

这很有趣。那么,在C#中,您不必像在PowerShell中一样标记行连续性(即:反引号(`))吗? - Abraham Zinala
2
@AbrahamZinala:在C#中没有行连续字符,因为逻辑是相反的:一个语句,无论跨越多少行,只有在结束时才会终止。在PowerShell中,不需要显式语句终止符,你可以在某些情况下不使用行尾反斜杠,特别是当语句明显不完整时,尤其是在行尾|之后,类似于上面的ps示例:行尾. - 也就是说,必须在行末,PowerShell才知道该语句是否继续。 - mklement0
3
作为一个明确的例外,PowerShell (Core) 7+现在允许你在下一行上放置一个 | 来继续管道。也就是说,虽然Windows PowerShell仅支持例如 Get-Date |<newline> Format-List,而 PowerShell(Core) 7+ 现在也支持 Get-Date<newline>| Format-List,尽管仅限于脚本,因为交互式地执行 Get-Date语句时,在你有机会继续语句之前它会先被执行(除了在 { ... } 中)。 - mklement0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接