The PowerShell scopes article (about_Scopes) is nice, but too verbose, so this is quotation from my article:

In general, PowerShell scopes are like .NET scopes. They are:

  • Global is public
  • Script is internal
  • Private is private
  • Local is current stack level
  • Numbered scopes are from 0..N where each step is up to stack level (and 0 is Local)

Here is simple example, which describes usage and effects of scopes:

$test = 'Global Scope'
Function Foo {
    $test = 'Function Scope'
    Write-Host $Global:test                                  # Global Scope
    Write-Host $Local:test                                   # Function Scope
    Write-Host $test                                         # Function Scope
    Write-Host (Get-Variable -Name test -ValueOnly -Scope 0) # Function Scope
    Write-Host (Get-Variable -Name test -ValueOnly -Scope 1) # Global Scope
}
Foo

As you can see, you can use $Global:test like syntax only with named scopes, $0:test will be always $null.

Answer from Anton on Stack Overflow
🌐
Microsoft Learn
learn.microsoft.com › en-us › powershell › module › microsoft.powershell.core › about › about_scopes
about_Scopes - PowerShell | Microsoft Learn
January 16, 2026 - Explains the concept of scope in PowerShell and shows how to set and change the scope of elements.
🌐
Varonis
varonis.com › blog › powershell-variable-scope
PowerShell Variable Scope Guide: Using Scope in Scripts and Modules
October 13, 2022 - I defined the $greeting variable in the global console scope as “Hello, Jeff!”. I then ran the script file, which reassigned the value to “Hello, World!” using the $global: scope modifier. After running the script, the value of $greeting has been modified in the global console scope to the script’s value. A PowerShell module is a package of commands, such as cmdlets or functions, that have similar functions or purposes.
Discussions

PowerShell — Understanding Scope - by Rod Trent - myITforum
When working with PowerShell scripts and modules, understanding variable scope is paramount to writing efficient, reliable, and maintainable code. However, the distinctions between global, script, and local scopes often lead to confusion. More on myitforum.substack.com
🌐 myitforum.substack.com
May 15, 2025
scope - Variable scoping in PowerShell - Stack Overflow
A sad thing about PowerShell is that function and scriptblocks are dynamically scoped. But there is another thing that surprised me is that variables behave as a copy-on-write within an inner scop... More on stackoverflow.com
🌐 stackoverflow.com
Powershell: is there a Scope Preference for Variables? - Stack Overflow
Morning guys, hopefully just a quick one. Is there a Scope Preference for Variables like there is for some other settings ($ErrorActionPreference, etc)? I'm working on a script that has a bunch of More on stackoverflow.com
🌐 stackoverflow.com
.net - about scopes in Powershell - Stack Overflow
I'm learning about scopes in Powershell and have some questions: About the "Local scope": From what i read, the local scope is always the current scope. So, by default, when we create an... More on stackoverflow.com
🌐 stackoverflow.com
🌐
Reddit
reddit.com › r/powershell › question about scopes and best practices
r/PowerShell on Reddit: Question about scopes and best practices
February 9, 2023 -

about_Scopes

So we have three main scopes, from the looks of things:

  • global

  • local

  • script

I think I understand local; if you do not define a scope, the scope is defaulted to local. I think? Meanwhile, global is accessible to the whole session. I think?

In the context of functions, by default, any variable defined within a function is inaccessible outside of the function. You use return to pass data out of the function.

But, if you declare a variable outside the function with the global scope, you can access it within a function. I’ve used this to declare HashTables and Lists outside the function, and then add elements to the HashTable or List within a function.

Or, if you declare a variable with the global scope within a function, it will also be accessible outside the function. It’s not how I would do things, but a colleague made a pair of functions in a script to connect and disconnect from a database. He declared the database details and credentials at the top of the script using the global scope, and then created the connection within the connection function with the global scope. This allowed him to call the same connection variable in the disconnect function to close the connection. I’d have probably defined the connection outside of the connect function …

But, if I have all my code contained within one script, do I need to use the global scope to make variables accessible inside and outside of functions? Would the script scope work? The explanation in the link at the top suggests it wouldn’t work …

What is this best practice?

🌐
SS64
ss64.com › ps › syntax-scopes.html
Understanding Scopes in PowerShell
PowerShell scopes protect access to variables, aliases, functions, and PowerShell drives (PSDrives) by limiting where they can be read and changed.
🌐
Substack
myitforum.substack.com › p › powershell-understanding-scope
PowerShell — Understanding Scope - by Rod Trent - myITforum
May 15, 2025 - By defining where a variable can be read, written, or executed, scope ensures that different parts of your script or module do not unintentionally interfere with one another. PowerShell manages scopes to provide a structured way of handling variables and commands.
🌐
Powershellbyexample
powershellbyexample.dev › post › variable-scopes
Scopes | PowerShell By Example
When you create a variable, alias or a function in PowerShell, it is only available in the current scope where it was created. For example, when you create a variable in a function, it is only available in the function.
Find elsewhere
Top answer
1 of 1
3

