How to modify parent scope variable using Powershell

The parent scope can actually be modified directly with Set-Variable -Scope 1 without the need for Script or Global scope usage. Example:

$val = 0
function foo {
    Set-Variable -scope 1 -Name "Val" -Value "10"
}
foo
write "The number is: $val"

Returns:

The number is: 10

More information can be found in the Microsoft Docs article About Scopes. The critical excerpt from that doc:

Note: For the cmdlets that use the Scope parameter, you can also refer to scopes by number. The number describes the relative position of one scope to another. Scope 0 represents the current, or local, scope. Scope 1 indicates the immediate parent scope. Scope 2 indicates the parent of the parent scope, and so on. Numbered scopes are useful if you have created many recursive scopes.


Be aware that recursive functions require the scope to be adjusted accordingly:

$val = ,0
function foo {
    $b = $val.Count
    Set-Variable -Name 'val' -Value ($val + ,$b) -Scope $b
    if ($b -lt 10) {
        foo
    }
}

You don't need to use the global scope. A variable with the same name could have been already exist in the shell console and you may update it instead. Use the script scope modifier. When using a scope modifier you don't include the $ sign in the variable name.

$script:val=10


Let me point out a third alternative, even though the answer has already been made. If you want to change a variable, don't be afraid to pass it by reference and work with it that way.

$val=1
function bar ($lcl) 
{
    write "In bar(), `$lcl.Value starts as $($lcl.Value)"
    $lcl.Value += 9
    write "In bar(), `$lcl.Value ends as $($lcl.Value)"
}
$val
bar([REF]$val)
$val

That returns:

1
In bar(), $lcl.Value starts as 1
In bar(), $lcl.Value ends as 10
10

If you want to use this then you could do something like this:

$global:val=0 
function foo()
{
    $global:val=10 
}
foo
write "The number is: $val"

Tags:

Powershell