Help with passing arguments with Invoke-Command (I am using -ArgumentList)

I’m trying to call a .ps1 on remote servers, every attempt to pass arguments with Invoke-Command has failed me.

The .ps1 I’m calling has mandatory parameters, if I leave it I have it, I’m then prompted for those parameters (because my args aren’t passing), however no combination of " and ’ has been the answer for me. Putting the whole string in quotes gets me the error “test.ps1 -var1” is not a valid file. I’m using the PSsession because a stackoverflow I read suggested that helped them.

 

Here’s my current code:

foreach ($server in $servers)

{

$session = New-PSSession -ComputerName $server

$scriptblock = {& 'C:\script\test.ps1' -var1 $args[0] -var2 $args[1] -var3 $args[2] -var4 $args[3]}

Invoke-Command -Session $session -ScriptBlock $scriptblock -ArgumentList $var1, $var2, $var3, $var4

}

 

You have to use Param() block to pass variables to a scriptblock,

A small example.

Invoke-Command -ComputerName Server -ScriptBlock {
Param(
$P1,
$P2
)
Write-Output "P1 is $P1"
Write-Output "P2 is $P2"
} -ArgumentList 1,2

Do i need to change formatting or adjust my "'s around the code calling the script file?

Update: This code prompts for arguments

 

foreach ($server in $servers)

{

$session = New-PSSession -ComputerName $server

$scriptblock = {

param(
$v1,
$v2,
$v3,
$v4
)

& 'C:\scripts\test.ps1' -v1 $v1 -v2 $v2 -v3 $v3 -v4 $v4

}

Invoke-Command -Session $session -ScriptBlock $scriptblock -ArgumentList $v1, $v2, $v3, $v4

}

I cannot see anything which prompts for input in above code. If you have anything inside test.ps1, you have to parametrize and pass the value.

You don’t need to use the call operator(&), just remove the quotes. If you are executing only that script in scriptblock. You can use -FilePath parameter of Invoke-Command. Instead of explaining options. I would suggest you to read the documentation for Invoke-Command.

I’m making an assumption that you declare the variables earlier in the script.

$Arg="bob"

$nextArg="robert"

invoke-command -cn other server -scriptblock {write-host "$using:Arg is short for $using:nextArg"}

Here’s my current code and some other info.

  1. all variables are declared and have a value before the foreach loop, i can write-output the expected value IN the foreach loop
  2. test\script.ps1 is on a remote machine, it accepts the parameters
  3. when i run this, it does execute the script, but doesn't pass the parameters, errors out saying string is empty

foreach ($server in $servers)

{
Invoke-Command -Computername $server -ScriptBlock {powershell.exe -file C:\test\script.ps1 -var1 “$args[0].ToString()” -var2 “$args[1].ToString()” -var3 “$args[2].ToString()” -var4 “$args[3].ToString()”} -ArgumentList $var1, $var2, $var3, $var4
}

 

here’s the test.ps1 parameter code

Function test
{
[cmdletbinding()]
param(
[parameter(position=0)][string] $var1,
[parameter(position=1)][string] $var2,
[parameter (position=2)][string] $var3,
[parameter (position=3)][string] $var4)

You don’t need to use PowerShell.exe here and should use Param() as I suggested before.

I reiterate , Please read the docs. It we can of course give you the solution and already gave the hints. but without reading the documentation, its going to put you in trouble for every new line of code you write.

see: about Scopes - PowerShell | Microsoft Docs

Here is an example of how you need to pass your parameters;

Param
(
$VariableA,
$VariableB,
$VariableC
)
Invoke-Command -ComputerName AComputer -ScriptBlock{
   Param($VariableA, $VariableB, $VariableC)     
       Do-Something -Parameter1 $VariableA -Paramaeter2 $VariableB -Parameter3 $VariableC
}-ArgumentList $VariableA, $VariableB, $VariableC

I appreciate everyone’s help and don’t mean disrespect. When I turn to powershell.org it means all my internet searches and attempts on my own have failed. I’ve tried the $Using: method, and the most recent passing parameters. Here is my current code that is still yielding no passing of parameters. In the code below, the remote ps1 file test.ps1 does execute, however the parameters are passed as empty strings, which test.ps1 needs to have values to run its code.

 

I can write-output all of the variables inside of the foreach loop successfully, so I know they have the correct value inside of the loop. My best guess is the way I’m calling the script.

 

foreach ($server in $servers)

{
Invoke-Command -Computername $server -ScriptBlock {
param($var1, $var2, $var3, $var4)
powershell.exe -file C:\test\script.ps1 -p1 "$var1" -p2 "$var2" -p3 "$var3" -p4 "$var4"} -ArgumentList $var1, $var2, $var3, $var4
}

 

Here is my receiving script code:

Function Test
{
[cmdletbinding()]
param(
[parameter(position=0)][string] $p1,
[parameter(position=1)][string] $p2,
[parameter (position=2)][string] $p3,
[parameter (position=3)][string] $p4)

if (!$p4)
{
Write-Host "No p4"
}

 

Ok issue is solved, the problem was the receiving function. Once i moved the param ( ) outside the function, it worked perfectly.

Awesome stuff!

Can you share the code?