0

I have a powershell script on machine A that uses PSSession to invoke a command on Machine B. Machine B has a powershell script which accepts 4 parameters. When I call this script with the 4 arguments as variables (which they MUST be), they are passed as empty strings/null. When I pass them as strings (For example -Argument1 "Hello"), that string will be passed as "Hello" and not as NULL/empty string.

Can anyone tell me why these are not passed correctly and how to fix it?

The powershell version on the client is 5.1.17134.112. The remote machine uses 5.1.14393.2248. These versions have been obtained by running $PSVersionTable.PSVersion.

The client is using Windows 10 Pro 10.0.17134. The server is using Windows 2016 Datacenter 10.0.14393 and is run as a VM on Azure.

I have tried using Script.ps1 -Argument1 $ClientArgument1 -Argument2 $ClientArgument2 ... to pass variables AND to use ArgumentList to pass the values comma separated to the script but both these attempts resulted in things not being printed.

I have noticed that when I use -Argument1 "Hello" -Argument2 $ClientArgument2 -Argument3 $ClientArgument3 -Argument4 $ClientArgument4, the Hello DOES get printed.

Code

Client that connects to the remote machine

$ErrorActionPreference = "Stop"

#Create credentials to log in
$URL = 'https://url.to.server:5986'
$Username = "username"
$pass = ConvertTo-SecureString -AsPlainText 'password' -Force
$SecureString = $pass
$MySecureCreds = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $Username,$SecureString

$ClientArgument1 = "Argument 1"
$ClientArgument2 = "Argument 2" 
$ClientArgument3 = "Argument 3" 
$ClientArgument4 = "Argument 4" 

#Create the remote PS session
$sessionOption = New-PSSessionOption -SkipCACheck -SkipCNCheck -SkipRevocationCheck
$session = New-PSSession -ConnectionUri $URL -Credential $MySecureCreds -SessionOption $sessionOption

#Call the remote script and pass variables
Invoke-Command -Session $session -Command {C:\Path\To\Script\On\Remote\Machine\Script.ps1 -Argument1 $ClientArgument1 -Argument2 $ClientArgument2 -Argument3 $ClientArgument3 -Argument4 $ClientArgument4}

#Note: Command is used because Command allows me to execute a script that is located on disk of the remote machine

The called script of the remote machine

param(
    [String]$Argument1,
    [String]$Argument2,
    [String]$Argument3,
    [String]$Argument4
)

Write-Host 'Results of the 4 parameters passed into this script:'

Write-Host $Argument1
Write-Host $Argument2
Write-Host $Argument3
Write-Host $Argument4

Write-Host "The results have been printed" 

Expected and actual results

Expected results:

Results of the 4 parameters passed into this script:
Argument 1
Argument 2
Argument 3
Argument 4
The results have been printed 

Actual results

Results of the 4 parameters passed into this script:




The results have been printed

Thank you very much for your time!

S. ten Brinke
  • 2,557
  • 4
  • 25
  • 50
  • The first thing I would suggest is to remove the `[string]` typing on the args. I don't know for a fact that this is the issue but it isn't necessary and I have seen forced typing do odd things in the past. – EBGreen Jul 05 '18 at 14:57
  • You're not scoping your parameters. Use the `$using:` scope for remote commands. – Maximilian Burszley Jul 05 '18 at 15:14
  • 1
    Possible duplicate of [How do I pass variables with the Invoke-Command cmdlet?](https://stackoverflow.com/questions/36328690/how-do-i-pass-variables-with-the-invoke-command-cmdlet) – Maximilian Burszley Jul 05 '18 at 15:16

2 Answers2

1

Since what inside the scriptblock in a different scope as the rest of your script, the $ClientArgument variables are undefined inside the scriptblock. The easiest solution if you are using PowerShell 3 or newer is to use the $using: scope. Otherwise an argumentlist for the Invoke-Command would be required.

Invoke-Command -Session $session -Command {C:\Path\To\Script\On\Remote\Machine\Script.ps1 -Argument1 $using:ClientArgument1 -Argument2 $using:ClientArgument2 -Argument3 $using:ClientArgument3 -Argument4 $using:ClientArgument4}
BenH
  • 9,766
  • 1
  • 22
  • 35
0

Try to execute it this way:

Invoke-Command -Session $session -Command {

C:\Path\To\Script\On\Remote\Machine\Script.ps1 `
-Argument1 $args[0] -Argument2 $args[1] `
-Argument3 $args[2] -Argument4 $args[3]

} -ArgumentList $ClientArgument1,$ClientArgument2,$ClientArgument3,$ClientArgument4
Avshalom
  • 8,657
  • 1
  • 25
  • 43
  • @TheIncorrigible1 you are wrong in that, the OP did not did it in the question, using `$args[0] etc.` will solve the problem, it just like the `$using` - fix the scoping issue – Avshalom Jul 05 '18 at 15:50
  • My bad. I misread part of his question in hindsight. Either way, it's a duplicate question that gets asked here every week. – Maximilian Burszley Jul 05 '18 at 15:54