使用C#执行Powershell命令时出现错误

4
我有以下代码已经测试并且可用:
    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();
    }

然而,当我尝试将该函数包含在不同的项目中,以便从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.

我不知道为什么会出现这种情况。如果能得到帮助将不胜感激。


你打算如何使用模拟对象?因为目前看起来你好像没有在使用它... - Edwin de Koning
这是我的尝试来解决这个问题。它被发布为类似问题的解决方案。 - Hugo
2个回答

8
发生的情况是模仿者只在线程上进行模拟,而PowerShell的Runspace在另一个线程上运行。
为了使其工作,您需要添加:
runspace.ApartmentState = System.Threading.ApartmentState.STA;
runspace.ThreadOptions = System.Management.Automation.Runspaces.PSThreadOptions.UseCurrentThread;

在打开runspace之前,务必执行此操作。

这将强制使runspace在模拟令牌所在的线程上运行。

希望这能帮到您,


的确如此。我修正了答案。 - Start-Automating
谢谢你的回答。我找不到ThreadOptions的任何命名空间。 - Dinesh Haraveer
那是因为我打错了字。这个类是System.Management.Automation.PSThreadOptions。 - Start-Automating

1
使用这些命名空间:
using System.Management.Automation;
using System.Management.Automation.Runspaces;
using System.Threading;

创建具有初始会话状态的运行空间。
InitialSessionState initialSessionState = InitialSessionState.CreateDefault();
initialSessionState.ApartmentState = ApartmentState.STA;
initialSessionState.ThreadOptions = PSThreadOptions.UseCurrentThread;

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

  // scripts invocation                 

  runspace.Close();
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接