Multiple commands within ScriptBlock
Asked Answered
O

3

11

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?

Orthicon answered 1/8, 2016 at 18:2 Comment(5)
It returns the result of both for me, one after the other. Can you describe exactly your environment and test, what you expect and what you get?Demello
@Demello I'm running this particular invoke-command against a Windows Server 2003 box. I'm expecting to get both the results of get-service, and then get-process. However, I only receive the results of Get-Service. It appears as though it's skipping get-process.Orthicon
@PetSerAl I tried that and still only receive the output of Get-Service on the remote machine.Orthicon
What is PowerShell version on client and on server?Holt
@PetSerAl Version 5 on client, 2 on remote machine. Perhaps some sort of compatibility issue?Orthicon
S
11

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.

Steed answered 1/8, 2016 at 18:18 Comment(3)
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..Orthicon
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.Unbroken
@Unbroken 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. :(Steed
C
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]
Concern answered 1/8, 2016 at 18:5 Comment(3)
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?Orthicon
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.Concern
@AlexEdwards your syntax is perfectly valid; this looks to be a bug between v5 and v2, see the update in my answer.Steed
G
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)}
Gaylegayleen answered 11/9, 2020 at 3:18 Comment(1)
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}Amphichroic

© 2022 - 2024 — McMap. All rights reserved.