简体   繁体   English

使用 C# 执行 Powershell 命令行开关时出错

[英]Error executing Powershell commandlets using C#

I have the following code that I have tested and works:我有以下经过测试和工作的代码:

    using (new Impersonator("Administrator", "dev.dev", #########"))
    {
        RunspaceConfiguration runspaceConfiguration = RunspaceConfiguration.Create();
        Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConfiguration);

        runspace.Open();

        RunspaceInvoke scriptInvoker = new RunspaceInvoke(runspace);
        scriptInvoker.Invoke("Set-ExecutionPolicy Unrestricted");

        Pipeline pipeline = runspace.CreatePipeline();
        Command myCmd = new Command(@"C:\test.ps1");
        myCmd.Parameters.Add(new CommandParameter("upn", upn));
        myCmd.Parameters.Add(new CommandParameter("sipAddress", sipAddress));
        pipeline.Commands.Add(myCmd);

        // Execute PowerShell script
        Collection<PSObject> results = pipeline.Invoke();
    }

However, when I try to include the function in a different project so that it is called from a webservice it throws an execption:但是,当我尝试将 function 包含在不同的项目中以便从 Web 服务调用它时,它会抛出一个异常:

    System.Management.Automation.CmdletInvocationException: Access to the registry key 'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell' is denied. ---> System.UnauthorizedAccessException: Access to the registry key 'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell' is denied.

I have no idea why this is happening.我不知道为什么会这样。 Any help would be appreciated.任何帮助,将不胜感激。

What's happening is that Impersonator only impersonates on the thread, and PowerShell's Runspace is running on another thread.发生的事情是 Impersonator 只在线程上模拟,而 PowerShell 的 Runspace 正在另一个线程上运行。

To make this work, you need to add:为了使这项工作,您需要添加:

runspace.ApartmentState = System.Threading.ApartmentState.STA;
runspace.ThreadOptions = System.Management.Automation.Runspaces.PSThreadOptions.UseCurrentThread;

just before you open the runspace.就在您打开运行空间之前。

This will force the runspace to run on the same thread as the impersonated token.这将强制运行空间与模拟令牌在同一线程上运行。

Hope this helps,希望这可以帮助,

Use these namespaces:使用这些命名空间:

using System.Management.Automation;
using System.Management.Automation.Runspaces;
using System.Threading;

Create Runspace with InitialSessionState使用 InitialSessionState 创建运行空间

InitialSessionState initialSessionState = InitialSessionState.CreateDefault();
initialSessionState.ApartmentState = ApartmentState.STA;
initialSessionState.ThreadOptions = PSThreadOptions.UseCurrentThread;

using ( Runspace runspace = RunspaceFactory.CreateRunspace ( initialSessionState ) )
{
  runspace.Open();

  // scripts invocation                 

  runspace.Close();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM