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

3r1*_*r1c 4 c# powershell powershell-sdk executionpolicy

我尝试结合 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(); 
Run Code Online (Sandbox Code Playgroud)

在我的 powershell 脚本中,我有以下参数:

Param(
[String]$key
)
Run Code Online (Sandbox Code Playgroud)

但是,当我执行此操作时,会出现以下异常:

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.
Run Code Online (Sandbox Code Playgroud)

mkl*_*nt0 7

在不知道您的具体问题是什么的情况下,请注意您的 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();
Run Code Online (Sandbox Code Playgroud)

注意:如果在执行 PowerShell 脚本期间发生终止.Invoke()错误,该方法只会引发异常。更典型的非终止错误是通过 报告的。.Streams.Error

  • @AbrahamZinala:作为一个明确的例外,_PowerShell (Core) 7+_ 现在允许您在 _next_ 行上放置“|”以继续管道。也就是说,虽然 Windows PowerShell 仅支持“Get-Date |<newline> Format-List”等,但 PowerShell (Core) 7+ 现在也支持“Get-Date<newline>|”。Format-List`,尽管仅在_scripts_中,因为_交互式_`Get-Date`会在您有机会继续语句之前自行执行(除了在`{ ... }`内部)。 (3认同)
  • @AbrahamZinala:没有续行字符。在 C# 中,因为逻辑是相反的:一条语句,无论它跨越多少行,都仅由 `;` 终止。在 PowerShell 中,不需要显式语句终止,在某些情况下,您可以在没有行结束反引号的情况下逃脱,即当语句明确_不完整_时,特别是在行结束符“|”之后,与上面的“ps”示例类似但不相同:行结束符“.” - 也就是说,“.”必须位于该行的末尾,以便 PowerShell 知道该语句继续。 (2认同)