Author Posts

November 14, 2016 at 11:34 am

I'm trying to use a local variable in the PS script that exists on a remote machine, how do I make it work? Here's what I tried but failed.

$Name="myname"
$CPU= 100

First Method:
PS C:\Windows\system32> Invoke-Command -Session $s -Scriptblock{ & "C:\Users\Administrator\Desktop\Test.ps1" -RName $args[0] -RCPU $args[1]}-argumentlist $Name ,$CPU
Error:

Cannot validate argument on parameter 'Name'. The argument is null or empty. Provide an argument that is not null or
empty, and then try the command again.
+ CategoryInfo : InvalidData: (:) [Get-Process], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.GetProcessCommand
+ PSComputerName
Here I'm just trying to pass a local variable to the remote PS script and trying to print the same variable.

PS script on remote machine contains the following print statements

$RN = $env:RName
$TestV = "Local_Variable"
Write-Host $TestV
Write-Host $RName
Write-Host $RN
Write-Host $env:RName

Second Method:
PS > Invoke-Command -Session $s -Scriptblock{ & "C:\Users\Administrator\Desktop\Test.ps1 " -RName $using:Name -RCPU $using:CPU} Cannot validate argument on parameter 'Name'. The argument is null or empty. Provide an argument that is not null or empty, and then try the command again. + CategoryInfo : InvalidData: (:) [Get-Process], ParameterBindingValidationException + FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Comman‌​ds.GetProcessCommand

November 14, 2016 at 2:33 pm

I'm lost my crystal ball and can't help witout seeing your code
but I try....
I Don't see the -Name parameter in your Test.ps1 call, but I see -RName
there is something wrong inside Test.ps1.
if Test.ps1 have parameter() block ?
How it call Get-Process ? may be just wrong typing

November 14, 2016 at 2:36 pm

See the help for Invoke-Command; $args isn't supported. See also https://devopscollective.gitbooks.io/the-big-book-of-powershell-gotchas/content/manuscript/remote-variables.html for some working examples.

In your second example, I'm not seeing where you first defined $name and $cpu locally. But, you're also using the invocation operator (&), which I don't understand. That's going to prevent $using from working correctly, as it doesn't occur in the actual -Scriptblock parameter.

November 14, 2016 at 2:39 pm

Don afaik, $args always works well ?!

PS C:\> invoke-command { ping $args[0] } -comp remote -ArgumentList 127.0.0.1

Pinging 127.0.0.1 with 32 bytes of data:
Reply from 127.0.0.1: bytes=32 time<1ms TTL=128

November 15, 2016 at 7:48 am

@Max Kozlow : You were right, I had commented out the Get-Process part inside test.ps1 but had pasted the output that I used to get when it exist. I'm sorry for the confusion. But I still don't see the variables being retrieved by the destination PS script. I'm listing out the methods I have tried and couldn't succeed in either of them.

Here is the Start_TestTalk.ps1 script

$RN = $env:RName
$TestV = "Local_Variable"
Write-Host $TestV
Write-Host $RName
Write-Host $RN
Write-Host $env:RName

I'm trying with the following ways

I've declared the below variables
$Name="myname"
$CPU= 100
First Method:

PS C:\Users\Administrator> Invoke-Command -Session $s -Scriptblock{ & "C:\Users\Administrator\Desktop\Start_TestTalk.ps1
" -RName $args[0] -RCPU $args[1]}-argumentlist $Name,$CPU
Local_Variable

Second Method:

PS C:\Users\Administrator> Invoke-Command -Session $s -scriptblock {param($RName) & "C:\Users\Administrator\Desktop\Star
t_TestTalk.ps1" $RName} -ArgumentList $Name
Local_Variable

Third Method


PS C:\Users\Administrator> Invoke-Command -Session $s -Scriptblock{ & "C:\Users\Administrator\Desktop\Start_TestTalk.ps1
" -RName $using:Name -RCPU $using:CPU}
Local_Variable

For all the above three methods I get only the value of the 'local variable'(local to destination machine and declared there in the script) gets printed and not the variable I pass(here $Name) from my local machine on to the destination machine.

Thanks for your help in advance.

November 15, 2016 at 10:21 am

you should read at least
about_Variables https://technet.microsoft.com/en-us/library/hh847734.aspx
and about_Parameters https://technet.microsoft.com/en-us/library/hh847824.aspx

your script doesn't use -RName parameter
it even doesn't have parameter() block to accept named parameters

some examples: I use { code } as example of your script Start_TestTalk.ps1

# proper use of named parameters with param() block
PS C:\> Invoke-Command -ScriptBlock {param($RName) "I'm display RName here: $RName" } -ArgumentList 'lalala'
I'm display RName here: lalala
# proper use $args inside scriptblock without named parameters
PS C:\> Invoke-Command -ScriptBlock {"I'm display RName here as args: $($args[0])" }  -ArgumentList 'lalala'
I'm display RName here as args: lalala

November 16, 2016 at 7:03 am

@Max Kozlov: Thanks for making me understand the use of variables even though that didn't solve the actual issue/problem I had with. I figured out the answer and have explained on how this feature works.

November 16, 2016 at 7:17 am

I figured out the way on how this feature works with the help of a Senior Architect here in our company. The variables sent from the local(source machine) are not actually made local on the remote machine and these just get dumped as values on the remote machine and not as variables(you can't use variables). A simple example on how the above script which I had mentioned works

Start_TestTalk.ps1 script

$RN = $args[0]
$CPU= $args[1]
$TestV = "Local_Variable"
Write-Host $RN
Write-Host $CPU`

Now use the same old Invoke Command with slight changes removing the variables earlier used to hold the values from local machine

I've declared the below variables
$Name="myname"
$CPU= 100
PS C:\Users\Administrator\ Invoke-Command -Session $s -Scriptblock{ & "C:\Users\Administrator\Desktop\Start_TestTalk.ps1
" $args[0] $args[1] }-argumentlist $Name,$CPU
myname
100

Now you see that you get the required output on the remote machine, so it conveys that the values are directly getting dumped and not with the variables and hence I was earlier not able to use those variables on the remote machine.