Steve
Steve

Reputation: 710

Invoke-Command returns only a single object when called using ScriptBlock and ArgumentList

When code is invoked though Invoke-Command using the -ScriptBlock, -ArgumentList and -Computer parameters, only a single item is returned from each call to the servers.

Two examples can be found below highlighting the problem.

$s = New-PSSession -ComputerName Machine01, Machine02

# when called, this block only retuns a single item from the script block
# notice that the array variable is being used
Invoke-Command -Session $s -ScriptBlock {
  param( $array )  
  $array | % { $i = $_ ; Get-culture | select @{name='__id'; ex={$i} } , DisplayName
  }
} -ArgumentList 1,2,3

write-host "`r`n======================================`r`n"

# when called, this block retuns all items from the script block
# notice that the call is the same but instead of using the array variable we use a local array
Invoke-Command -Session $s -ScriptBlock {
  param( $array )  
  1,2,3 | % { $i = $_ ; Get-culture | select @{name='__id'; ex={$i} } , DisplayName
  }
} -ArgumentList 1,2,3

$s | Remove-PSSession

Can anyone explain to me what i am doing wrong? I cant be the only person caught out by this.

Upvotes: 2

Views: 609

Answers (1)

marsze
marsze

Reputation: 17035

-ArgumentList does what the name implies, it passes a list of arguments to the command. Each value from that list is, if possible, assigned to a defined parameter. But you only have one parameter defined: $array. Therefore, you only get the first value from the arg list.

See, this is actually how it's supposed to work (3 arguments bound to 3 parameters):

Invoke-Command -Session $s -ScriptBlock {
    param ($p1, $p2, $p3)  
    $p1, $p2, $p3 | % { $i = $_ ; Get-culture | select @{name='__id'; ex={$i} } , DisplayName }
} -ArgumentList 1, 2, 3

So, what you actually want to do is pass one array as one single parameter.

One way to accomplish that would be:

-ArgumentList (,(1, 2, 3))

Final code:

Invoke-Command -Session $s -ScriptBlock {
    param ($array) 
    $array | % { $i = $_ ; Get-culture | select @{n = '__id'; e = {$i}}, DisplayName }
} -ArgumentList (, (1, 2, 3))

Another way (in this simple case) would be using the automatic $args variable:

Invoke-Command  -ScriptBlock {
    $args | % { $i = $_ ; Get-culture | select @{n = '__id'; e = {$i}}, DisplayName }
} -ArgumentList 1, 2, 3

Upvotes: 2

Related Questions