9

I'm having trouble running multiple commands within a Scriptblock parameter. All documentation points towards using a semicolon for separation between cmdlets. Using the same methodology of separating cmdlets via a semicolon works on my local machine, but not on a remote machine through invoke-command.

For example, the below code will only return the result of Get-Service, and not Get-Process.

Invoke-Command -ComputerName cas-bkupexec -ScriptBlock { Get-Service;  Get-Process }

How can I achieve the desired result of both commands successfully running and receive the output of each?

Alexander Edwards
  • 772
  • 2
  • 7
  • 18

3 Answers3

10

I am able to reproduce this.. it only returns the first statement. It's not the semicolon, it does the same thing if you use line breaks.

These options work:

Invoke-Command -ComputerName computer -ScriptBlock {
    (Get-Service)
    Get-Process
}

Or this curiously:

Invoke-Command -ComputerName computer -ScriptBlock {
    & { 
        Get-Service
        Get-Process
    }
}

Since wrapping one of them in ( ) works I feel like this must be some quirk of the pipeline but I haven't been able to figure out exactly what it's doing yet.

Update:

After reading your comment that your source machine was running v5 and the remote v2, I realized that my testing did the same.

When I remoted from the v5 into itself, the issue disappeared.

Remoting from:

v2 -> v5: no issue
v2 -> itself: no issue
v2 -> other v2: no issue
v3 -> v2: no issue
v3 -> v5: no issue
v3 -> itself: no issue
v4 -> v2: no issue
v4 -> v3: no issue
v4 -> itself: no issue
v4 -> v5: no issue

Not every combination here, but it seems like it really may be a bug from v5 to v2.

briantist
  • 45,546
  • 6
  • 82
  • 127
  • I'll use this as a workaround in the meantime. Thanks. Would still love to see why the expected behavior of command separation via semicolon isn't working though. Or an explanation as to why.. – Alexander Edwards Aug 01 '16 at 18:39
  • Could this be another victim of the formatting engine formatting all output for the first thing it gets (`Get-Service`), and since `Get-Process` has different output it ignores it? Then wrapping the first one outputs that as a separate process, so the formatting engine has a degree of separation and outputs correctly? Just a guess, but it kind of makes sense to me. – TheMadTechnician Aug 01 '16 at 18:47
  • @TheMadTechnician that's what I initially thought too, so I captured the output in a variable, checked the count, checked the first and last element, make sure it wasn't an array of arrays, etc. The output really wasn't there. :( – briantist Aug 01 '16 at 18:49
3

You could try to separate them by a comma which would make the results an array that you could then look at by each index.

$Results = Invoke-Command -ComputerName cas-bkupexec -ScriptBlock { (Get-Service), (Get-Process) }

#Services
$Results[0]

#Processes
$Results[1]
boeprox
  • 1,848
  • 13
  • 24
  • Yes this works, however I'm still confused as to why I can't simply use the semicolon to separate the two Cmdlets within the Scriptblock. Is using a semicolon to separate commands invalid syntax for the -Scriptblock parameter? – Alexander Edwards Aug 01 '16 at 18:22
  • 1
    Yea, that is odd. Might be something with the pipeline as briantist pointed out. If you run it like this, it works as expected: `Invoke-Command -ComputerName J23 -ScriptBlock {$a = Get-Process;$b = Get-Service;$a;$b}`. The moment you add any command that sends data to the pipeline such as Write-Output, it will only display the first item. – boeprox Aug 01 '16 at 18:36
  • @AlexEdwards your syntax is perfectly valid; this looks to be a bug between v5 and v2, see the update in my answer. – briantist Aug 01 '16 at 18:50
1

The options mentioned above as answer didn't work for me. But, I worked by using below command.

Invoke-Command -ComputerName computer -ScriptBlock {(Get-Service), (Get-Process)}
Arghya Sadhu
  • 41,002
  • 9
  • 78
  • 107
  • parenthesis worked for me too. Example below where I wanted to print the machine named followed by the results of a command, in this case get the version of chrome on a machine: `Invoke-Command -ComputerName MyMachine -ScriptBlock {(hostname),$(Get-Package -Name "Google Chrome").Version}` – Chris Smith Jun 20 '23 at 20:40