2

I have developed a mvc4 application that executes a PowerShell command from WebAPI and gets specific service information from number of remote computers.

Everything works fine on my dev machine but now i deployed it to IIS and it gives me weird results.

If i pass array of computers to the CmdLet, it gives back result for only one computer but if i execute the same CmdLet individually for each computer, it works fine.

Am i missing something here?

This is how my code looks like:

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

1 回答 1

2

This is because of a bug in the Get-Service cmdlt in PowerShell 2.0 where it doesn't accept a string array for the ComputerName parameter (despite what the help file says). This is fixed in PowerShell 3.0.

To demonstrate, run the following in PowerShell 2.0:

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

This returns the following:

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

Running the same code in PowerShell 3.0 gives you your expected results:

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

The workaround to running this in PowerShell 2.0 is to use the pipeline and a ForEach to enumerate your server names properly:

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

Which gives you your expected results:

MachineName    Status Name     DisplayName
-----------    ------ ----     -----------
Server1       Running wuauserv Windows Update
Server2       Running wuauserv Windows Update
Server3       Running wuauserv Windows Update
于 2013-06-13T17:35:05.433 回答