Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to run a PowerShell script from C# as non-elevated user

I'm trying to run a PowerShell script from a C# application and I need the script to run when my C# app is running as a non-admin user (e.g. Network Service or some other domain account).

Previously, I was using the following code:

using (RunspaceInvoke invoker = new RunspaceInvoke())
{
    // load the powershell module
    invoker.Invoke("Import-Module MyModule");

    // run the cmdlet defined in the module 
    invoker.Invoke("MyCmdlet");
}

I don't know whether this is the best approach for running cmdlets defined in a module (please teach me if there's a better way!). In any case, this works perfectly if I'm running as an administrative user. I tried running this as Network Service, however, and I got an unfriendly error in the constructor of RunspaceInvoke:

Requested registry access is not allowed.

Is there a way I can run my PowerShell cmdlets as a non-elevated user such as Network Service? I do not need or desire to access the registry. The cmdlet itself also does not require elevated privileges.

like image 444
Chris Gillum Avatar asked Feb 13 '10 03:02

Chris Gillum


People also ask

How do I Run a script in a PowerShell script?

To run a script, open a PowerShell window, type the script's name (with or without the . ps1 extension) followed by the script's parameters (if any), and press Enter.

How do I Run a ps1 script from the command line?

ps1. Then, to execute the PowerShell script from the command line, launch the Windows command line by typing "cmd" into the search box and clicking the result. Type the full path of the PowerShell script, such as "C:\Example\example_script. ps1" and press enter.

How do I Run a PowerShell file?

In File Explorer (or Windows Explorer), right-click the script file name and then select "Run with PowerShell". The "Run with PowerShell" feature starts a PowerShell session that has an execution policy of Bypass, runs the script, and closes the session.


1 Answers

We use a version of the below. The "script" parameter is the PS script to run. We use this from a custom command line so that we can mix c# commands with some written in PS. "results" can be used to capture the evaluation of your script. The "out-default" line means that the output of the PS script is written to the console. A version of this can instead capture the output to a TextBox or similar if you have a WinForm of WPF app.

public void run(string script)
{
    IEnumerable<PSObject> results;
    var config = RunspaceConfiguration.Create();
    var host = new ScriptHost();
    using (var runspace = RunspaceFactory.CreateRunspace(host, config))
    {
        runspace.Open();
        runspace.SessionStateProxy.SetVariable("prog", this);

        using (var pipeline = runspace.CreatePipeline())
        {
            if (!string.IsNullOrEmpty(scriptPath))
                pipeline.Commands.AddScript(string.Format("$env:path = \"{0};\" + $env:path", scriptPath));

            pipeline.Commands.AddScript(script);

            var outDefault = new Command("out-default");
            outDefault.MergeMyResults(PipelineResultTypes.Error, PipelineResultTypes.Output);
            pipeline.Commands.Add(outDefault);

            results = pipeline.Invoke();
        }
    }
}
like image 126
AndyPook Avatar answered Oct 18 '22 20:10

AndyPook