Would you like to see PowerShell in action and ask questions live? Join us for our brand new PowerShell Live! webcasts starting on Tuesday, July 18th at 10:00 AM, MDT. Can’t join this Tuesday? You are in luck, we will be having these the 1st and 3rd Tuesday of every month. I’m looking forward to seeing you there!
Now, onto the topic at hand…
When using remote PowerShell, have you ever run into problems with variables having the correct value? If you have, then you are probably running into one of the most common problems that people run into with PowerShell: remote variables.
By default, variables in remote commands are created in the remote session. This means variables created outside of a remote command will not be directly available within the remote command.
Remote Variables
Variables defined outside of Invoke-Command will not be available in the Invoke-Command scriptblock unless you explicitly pass them through or reference them. See this article about Remote Variables for more info. In my examples, I am defining a variable and then outputting the result both locally and remotely with my machine FRY. (See Write-Output)
$MyVariable = "My Value"
Write-Output "Outside Invoke-Command, MyVariable has a value of: $MyVariable"
Invoke-Command -ComputerName FRY -ScriptBlock {
Write-Output "Inside Invoke-Command, MyVariable has a value of: $MyVariable"
}
Since the contents of $MyVariable don’t work within the remote session, the value shows up as blank in this case.
So, what do we do about this?
Well, there are a couple of ways to overcome this depending on if you’re using PowerShell 2 or PowerShell 3 and later.
PowerShell 2 method: ArgumentList and Param
If you’re stuck writing scripts that need backwards compatibility with PowerShell 2, this is how you pass the local variable value into the remote session. Notice the usage of -ArgumentList $MyVariable and Param($LocalVariable) here.
$MyVariable = "My Value"
Write-Output "Outside Invoke-Command, MyVariable has a value of: $MyVariable"
Invoke-Command -ComputerName FRY -ScriptBlock {
Write-Output "Inside Invoke-Command, MyVariable has a value of: $LocalVariable"
}
PowerShell takes the variable $MyVariable and passes it into the remote session as $LocalVariable. You can change the names of these variables to anything you like.
PowerShell 3+ method: $Using
In PowerShell 3, you can use local variables in remote sessions by utilizing the $Using modifier.
$MyVariable = "My Value"
Write-Output "Outside Invoke-Command, MyVariable has a value of: $MyVariable"
Invoke-Command -ComputerName FRY -ScriptBlock {
Write-Output "Inside Invoke-Command, MyVariable has a value of: :MyVariable"
}
While inside the remote session, the $Using modifier references the local variable that was set previously.
Wrapping up
PowerShell gives us a couple of great methods to use local variables in a remote context. Try them out!
Happy PowerShelling!