簡體   English   中英

如何從C#運行PowerShell腳本

[英]How to run PowerShell scripts from C#

我正在嘗試使用C#運行PowerShell腳本,但我沒有任何成功。 這是我的功能:

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();
}

這是我得到的錯誤:

訪問注冊表項“HKEY_LOCAL_MACHINE \\ SOFTWARE \\ Microsoft \\ PowerShell \\ 1 \\ ShellIds \\ Microsoft.PowerShell”被拒絕。

我該如何解決這個問題? 我已經看到了冒充的想法,但我似乎沒有找到任何好的例子來冒充。 我想以管理員身份運行此腳本。

我做了以下聲明:

[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);

我為模擬創建了以下函數:

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);
}

我創建了一個用作委托的函數:

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

我修改了我的方法:

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();
}

結果是......

...非常山姆的錯誤,告訴我我無法訪問注冊表項。

這是方法b,不需要提升權限或注冊表修改權限

使用Process.Start啟動它並添加相關的initial -command-file args。

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

這是另一種技術, http://dmitrysotnikov.wordpress.com/2008/06/27/powershell-script-in-a-bat-file/

這依賴於首先對其進行編碼並通過powershell.exe的-EncodedCommand arg傳遞int,這似乎繞過了執行策略。

默認的Set-ExecutionPolicy命令嘗試設置機器范圍的值。 您只想更改C#應用程序范圍內的設置,因此您應該在命令中添加-Scope Process選項。

使用Get-Help Set-ExecutionPolicy -detailed顯示以下信息:

注意:要更改默認(LocalMachine)范圍的執行策略,請使用“以管理員身份運行”選項啟動Windows PowerShell。

...它還描述了-Scope選項。

這樣做的好處是影響從C#應用程序運行的腳本的執行策略,並且不會不必要地更改默認PowerShell行為的執行策略。 (因此它更安全,特別是如果您可以保證應用程序運行的腳本的有效性。)

您可以嘗試以下內容

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

這是一個鏈接,你可以看一個想法作為一個例子, 模擬用戶模擬

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM