Unable to pass local variable to a remote PS script

This topic contains 7 replies, has 3 voices, and was last updated by Profile photo of Sillekyatha Sillekyatha 3 weeks, 1 day ago.

  • Author
    Posts
  • #57577
    Profile photo of Sillekyatha
    Sillekyatha
    Participant

    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

  • #57599
    Profile photo of Max Kozlov
    Max Kozlov
    Participant

    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

    • #57683
      Profile photo of Sillekyatha
      Sillekyatha
      Participant

      @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.

    • #57695
      Profile photo of Max Kozlov
      Max Kozlov
      Participant

      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
      
    • #57851
      Profile photo of Sillekyatha
      Sillekyatha
      Participant

      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.

  • #57605
    Profile photo of Don Jones
    Don Jones
    Keymaster

    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.

    • #57847
      Profile photo of Sillekyatha
      Sillekyatha
      Participant

      @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.

  • #57607
    Profile photo of Max Kozlov
    Max Kozlov
    Participant

    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
    

You must be logged in to reply to this topic.