How to run PowerShell scripts with C #

I am trying to run a PowerShell script with C #, but I have no success. Here is my function:

private void ExecutePowerShellCommand(string scriptfile) { RunspaceConfiguration runspaceConfiguration = RunspaceConfiguration.Create(); Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConfiguration); runspace.Open(); RunspaceInvoke scriptInvoker = new RunspaceInvoke(); scriptInvoker.Invoke("Set-ExecutionPolicy Unrestricted"); Pipeline pipeline = runspace.CreatePipeline(); //Here 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 pipeline.Invoke(); } 

This is the error I get:

Access to the registry key "HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ PowerShell \ 1 \ ShellIds \ Microsoft.PowerShell" is denied.

How can I solve this problem? I saw ideas for impersonation, but I didn't seem to find any good examples for impersonation. I would like to run this script as an administrator.

I made the following announcements:

 [DllImport("advapi32.dll")] private static extern bool LogonUser(string lpszUsername, string lpszDomain, string lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken); [DllImport("kernel32.dll")] private static extern bool CloseHandle(IntPtr handle); public delegate void IncognitoDelegate(params object[] args); 

I created the following function to impersonate:

 public static void Impersonate(IncognitoDelegate incognitoDelegate, params object[] args) { System.IntPtr token = new IntPtr(); WindowsIdentity wi; if (LogonUser("myusername", "", "mypassword", 8, 0, ref token)) { wi = new WindowsIdentity(token); WindowsImpersonationContext wic = wi.Impersonate(); incognitoDelegate(args); wic.Undo(); } CloseHandle(token); } 

I created a function that is used as a delegate:

 private static void GIncognito(params object[] args) { RunspaceInvoke scriptInvoker = new RunspaceInvoke(); scriptInvoker.Invoke("Set-ExecutionPolicy Unrestricted"); } 

And I changed my method:

 private void ExecutePowerShellCommand(string scriptfile) { RunspaceConfiguration runspaceConfiguration = RunspaceConfiguration.Create(); Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConfiguration); runspace.Open(); Impersonate(new Util.IncognitoDelegate(GIncognito)); //RunspaceInvoke scriptInvoker = new RunspaceInvoke(); //scriptInvoker.Invoke("Set-ExecutionPolicy Unrestricted"); Pipeline pipeline = runspace.CreatePipeline(); //Here 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 pipeline.Invoke(); } 

The result was ...

... sam error itself, telling me that I cannot access registry keys.

+4
source share
3 answers

By default, the Set-ExecutionPolicy command attempts to set a common value for the machine. You want to change the parameter within the scope of your C # application, so you should add the -Scope Process parameter to the command.

Using Get-Help Set-ExecutionPolicy -detailed shows this information:

NOTE. To change the execution policy for the default scope (LocalMachine), start Windows PowerShell with the option "Run as administrator".

... and also describes the -Scope .

This has the advantage of only affecting the execution policy of scripts run from your C # application, and it does not unnecessarily change the execution policy for the default PowerShell behavior. (So ​​this is much safer, especially if you can guarantee the authenticity of the scripts that your application launches.)

+2
source

Here is method b, which does not require elevated rights or Rights to modify the registry.

Using Process.Start run this and add the appropriate initial arguments -command or -file .

% SystemRoot% \ system32 \ WindowsPowerShell \ v1.0 \ powershell.exe -ExecutionPolicy bypass

Here is another method, http://dmitrysotnikov.wordpress.com/2008/06/27/powershell-script-in-a-bat-file/

It depends on the execution, first coding it and passing the int via the -EncodedCommand powershell.exe argument, which seems to bypass the execution policy.

+2
source

You can try something like the following

 using ( new Impersonator( "Username", "DomainName", "Password" ) ) { using (RunspaceInvoke invoker = new RunspaceInvoke()) { invoker.Invoke("Set-ExecutionPolicy Unrestricted"); } } 

Here is a link that you can look at, for example, Class to impersonate the user .

0
source

Source: https://habr.com/ru/post/1447312/


All Articles