title: How to run PowerShell scripts from C#
body: <p>I am trying to run a PowerShell script with C#, but I don't have any success. Here is my function:</p>
  
  <pre><code>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's 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();
  }
  </code></pre>
  
  <p>This is the error I get:</p>
  
  <blockquote>
    <p>Access to the registry key 'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell' is denied.</p>
  </blockquote>
  
  <p>How can I solve this issue? I have seen ideas for impersonation, but I didn't seem to find any good examples to impersonate. I would like to run this script as an administrator.</p>
  
  <p>I have made the following declarations:</p>
  
  <pre><code>[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);
  </code></pre>
  
  <p>I have created the following function for impersonation:</p>
  
  <pre><code>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);
  }
  </code></pre>
  
  <p>I have created a function which is used as a delegate:</p>
  
  <pre><code>private static void GIncognito(params object[] args)
  {
      RunspaceInvoke scriptInvoker = new RunspaceInvoke();
      scriptInvoker.Invoke("Set-ExecutionPolicy Unrestricted");
  }
  </code></pre>
  
  <p>And I have modified my method:</p>
  
  <pre><code>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's 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();
  }
  </code></pre>
  
  <p>The result was...</p>
  
  <p>... the very sam error, telling me I can't access registry keys.</p>