使用c#执行powershell命令时的奇怪行为

时间:2013-06-03 21:47:50

标签: c# powershell

我开发了一个mvc4应用程序,它从WebAPI执行PowerShell命令,并从多台远程计算机获取特定的服务信息。

我的开发机器上的一切正常,但现在我将它部署到IIS,它给我带来了奇怪的结果。

如果我将计算机阵列传递给CmdLet,它只返回一台计算机的结果,但如果我为每台计算机单独执行相同的CmdLet,它可以正常工作。

我在这里错过了什么吗?

这就是我的代码的样子:

string[] serverNames = new string[] {"server1","server2","server3","server4","server5" };

CommandParameter paramServiceName = new CommandParameter("Name", "SomeService");
CommandParameter paramComputerName = new CommandParameter("ComputerName", computerNames);
Collection<PSObject> psObjects = ExecutePowerShellCommand("Get-Service", new CommandParameter[] { paramServiceName, paramComputerName });

foreach (PSObject psObject in psObjects)
{
     // Do Something
}


private Collection<PSObject> ExecutePowerShellCommand(string commandName, CommandParameter[] parameters)
{
     Runspace runSpace = RunspaceFactory.CreateRunspace();
     runSpace.Open();

     Pipeline pipeline = runSpace.CreatePipeline();

     Command psCommand = new Command(commandName);

     foreach (var cmdParameter in parameters)
        {
           psCommand.Parameters.Add(cmdParameter);
        }

     pipeline.Commands.Add(psCommand);

     Collection<PSObject> output = pipeline.Invoke();

     return output;
}

1 个答案:

答案 0 :(得分:2)

这是因为PowerShell 2.0中的Get-Service cmdlt中存在一个错误,它不接受ComputerName参数的字符串数组(尽管帮助文件说的是什么)。这在PowerShell 3.0中已得到修复。

要演示,请在PowerShell 2.0中运行以下命令:

$serverName = "Server1", "Server2", "Server3"
Get-Service -ComputerName $serverName -Name "wuauserv"  | format-table -property MachineName, Status, Name, DisplayName -auto

返回以下内容:

MachineName    Status Name     DisplayName
-----------    ------ ----     -----------
Server1       Running wuauserv Windows Update

在PowerShell 3.0中运行相同的代码可以获得预期的结果:

MachineName    Status Name     DisplayName
-----------    ------ ----     -----------
Server1       Running wuauserv Windows Update
Server2       Running wuauserv Windows Update
Server3       Running wuauserv Windows Update

在PowerShell 2.0中运行此方法的解决方法是使用管道和ForEach正确枚举您的服务器名称:

$serverName = "Server1", "Server2", "Server3"
$serverName | ForEach {Get-Service -ComputerName $_ -Name "wuauserv"} | format-table -property MachineName, Status, Name, DisplayName -auto

这可以为您提供预期的结果:

MachineName    Status Name     DisplayName
-----------    ------ ----     -----------
Server1       Running wuauserv Windows Update
Server2       Running wuauserv Windows Update
Server3       Running wuauserv Windows Update