Home > Blockchain >  What is the best way to check PowerShell Execution Policy in C#?
What is the best way to check PowerShell Execution Policy in C#?

Time:06-17

When you run Get-ExecutionPolicy in PowerShell, it gets the effective execution policy. I need to know the best way to get that information in 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#.

CodePudding user response:

Note:

  • PowerShell execution policies apply only on Windows.

  • With respect to Windows, the answer below covers both PowerShell editions.


It can be inferred from the docs that boxdog pointed to in a comment, but to spell it out:

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.

  • If you're using a PowerShell (Core) 7 SDK, additional considerations apply:

    • 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:

    • The LocalMachine scope of any - by definition install-on-demand - PowerShell (Core) 7 version does not apply; only - if defined - the CurrentUser and GPO-based policies (which preempt the former) do.

  • On Windows:

    • In the absence of a relevant execution policy being defined, Restricted is the default, which categorically prevents execution of script files (.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.

CodePudding user response:

The most elegant solution would probably be to get the ExecutionPolicy registry key in HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell. 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. 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. 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. 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}");
}
  • Related