Is there a Scope Preference for Variables like there is for some other settings ($ErrorActionPreference, etc)?

No, scoping behavior is part of the language's core runtime semantics and is not configurable.

I'm working on a script that has a bunch of functions that call on information created in each other and I'm just looking to avoid writing $Script: or $Global: in front of each variable everytime

You don't need it everytime - you only need the scope modifier when you're writing to a parent scope.

Resolution of variables for reading will fall back through parent scopes and eventually the global scope, until a matching variable is found:

# variable defined at script scope, functions defined in here will fall back to resolving this when `$Config` is referenced
$Config = @{
  'setting' = 'initialValue'
}

function Update-Config {
  # Scope modifier is only necessary when "writing up" through the scope stack
  $script:Config = @{
    setting = 'updatedValue'
  }
}

function Do-Stuff {
  $setting = $Config['setting'] # no need to use script: here

  Write-Host "About to do something with '$setting'"
}

Do-Stuff
Update-Config
Do-Stuff

Executing the above in a script file will print:

About to do something with 'initialValue'
About to do something with 'updatedValue'

Note that for functions bound to a module, the script: scope is shared across the module - writing to $script:Variable in one module function will cause resolution of non-local $Variable to resolve correctly in any other function in the same module

For more information about scoped variable resolution, consult the about_Scopes help file

Top answer
1 of 2
4

Starting with the latter question:

Scopes come in play with functions and invoked scripts(cmdlets), like:

Function Test {
    $Test++
    Write-Host 'Local:' $Test
}
$Test = 5
Test
Write-Host 'Global:' $Test

Returns:

Local: 6
Global: 5

And:

Function Test {
    $Global:Test++
    Write-Host 'Local:' $Test
}
$Test = 5
Test
Write-Host 'Global:' $Test

Returns:

Local: 6
Global: 6

Or if you put the function in a script (e.g. MyScript.ps1):

$Test = 5
.\MyScript.ps1
Write-Host $Test # $Test is unaffected unless you use the $Global scope in your script

Which will return basically the same results as above, unless you Dot-Source your script where it will run in the current scope:

$Test = 5
. .\MyScript.ps1
Write-Host $Test # $Test might be affected by MyScript.ps1 if you just use $Test

For what you are doing:
You are creating a complete new PowerShell session (with Powershell.exe) which will start with a fresh list of variables.
Note here that you will see the initial variables again if you exit from the new session:

PS C:\> $Name = "John"
PS C:\> Powershell.exe
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

Try the new cross-platform PowerShell https://aka.ms/pscore6

PS C:\> Write-Host 'New session' $Name
New session
PS C:\> Exit
PS C:\> Write-Host 'Initial session' $Name
Initial session John

Which regards to the first question, I don't think that there are many applications where you need to explicitly refer to the $Local scope, but to give you an example where you might use it:

$Test = 5
Function Test {
    Write-Host ($Local:Test++)
}
Test

In the above example the unary increment operator will start with 0 if you explicitly use the $Local scope (in fact you starting with an empty local variable which will cast to 0) and with 5 if you omit the $Local scope where you will inherit a copy of the $Test variable out of the parent scope.

2 of 2
3

To complement iRon's helpful answer:

  1. [...] when will we need to explicitly specify the local modifier?

$local: is rarely required, because the local scope is implied in the absence of a scope specifier.

However, that only applies if the referenced variable actually exists as a local variable, given that PowerShell's dynamic scoping makes variables from ancestral (parent) scopes visible to descendant (child) scopes as well (see this answer for more information):

  • For example, say you have $foo = 'bar' declared in the global scope, then referring to $foo in a script would look for a local $foo instance first; if there is none, a $foo defined in an ancestral (parent) scope is used, if any, which would be the global $foo in this example, and 'bar' would be returned.

  • By contrast, if, in your script, you use $local:foo, without a local $foo variable being defined, you either get $null by default or, if Set-StrictMode -Version 2 or higher is in effect, a statement-terminating error occurs.


  1. MSDN says: [...] by creating a session, or by starting a new instance of PowerShell [...] the result is a parent scope (the original scope) and a child scope (the scope that you created).

