Problem
You want to control how you define (or interact with) the visibility of variables, aliases, functions, and drives.
Solution
PowerShell offers several ways to access variables. To create a variable with a specific scope, supply that scope before the variable name:
$SCOPE:variable = value
To access a variable at a specific scope, supply that scope before the variable name:
$SCOPE:variable To create a variable that remains even after the script exits, create it in the GLOBAL scope: $GLOBAL:variable = value To change a scriptwide variable from within a function, supply SCRIPT as its scope name:
$SCRIPT:variable = value
Discussion
PowerShell controls access to variables, functions, aliases, and drives through a mechanism known as scoping. The scope of an item is another term for its visibility. You are always in a scope (called the current or local scope), but some actions change what that means.
When your code enters a nested prompt, script, function, or script block, PowerShell creates a new scope. That scope then becomes the local scope. When it does this, PowerShell remembers the relationship between your old scope and your new scope. From the view of the new scope, the old scope is called the parent scope. From the view of the old scope, the new scope is called a child scope. Child scopes get access to all the variables in the parent scope, but changing those variables in the child scope doesn’t change the version in the parent scope.
Trying to change a scriptwide variable from a function is often a “gotcha,” because a function is a new scope. As mentioned previously, changing something in a child scope (the function) doesn’t
affect the parent scope (the script). The rest of this discussion describes ways to change the value for the entire script.
When your code exits a nested prompt, script, function, or script block, the opposite happens. PowerShell removes the old scope, then changes the local scope to be the scope that originally created it—the parent of that old scope.
Some scopes are so common that PowerShell gives them special names:
Global
The outermost scope. Items in the global scope are visible from all other scopes.
Script
The scope that represents the current script. Items in the script scope are visible from all other scopes in the script.
Local
The current scope.
When you define the scope of an item, PowerShell supports two additional scope names that act more like options: Private and AllScope. When you define an item to have a Private scope, PowerShell does not make that item directly available to child scopes. PowerShell does not hide it from child scopes, though, as child scopes can still use the Scope parameter of the GetVariable cmdlet to get variables from parent scopes. When you specify the AllScope option for an item (through one of the *Variable, *Alias,or *Drive cmdlets), child scopes that change the item also affect the value in parent scopes.
With this background, PowerShell provides several ways for you to control access and scope of variables and other items.
Variables
To define a variable at a specific scope (or access a variable at a specific scope), use its scope name in the variable reference. For example:
$SCRIPT:myVariable = value
Functions
To define a function at a specific scope (or access a function at a specific scope), use its scope name when creating the function. For example:
function $GLOBAL:MyFunction { ... } GLOBAL:MyFunction args
Aliases and drives
To define an alias or drive at a specific scope, use the Option parameter of the *Alias and *Drive cmdlets. To access an alias or drive at a specific scope, use the Scope parameter of the *Alias and *Drive cmdlets.
For more information about scopes, type GetHelp AboutScope.