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.