使用C#启用PowerShell的执行策略

4
我有一个调用PowerShell的ASP.NET MVC 4页面。但是,我遇到了一个问题,因为我正在使用的一个模块没有签名,所以我必须启用“Unrestricted”策略。如何强制PowerShell子进程使用“Unrestricted”策略?
我已经在脚本中启用了此选项,但被忽略了。当我试图在代码中设置该策略时,会抛出异常。
    using (Runspace myRunSpace = RunspaceFactory.CreateRunspace())
    {
        myRunSpace.Open();

        using (PowerShell powerShell = PowerShell.Create())
        {
            powerShell.Runspace = myRunSpace;
            powerShell.AddCommand("Set-ExecutionPolicy").AddArgument("Unrestricted");
            powerShell.AddScript(script);

            objectRetVal = powerShell.Invoke();
        }
    }

2
异常信息是什么? - SLaks
1
生成自签名证书,将 Web 应用程序的身份设置为信任该证书,然后签署脚本是否有帮助?(似乎没有办法创建一个带有类似于 PowerShell.exe 的 -ExecutionPolicy 参数的 Runspace。) - Richard
感谢提供指针。我已经在用户和计算机的注册表中设置了我的执行策略为RemoteSigned。然后,我对我正在使用的模块以及运行的脚本进行了自签名。 - albal
5个回答

14

对于 PowerShell 5.1 和 PowerShell 7 Core,您可以使用一个 ExecutionPolicy 枚举 来设置执行策略,方法如下:

using Microsoft.PowerShell;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
...
public class MyClass
{
     public void MyMethod() 
     {
          // Create a default initial session state and set the execution policy.
          InitialSessionState initialSessionState = InitialSessionState.CreateDefault();
          initialSessionState.ExecutionPolicy = ExecutionPolicy.Unrestricted;

          // Create a runspace and open it. This example uses C#8 simplified using statements
          using Runspace runspace = RunspaceFactory.CreateRunspace(initialSessionState);
          runspace.Open();

          // Create a PowerShell object 
          using PowerShell powerShell = PowerShell.Create(runspace);

          // Add commands, parameters, etc., etc.
          powerShell.AddCommand(<command>).AddParameter(<parameter>);

          // Invoke the PowerShell object.
          powerShell.Invoke()
     }
}

对于 PS 6 及以上版本,如果您不在 Windows 上运行,请注意以下重要事项,来自文档:从 PowerShell 6.0 开始,针对非 Windows 计算机,默认执行策略为 Unrestricted,并且无法更改。 Set-ExecutionPolicy cmdlet 可用,但 PowerShell 显示控制台消息,指出它不受支持。来源:https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.security/set-executionpolicy?view=powershell-7 - Jacob Archambault
这应该是被接受的答案。 - SuperJMN

12

如果您只需要运行一个脚本而不需要交互,您可以通过命令提示符设置执行策略,方法如下:

string command = "/c powershell -executionpolicy unrestricted C:\script1.ps1";
System.Diagnostics.Process.Start("cmd.exe",command);

不错的想法 - 这让我达到了我现在需要的目标,同时也发现了其他的一些东西。 - albal

5

您需要使用参数-Scope = CurrentUser:

  powershell.AddCommand("Set-ExecutionPolicy").AddArgument("Unrestricted")
    .AddParameter("Scope","CurrentUser");

2

这与@kravits88的答案相同,但不显示cmd:

static void runPowerShellScript(string path, string args) {
        ProcessStartInfo startInfo = new ProcessStartInfo();
        startInfo.FileName = "cmd.exe";
        startInfo.Arguments = @"/c powershell -executionpolicy unrestricted " + path + " " + args;
        startInfo.UseShellExecute = false;
        startInfo.WindowStyle = ProcessWindowStyle.Hidden;
        startInfo.CreateNoWindow = true;
        Process process = new Process();
        process.StartInfo = startInfo;
        process.Start();
    }

0
我的解决方案是为我从IIS Express运行的模块和脚本自签名。我仍在开发中,发现IIS Express无法看到你可能已经安装在\System32\WindowsPowerShell...\Modules路径下的所有模块。我将我正在使用的模块移动到另一个驱动器,并使用该位置将模块导入到我的脚本中。
谢谢回复 :-)

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