Home > Back-end >  Using Splat in Invoke-Command AND passing arguments relevant to the machine
Using Splat in Invoke-Command AND passing arguments relevant to the machine

Time:08-25

I'm using Invoke-Command, but this question can be relevant to any command using splat. I essentially want to pass two sets of variables that will be useful in the splat command, but I'm not sure how I can do this.

In the code below, the Invoke-Command successfully connects to both servers, but the output I get is "Server1 Info" from both servers, which makes sense since the code is reading it like I'm trying to pass two arguments to both servers and it is taking what is in the first argument and writing it to host. What I really want it to do though is only pass one argument each time and to move down the list of which argument is being passed as it connects to successive servers.

$ServerList = "Server1","Server2"
$ServerArgs = "Server1 Info","Server2 Info"

$SB = {
    param($Arg1)
    Write-Host $Arg1
}

$SplatInfo = @{
    ComputerName = $ServerList
    ArgumentList = $ServerArgs
}

Invoke-Command @SplatInfo -ScriptBlock $SB

CodePudding user response:

You can only send one set of arguments per invocation of Invoke-Command.

If you want to pass different arguments per remote machine, you need to call Invoke-Command once per server:

$ServerList = "Server1","Server2"
$ServerArgs = "Server1 Info","Server2 Info"

$SB = {
    param($Arg1)
    Write-Host $Arg1
}

for($i = 0; $i -lt $ServerList.Count; $i  ){

    $SplatInfo = @{
        ComputerName = $ServerList[$i]
        ArgumentList = $ServerArgs[$i]
    }

    Invoke-Command @SplatInfo -ScriptBlock $SB
}

... in which case you might want to organize the input data slightly differently:

$inputList = @(
  @{ ComputerName = "Server1"; ArgumentList = @("Server1 Info") }
  @{ ComputerName = "Server2"; ArgumentList = @("Server2 Info") }
)

$baseSplat = @{
  ScriptBlock = {
    param($Arg1)
    Write-Host $Arg1
  }
}

foreach($entry in $inputList){
  Invoke-Command @baseSplat @entry
}

CodePudding user response:

Using the hashtable idea. This should run in parallel still.

import-csv file.csv | 
  % { $ServerArgs = @{} } { $ServerArgs[$_.server] = $_.args }
$ServerList = $ServerArgs | % keys
$SB = {
    param($Arg1)
    [pscustomobject]@{result = $Arg1[$env:computername]}
}
$SplatInfo = @{
    ComputerName = $ServerList
    ArgumentList = $ServerArgs
    ScriptBlock = $SB
}
Invoke-Command @SplatInfo


result       PSComputerName RunspaceId
------       -------------- ----------
Server1 Info Server1        gacbbb30-2492-41df-b181-9ebf6395b8b6
Server2 Info Server2        ebca4b52-c349-4ff7-972e-e67d07d9c0c3
  • Related