The documentation is incorrect in this regard as of this writing (a GitHub issue has been filed):

  • Ancestral (parent-child) relationships between scopes exist only in the context of a given session (runspace).

    • That is, dynamic scoping - the visibility of variables and other definitions from ancestral scopes - only applies to scopes within a given session.

    • A notable exception is that functions from a module do not run in a child scope of the calling scope - except if the that calling scope happens to be the global scope; modules have their own scope domains (technically called session states) that are linked to the global scope only - see this GitHub docs issue for a discussion.

  • Therefore, no child scope of the calling scope is created in the following scenarios, where the newly launched code knows nothing of the variables (and other definitions) in the calling scope:

    • Starting a new session via PowerShell remoting (e.g., with Enter-PSSession) or Invoke-Command -Computer

    • Starting a background [thread] job with Start-Job or Start-ThreadJob or running threads in parallel with ForEach-Object -Parallel in v7.0+

    • Starting a new PowerShell instance (process), using the PowerShell CLI (pwsh for PowerShell [Core], powershell.exe for Windows PowerShell).

    • To communicate values from the calling scope to the newly launched code in these scenarios, explicit action is required:

      • When calling the CLI or using Start-Job, where a child process on the same machine is created, only environment variables defined in the calling process become automatically available to the child process.
      • Otherwise, values from the caller must be passed as arguments or - except when using the CLI - via the $using: scope - see this answer.
🌐
Powershelluniversal
docs.powershelluniversal.com › apps › custom-variable-scopes
Custom Variable Scopes | PowerShell Universal
January 6, 2026 - Universal Apps expose three custom variable scopes using custom providers. These providers allow you to store your variables in scopes that make sense for a web application. The cache scope is used to store variables that can be used within any endpoint inside an app.
🌐
Adam the Automator
adamtheautomator.com › powershell-scopes
PowerShell Scopes: Understanding Variable Scope
January 27, 2026 - Maybe you’ve wondered how certain PowerShell variables have values when you reference them in your console but don’t exist in your scripts. Chances are those variables are in another ‘bucket’ that’s not available at that time. Scopes are like buckets.
🌐
How-To Geek
howtogeek.com › home › scopes in powershell
Scopes in PowerShell
December 29, 2020 - These are global, local, and script and tell PowerShell what variables and functions are available in what context. When referencing scopes, you usually use scope prefixes to reach variables outside the current, local, scope.
🌐
4sysops
4sysops.com › home › blog › articles › the powershell variable scope
The PowerShell variable scope – 4sysops
July 28, 2023 - Scopes are organized in hierarchies. At the top sits the Global scope. This scope is created whenever you start a PowerShell session. The Script scope is one level below the Global scope. Next is the scope of a function that you define in your script, and, if you create a function within a function, you also create a new scope that sits below the other scopes.
🌐
clan8blog
clan8blog.wordpress.com › powershell-variable-scope
PowerShell Variable Scope - clan8blog - WordPress.com
November 6, 2013 - When you prefix a variable with it’s scope it is read and write, i.e. you can update the value. If you don’t prefix the variable then PowerShell will search for the variable in the private scope then local, then script and then finally global scope before giving up and sulking.
🌐
Hosting Ultra So
hostingultraso.com › help › windows › control-access-scope-variables-other-items-windows-powershell
Control Access and Scope of Variables and Other Items in Windows PowerShell | Windows PowerShell, Windows Server | HostingUltraso.com
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
🌐
O'Reilly
oreilly.com › library › view › mastering-windows-powershell › 9781787126305 › dbc49d6e-a8d3-4501-92c6-d992cab49f31.xhtml
Script scope - Mastering Windows PowerShell Scripting - Second Edition [Book]
October 27, 2017 - The Script scope is a useful place to store variables which must be shared without exposing the variable to the Global scope (and therefore to anyone with access to the session).
Authors   Chris DentBrenton J.W. Blawat
Published   2017
Pages   440
🌐
Datatechguard
datatechguard.com › home › powershell variable scope guide: using scope in scripts
PowerShell Variable Scope Guide: Using Scope in Scripts
December 4, 2025 - In PowerShell, we have four main scopes: global, local, script, and private. The global scope is in effect when PowerShell starts and is accessible everywhere. The local scope, on the other hand, represents the current scope and can be the global ...
🌐
Davemason
davemason.me › 2021 › 11 › 30 › powershell-variables-and-scope
PowerShell Variables and Scope - It's All Just Electrons
November 29, 2021 - In a word, yes. You can see evidence of this from Intellisense in your development tool. Here's what you'd see in the PowerShell ISE: I don't know of an ideal way to programatically list out just the user-defined variables that are in scope for the current session and available in the console.
🌐
Ais
ais.com › home › blog › powershell 101: script cleanup using variable scope
PowerShell 101: Script Cleanup Using Variable Scope - Applied Information Sciences
August 28, 2023 - Named scopes are “Global,” “Local (default),” and “Script”. Global is accessible to the current runspace. Local is accessible within the current running function. Script is accessible in the current running script.