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

本文关键字:执行 powershell 命令 使用 | 更新日期: 2023-09-27 18:16:35

我开发了一个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;
}

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

这是由于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