The scope of a variable determines its logical boundaries. You can set variable scope as global, local, script, or private. The scopes exist in a logical hierarchy in which scope information is accessible downward in this order:
global > script/local > private
Following this, you can see that the local and script scopes can read information from the global scope, but the global scope cannot read a local or script scope.
REAL WORLD Scope applies to aliases, functions, and PowerShell drives as well as to variables. You can think of the global scope as the parent or root scope and script/ local scripts as child scopes of the global scope. Child scopes can always read informa- tion from parent scopes. Technically speaking, variables, aliases, and functions in a parent scope are not part of the child scope. A child scope does not inherit the vari- ables, aliases, or functions from the parent scope. However, a child scope can view the variables, aliases, or functions from the parent scope, and it can change these items in the parent scope by explicitly specifying the parent scope.
The default scope for a script is a script scope that exists only for that script. The default scope for a function is a local scope that exists only for that function, even if the function is defi ned in a script.
Regardless of whether you are working with variables, aliases, functions, or PowerShell drives, scopes work the same. An item you include in a scope is visible in the scope in which it was created and any child scopes, unless you explicitly make it private. An item in a particular scope can be changed only in that scope, unless you explicitly specify a different scope. If you create an item in a child scope and that item already exists in another scope, the original item is not accessible in the child scope, but it is not overridden or changed in the original (parent) scope.
You can create a new scope by running a script or function, by defi ning a script block, by creating a local or remote session, or by starting a new instance of Power- Shell. When you create a new scope through a script, function, script block, or nest- ing of instances, the scope is a child scope of the original (parent) scope. However, when you create a new session, the session is not a child scope of the original scope. The session starts with its own global scope, and that global scope is independent from the original scope.
You can explicitly or implicitly set the scope of a variable. You explicitly set scope by adding the Global, Local, Script, or Private keyword prefi x to the variable name. The following example creates a global variable:
$Global:myVar = 55
You implicitly set scope whenever you defi ne a variable at the prompt, in a script, or in a function. A variable with an implicit scope resides in the scope in which it is defi ned.
The default scope is the current scope and is determined as follows:
N Global when defi ned interactively at the PowerShell prompt
N Script when defi ned outside functions or script blocks in a script N Local within functions, script blocks, or anywhere else
The global scope applies to an entire PowerShell instance. Because data defi ned in the global scope is inherited by all child scopes, this means any commands, func- tions, or scripts that you run can make use of variables defi ned in the global scope.
Global scopes are not shared across instances of PowerShell. With regard to the PowerShell console, this means the variables you defi ne in one console are not
available in another console (unless you defi ne them in that console session). With regard to the PowerShell application, this means variables you defi ne in one tab are not available in another tab (unless you defi ne them in that tab session).
Local scopes are created automatically each time a function, script, or fi lter runs. A local scope can read information from the global scope, but it can make changes to global information only by explicitly declaring the scope. After a function, script, or fi lter has fi nished running, the information in the related local scope is discarded.
To learn more about scopes, consider the following example and sample output:
function numservices {$serv = get-service} numservices
write-host "The number of services is: `t" $serv.count
The number of services is:
Here, $serv is created as a variable inside the numservices function. As a result, when you run the function, a local variable instance is created. When you then try to access the $s variable in the global scope, the variable has no value. In contrast, if you explicitly declare the variable as global, you can access the variable in the global scope as shown in the following example and sample output:
function numservices {$Global:serv = get-service} numservices
write-host "The number of services is: `t" $serv.count
The number of services is: 157
Script scopes are created whenever a script runs. Only commands in a script run in the script scope; to these commands, the script scope is the local scope. As func- tions in a script run in their own local scope, any variables set in a script function are not accessible to the script itself. To remedy this, you can set the scope of variables defi ned in a script function explicitly as shown in this example:
function numservices {$Script:serv1 = get-service} numservices
write-host "The number of services is: `t" $serv1.count
Normally, when a function or script fi nishes running, the related scope and all related information is discarded. However, you can use dot sourcing to tell Power- Shell to load a function’s or script’s scope into the calling parent’s scope rather than creating a new local scope for the function or script. To do this, simply prefi x the function or script name with a period (.) when running the function or script, as
function numservices {$serv = get-service} numservices
write-host "The number of services is: `t" $serv.count
The number of services is:
function numservices {$Global:serv = get-service} numservices
write-host "The number of services is: `t" $serv.count
The number of services is: 157
function numservices {$Script:serv1 = get-service} numservices
The fi nal scope type you can use is the private scope. You must create privately scoped items explicitly. Because any information in a private scope is not available to any other scopes, including child scopes, a privately scoped variable is available only in the scope in which it is created. The following example and sample output shows this:
function numservices {$Private:serv = get-service write-host "The number of services is: `t" $serv.count
&{write-host "Again, the number of services is: `t" $serv.count} }
numservices
The number of services is: 157 Again, the number of services is:
Here, you create a function with a private variable and then defi ne a script block within the function. Within the function, you have access to the private variable, and this is why you can write the number of services when you call the function. Because the script block automatically runs in its own local scope, you cannot access the pri- vate variable in the script block. This is why you cannot write the number of services from within the script block when you call the function.