PowerShell Scope
PowerShell scopes are nested. A function can read variables from the scope that called it, but assigning to one creates a new local variable instead of changing the original.
Documentation: Microsoft Learn
Overview
That asymmetry is the whole lesson. Reading looks like it shares state, so people assume writing does too. It does not: the assignment shadows the outer variable for the rest of the function, and the caller's value is untouched.
Scope modifiers exist for the cases where you really do want to reach out. $script:total refers to the variable at script level, $global:config to the global one. Both work, and both make code harder to follow, so treat them as a last resort. Passing a value in as a parameter and returning the result is almost always clearer.
Dot-sourcing changes the rules. Running . .\script.ps1 with a leading dot and space executes the file in your current scope, so its functions and variables stay behind after it finishes. That is how profile scripts and module-style helper files load.
Inspect this example’s structure
Read the command and its supplied arguments. This example requires real PowerShell or its module; this diagram does not execute it.
$counter = 10
function Test-Scope {
Write-Output "Function sees: $counter"
$counter = 99
Write-Output "Function set it to: $counter"
}
Test-Scope
Write-Output "Caller still has: $counter"- Stage 1$counter
Positional values or no named parameters
An example to inspect
Preview the example. Sign in for the full lesson and activities.
$counter = 10
function Test-Scope {
Write-Output "Function sees: $counter"
$counter = 99
Write-Output "Function set it to: $counter"
}
Test-Scope
Write-Output "Caller still has: $counter"What happens
$counter is 10 at script level. The function reads it and prints 10, which shows reading crosses the boundary. It then assigns 99 and prints 99, which is the new local variable. After the function returns, the caller still sees 10, because the outer variable was never touched.
Worth remembering
- A function can read the caller's variables.
- Assigning creates a local copy. The original is unchanged.
- $script: and $global: reach outward, at the cost of clarity.
- Dot-sourcing with '. .\file.ps1' runs the file in the current scope.
Primary documentation
Try it
Illustrative output · values vary by environment
Example reader
Inspect this page's example
Run supported commands against the practice data, or inspect the example without executing it.
Ready to inspect.
Show reference output
Function sees: 10 Function set it to: 99 Caller still has: 10
Shows that a function reads outer variables but cannot assign to them.
Practise this
Store reusable function output
Define Get-ServiceSummary returning Name and Status, then store its output in $summary.
The sandbox is visible now. Sign in with Google only when you run or check a task; commands and temporary files are discarded when you leave.
Run a command to inspect its result.