Home > Net >  Powershell scripting : Why is this function not able to access a global variable
Powershell scripting : Why is this function not able to access a global variable

Time:03-09

i have a script, let's say script1 that calls a function abc from script2. Below is script2 :-

$Global:splat2 
function xyz ()
{
    Write-Host "in xyz"
    Write-Host "$Global:splat2"
}
function abc ([System.Collections.ArrayList] $splat)
{
    $Global:splat2 = $splat
    Write-Host "in abc"
    Write-Host "$Global:splat2"
    $func = (Get-Command -Type Function xyz)
    $wholeFuncDef = 'Function '   $func.Name   " {`n"   $func.Definition   "`n}"

    Start-Process powershell -args '-noprofile', '-noexit', '-EncodedCommand', `([Convert]::ToBase64String([Text.Encoding]::Unicode.GetBytes("$wholeFuncDef; xyz")))
    
}

The function abc is called from script 1 (some value was assigned to $splat):

abc $splat

The problem is that only function abc prints the value for $splat2 while as in function xyz, $splat2 is empty. I was expecting that function xyz should also have the value for $splat2 since it's a global variable.

CodePudding user response:

Global variables are limited to a given session, i.e. a PowerShell runspace (thread) inside a given process.

Using Start-Process with powershell.exe invariably creates a new session, in a new process, which knows nothing about the caller's variables (except for inheriting environment variables by default).


You'll have to pass any values from the caller's scope explicitly to such a separate session.

Options:

  • Incorporate values from the caller's scope as a variable-assignment statements into the (Base64-encoded) command string passed to -EncodedCommand

  • A simple alternative is indeed to use an aux. environment variable.

Caveat re data types:

  • If you use an environment variable, its value is invariably a string.

  • If you incorporate a variable assignment into the command string, you can express more data types, but are limited to those that can be expressed as literals in PowerShell (unless you include a constructor call based on a literal, if feasible).

  • Supporting more data types - but not all - is possible with the - undocumented as of this writing - -EncodedArguments parameter; see this answer.

  • Related