c# PowerShell脚本不能使用ExecutionPolicy



我正在尝试用c#在。netcore上运行PowerShell脚本。

我已经尝试了许多不同的解决方案,但他们似乎都没有工作。我只是想执行一个PowerShell脚本,并设置ExecutionPolicies和Scope使其工作。但是我总是得到一个异常,ExecutionPolicies不允许我以这种方式运行脚本。

尽管使用下面的实际配置和代码,但在到达.Invoke();之后,我没有从调试器获得任何反馈是执行。等待响应并让软件在后台做它的事情总是会导致stackoverflow异常。

commandParameters是一个简单的Dictionary<string,>

对此有什么想法吗?

欢呼。


var iss = InitialSessionState.CreateDefault2();
// Set its script-file execution policy.
iss.ExecutionPolicy = Microsoft.PowerShell.ExecutionPolicy.Unrestricted;
iss.ExecutionPolicy = (ExecutionPolicy)Microsoft.PowerShell.ExecutionPolicyScope.CurrentUser;
// Create a PowerShell instance with a runspace based on the 
// initial session state.
PowerShell ps = PowerShell.Create(iss);
ps.AddCommand(path + "\" + fileName);
ps.AddParameters(commandParameters);
var results = ps.InvokeAsync().GetAwaiter().GetResult();

  • 分配给iss.ExecutionPolicy只控制当前进程的执行策略.

  • 分配Microsoft.PowerShell.ExecutionPolicyScope值,因为它是无关的枚举它定义了执行策略范围,仅与Set-ExecutionPolicyGet-ExecutionPolicycmdlet相关。这个不相关的枚举的数值恰好与相应的[Microsoft.PowerShell.ExecutionPolicy]枚举值重叠,因此策略scopeCurrentUser映射到策略RemoteSigned(值0x1)。

    • 实际上,您的第二个iss.ExecutionPolicy = ...赋值覆盖第一个赋值,并将进程范围执行策略设置为RemoteSigned
    • 进程作用域执行策略,即对于当前进程只有,是唯一可以通过初始会话状态设置的策略;关于如何更改持久作用域的策略,请参阅下一节。

因此,iss.ExecutionPolicy = Microsoft.PowerShell.ExecutionPolicy.Unrestricted;单独足以在当前会话中调用*.ps1文件-移除第二个iss.ExecutionPolicy = ...赋值。


如果要持久修改执行策略,必须使用带有适当参数的.AddCommand('Set-ExecutionPolicy'),并且调用该命令。警告:

  • 更改持久当前用户配置也对常规PowerShell会话(交互会话/CLI调用)在相应的PowerShell版本中生效。

  • 相反,如果您更改了持久的机器配置—这需要使用提升运行(作为admin):

    • 使用Windows PowerShellSDK,此更改也对常规PowerShell会话生效。
    • 使用PowerShell (Core)SDK,它只对手头的SDK项目生效[1]
  • 查看示例代码的答案

警告:

  • 如果当前用户/机器的执行策略是通过gpo(组策略对象)控制的,你基本上不能通过编程重写它(通过GPO更改除外)。

  • 检查基于gpo的策略是否生效:

    • 运行Get-ExecutionPolicy -List以优先级降序列出为每个可用范围定义的策略。
    • 如果MachinePolicyUserPolicy作用域的值Undefined作用域的值不同,则GPO策略生效(不带参数运行Get-ExecutionPolicy以查看当前会话的有效策略)。

基于gpo的策略阻止脚本文件执行时的有限解决方案:

假设以下所有;脚本文件*.ps1文件:

  • 您的脚本文件不调用其他脚本文件。
  • 它(直接或间接)不加载在导入时碰巧调用脚本文件的模块。
  • 你的脚本文件不依赖于知道自己的位置(目录)或磁盘上的名称。

您可以将脚本文件的内容装入字符串并将该字符串传递给SDK的.AddScript()方法,如下所示:

using (var ps = PowerShell.Create()) {
var results =
ps.AddScript(File.ReadAllText(path + "\" + fileName))
.AddParameters(commandParameters)
.Invoke();
}

[1]Windows PowerShell将执行策略存储在注册表中,常规会话和SDK都会查询该注册表。相比之下,PowerShell (Core)将它们存储在powershell.config.json文件中,并且在机器策略的情况下,与PowerShell可执行文件(DLL)一起存储。因为SDK项目有自己的可执行文件,随之而来的JSON文件不是被定期PowerShell的可执行文件(核心)安装。

相关内容

  • 没有找到相关文章