简体   繁体   English

在 C# 中检查 PowerShell 执行策略的最佳方法是什么?

[英]What is the best way to check PowerShell Execution Policy in C#?

When you run Get-ExecutionPolicy in PowerShell, it gets the effective execution policy .当您在 PowerShell 中运行Get-ExecutionPolicy时,它会获取有效的执行策略 I need to know the best way to get that information in C#.我需要知道在 C# 中获取该信息的最佳方式。 I don't need to know how to change it like many other questions about PowerShell Execution Policy, I just need to know how to get it in C#.我不需要像许多其他关于 PowerShell 执行策略的问题一样知道如何更改它,我只需要知道如何在 C# 中获取它。

Note:笔记:

  • PowerShell execution policies apply only on Windows . PowerShell 执行策略仅适用于 Windows

  • With respect to Windows, the answer below covers both PowerShell editions.对于 Windows,下面的答案涵盖了两个 PowerShell 版本。


It can be inferred from the docs that boxdog pointed to in a comment, but to spell it out:可以从boxdog在评论中指出的文档中推断出来,但要拼写出来:

using System;
using System.Management.Automation;

namespace demo
{
  class ConsoleApp {
    static void Main() {
      using (var ps = PowerShell.Create()) {
        var effectivePolicy = ps.AddCommand("Get-ExecutionPolicy").Invoke()[0].ToString();
        ps.Commands.Clear();
        Console.WriteLine("Effective execution policy: " + effectivePolicy);
      }
    }
  }
}

Note:笔记:

  • The above assumes that you're using the PowerShell SDK - see this answer for the appropriate NuGet package to add to your project.以上假设您使用的是 PowerShell SDK - 请参阅此答案以了解要添加到项目中的适当 NuGet 包。

  • If you're using a PowerShell (Core) 7+ SDK, additional considerations apply:如果您使用的是PowerShell (Core) 7+ SDK,则需要考虑其他注意事项:

    • On Unix-like platforms, execution policies fundamentally do not apply ( Unrestricted is reported, though in effect it is Bypass ), so the following applies to Windows only:类 Unix平台上,执行策略基本上不适用(报告了Unrestricted ,尽管实际上它是Bypass ),因此以下仅适用于 Windows:

    • The LocalMachine scope of any - by definition install-on-demand - PowerShell (Core) 7+ version does not apply;任何的LocalMachine范围 - 根据定义按需安装 - PowerShell (Core) 7+ 版本适用; only - if defined - the CurrentUser and GPO-based policies (which preempt the former) do.只有 - 如果已定义 - CurrentUser和基于 GPO 的策略(抢占前者)才可以。

  • On Windows:在 Windows 上:

    • In the absence of a relevant execution policy being defined, Restricted is the default, which categorically prevents execution of script files ( .ps1 ).在没有定义相关执行策略的情况下, Restricted是默认设置,它绝对阻止脚本文件 ( .ps1 ) 的执行。

    • If your application needs to execute .ps1 files when hosting the PowerShell SDK, for predictable behavior it is best to set the execution policy, for the current process only , as shown in this answer .如果您的应用程序需要在托管 PowerShell SDK 时执行.ps1文件,为了可预测的行为,最好设置执行策略,仅针对当前进程,如本答案所示。

The most elegant solution would probably be to get the ExecutionPolicy registry key in HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell .最优雅的解决方案可能是在HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell中获取ExecutionPolicy注册表项。 For this solution to work, your program needs to be running on the same architecture (x64 or x86) as the operating system it's running on or it won't be able to see the registry key.要使此解决方案正常工作,您的程序需要在与其运行的操作系统相同的体系结构(x64 或 x86)上运行,否则将无法看到注册表项。 Code to do this would look something like this:执行此操作的代码如下所示:

using Microsoft.Win32
...
string executionPolicy = Registry.GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell", "ExecutionPolicy", null)?.ToString();

If for any reason you can't do the first solution, the second way I would recommend is by using the System.Management.Automation.PowerShell NuGet package.如果由于任何原因您无法执行第一个解决方案,我推荐的第二种方法是使用System.Management.Automation.PowerShell NuGet 包。 This method would look something like this:这个方法看起来像这样:

using(var ps = PowerShell.Create()){
  ps.AddScript("Get-ExecutionPolicy");
  Collection<PSObject> output = ps.Invoke();
  Console.WriteLine($"Execution policy is {output[0]}")
}

If you really don't want to add an extra NuGet package to your project, there is another, but quite a bit messier way of doing this using System.Diagnostics.Process and it's output stream.如果你真的不想在你的项目中添加额外的 NuGet 包,还有另一种方法,但使用System.Diagnostics.Process和它的输出流来做这件事有点混乱。 It would look something like this:它看起来像这样:

var procInfo = new ProcessStartInfo("powershell.exe", "-Command \"Get-ExecutionPolicy\"")
{
  CreateNoWindow = true,
  UseShellExecute = false,
  RedirectStandardOutput = true
};

var proc = new Process
{
  StartInfo = procInfo
};
proc.OutputDataReceived += Proc_OutputDataReceived;

proc.Start();
proc.BeginOutputReadLine();
Console.ReadLine();

...

private static void Proc_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
  if (!string.IsNullOrWhiteSpace(e.Data))
    Console.WriteLine($"Execution policy is {e.Data}");
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM