Search code examples
functionpowershellvariablesscopeinvoke-command

variable in function executed by invoke-command not visible


Can someone please help me get the below code to work?

$ab = "1"
function test {
$script:ab = "c"

}

invoke-command -ComputerName localhost ${function:test}
$ab

After running the above function by invoke-command I want to see value "c" for $ab


Solution

  • Note: ${function:test} is an unusual instance of PowerShell's namespace notation and is equivalent to
    (Get-Item function:test).ScriptBlock; i.e., it references the body of function test, as a script block.

    When you use the -ComputerName parameter, Invoke-Command uses remoting to execute the specified script block - even if the target computer is the same machine (localhost or .).

    Remotely executed code runs in a different process and has no access to the caller's variables.

    Therefore:

    • If local execution is the goal, simply omit the -ComputerName argument; then again, in that case you could simply run . ${function:test} or even just test:

      $ab = "1"
      function test { $script:ab = "c" }
      test  # shorter equivalent of: Invoke-Command ${function:test}
      
    • For remote execution, output the desired new value from the remotely executed script block and assign it to $ab in the caller's scope:

      $ab = "1"
      function test { "c" } # Note: "c" by itself implicitly *outputs* (returns) "c"
      $ab = Invoke-Command -ComputerName localhost ${function:test}