5

I am trying to run a PowerShell script with C#, but I don't have any 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'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();
}

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 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.

I have made the following declarations:

[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 have created the following function for impersonation:

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 have created a function which is used as a delegate:

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

And I have modified 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'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();
}

The result was...

... the very sam error, telling me I can't access registry keys.

2
  • re: can't access registry keys-- You will have to either use an account that can modify registry keys or use a technique that does involve changing the execution policy from inside a running powershell instance. Commented Nov 20, 2012 at 22:01
  • @Lajos: impersonation is a lot of overkill for this... all you need to do is change the scope that the Set-ExecutionPolicy uses... see my answer below. Commented May 2, 2013 at 18:17

3 Answers 3

2

Here is method b, that doesn't require elevated rights or Registry modification rights.

Using Process.Start launch this and add the relevant initial -command or -file args.

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

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

That relies on executing by encoding it first and passing int through the -EncodedCommand arg of powershell.exe, which appears to bypass execution policy.

Sign up to request clarification or add additional context in comments.

4 Comments

I'm trying to run a git command and if I do it this way it asks for username and password. The problem is that I would like to make this fully automatic. If user name or password is needed, then human work is needed for each run. Can I make this fully automatic? Thanks.
git asks for a username password or windows? What's in your scriptfile?
git is out of my range of experience. I'm guessing you are getting prompted by git for credentials, maybe this will help: superuser.com/questions/338511/…
I have edited my question. I have tried to implement an impersonate method. I don't know what is wrong, but something is certainly not right.
1

The default Set-ExecutionPolicy command attempts to set the machine-wide value. You only want to change the setting within the scope of your C# application, so you should add the -Scope Process option to the command.

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

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

... and it also describes the -Scope option.

This has the advantage of only impacting the execution policy for scripts run from your C# application, and it doesn't unnecessarily change the execution policy for the default PowerShell behavior. (So it's a lot safer, especially if you can make guarantees about the validity of the scripts your application runs.)

Comments

0

You could 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 you can look at to get an idea as an example, Class For Impersonating a User.

10 Comments

Thank you for your post. To do this I need to use the Impersonator class, but I have no clue where can I find it or how can I implement it. I don't find a download link, only a link pointing to another page where an impersonator is described, but that can't be downloaded either, only the function shared there. Should I register to the site to be able to download these?
Check out the link that Matthew Martin has posted as well I hope this information helps in getting started here is the link I posted as well in case it did not work from my initial post codeproject.com/Articles/10090/…
Ok, now I have the following error: Requested registry access is not allowed.
do you have the proper permissions / rights to run a powershell script..?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.