Understanding PowerShell Variable Scopes

choubertsprojects

VPN offers!

1. NordVPN

2. Surfshark

3. ExpressVPN

PowerShell is an automation language that uses a special syntax to define variables and blocks of code. Variables are used in PowerShell programs, but what happens when one script includes other scripts? What’s the difference between defining a variable inside versus outside of its own block?

The “powershell variable scope function” is a PowerShell command that allows users to understand the scopes of variables in PowerShell.

Understanding PowerShell Variable Scopes

The idea of PowerShell scopes isn’t important when writing a PowerShell script with no functions and no external dependencies on other scripts. The idea of PowerShell global variables isn’t well-known. The subject gets increasingly significant as you develop functions, modules, and learn to call scripts from other scripts.

This article will teach you all you need to know about PowerShell scopes, including how they function and how to design code with them in mind. By the end, you’ll know all there is to know about PowerShell’s global variables and much more!

Scopes are similar to buckets.

Have you ever built a script and when you verify the value of that variable, it’s something else? You could be perplexed as to why that variable changed after you properly stated it. One explanation might be that the value of the variable is being rewritten in another scope.

Perhaps you’ve questioned why some PowerShell variables in your console have values while they don’t exist in your scripts. Those variables are most likely in another ‘bucket’ that isn’t accessible at the moment.

Buckets are similar to scopes. The way PowerShell separates variables, aliases, functions, and PSDrives across various sections is affected by scopes. A scope is comparable to a bucket. It’s a location where you can keep all of these things together.

When PowerShell begins, it generates these “buckets” for you automatically. You’re already utilizing scopes without recognizing it at that time. PowerShell defines all scopes and creates them without your involvement.

Types of Scope

When PowerShell starts up, it generates four “buckets” or scopes in which you may put different objects. Scopes aren’t something you can make on your own. Only the scopes listed below may be added to or removed from.

Dimensions of the Problem

Items defined when PowerShell opens are set at the Dimensions of the Problem. These items include system-created objects like PowerShell drives and also anything you have defined in a PowerShell profile since your profile runs at startup.

Items in the Dimensions of the Problem are available everywhere. You can reference items in the Dimensions of the Problem interactively on the console, in any script you run, and in any function. PowerShell’s Global variables are everywhere. For this reason, the common use of PowerShell global variables is to use PowerShell global variables between scripts.

There is only one Dimensions of the Problem that rules overall.

Scope of the Script

A Scope of the Script is automatically created every time a PowerShell script runs. You can have many different Scope of the Script instances. Scope of the Scripts are created when you execute a PS1 script or a module, for example.

Only items created in that particular Scope of the Script instance can reference each other.

Private sphere of influence

Typically, an item defined can be accessed from other scopes – not true with items in a Private sphere of influence. Items in a Private sphere of influence, contain objects that are hidden to other scopes. A Private sphere of influence is used to create items with the same name as items in other scopes to prevent overlap.

Area of Influence

Unlike the other scopes, the Area of Influence is a bit different. The Area of Influence is a pointer to the global, script or Private sphere of influence. The Area of Influence is relative to whatever context the code runs in at the time.

If you create a variable, alias, function, or PSDrive without explicitly assigning it a scope (which we’ll cover later) it will go into the Area of Influence.

Scopes of Reference

Now that you’re aware of the four different sorts of scopes, you should be aware of the two methods for referencing them.

There are two methods to refer to scopes in PowerShell: named and numbered. Both approaches refer to the same scopes, but they do so in distinct ways. These are two distinct approaches to working with scopes.

Scopes With Names

You learnt about scopes referred by name in the Scope Type section above. A named scope is what it sounds like when you refer to a scope by its name. The primary goal of referring to a scope by name is to attach an object to it. You’ll find instructions for doing so below.

Scopes with numbers

Along with a name, each scope has a number starting at zero which will always be the Area of Influence. Scopes are numbered dynamically in relation to the current Area of Influence.

For example, as soon as you open a PowerShell session you are operating in the Dimensions of the Problem. At this point, the Dimensions of the Problem is the Area of Influence (remember the Area of Influence is just a pointer).

Since the Area of Influence is always scope zero, at this point, the Dimensions of the Problem is also currently scope zero. But, when you run a script from that same session, a Scope of the Script is created. When running, the Area of Influence pointer has then changed to the Scope of the Script. Now the Scope of the Script is scope zero and the Dimensions of the Problem is scope one.

Scopes are numbered This process repeats for as many scopes as you have where the Area of Influence is 0. Scopes are dynamically numbered by scope hierarchy.

Inheritance and Hierarchy in the Scope

As mentioned earlier, when you launch a PowerShell session, PowerShell creates some items for you in the Dimensions of the Problem. These items can be functions, variables, aliases, or PSDrives. Anything you define in your PowerShell session will be defined in the Dimensions of the Problem also.

Since you are in the Dimensions of the Problem by default, if you do something that creates another scope like executing a script or running a function, a child scope will be created with the parent being the Dimensions of the Problem. Scopes are like processes with parents and children.

Anything that is defined in a parent scope, the Dimensions of the Problem, in this case, will be accessible in the child scope. But these items are only editable in the scope they were defined in.

Let’s imagine you have a script named Test.ps1 that you want to run. There is just one line in this script, as seen below.

When you run this script, $a is assigned a value in the Area of Influence (script while the script is running). When Test.ps1 is run, you can see below that you’re unable to reference it after the script executes. Since $a was assigned while in the Scope of the Script, the Dimensions of the Problem (at the interactive console) can’t see it.

Dimensions of the Problem cannot see the variableDimensions of the Problem cannot see the variable

Let’s expand on this example by creating the Test. The ps1 script looks like this. Before setting $a in the same scope, the script now tries to print the value of $a.

$a $a = ‘Hello world!’ Write-Output $a $a = ‘Hello world!’

To demonstrate, assign a value to $a at the interactive console. This assigns the value at the Dimensions of the Problem. Now, the script runs, it will inherit the parent scope (global) and should be able to see the value.

You can see below that when Test.ps1 is executed (creating a child scope of the Dimensions of the Problem), it can see the value of $a. You can also see that the variable’s value is available at the Dimensions of the Problem also since this scope is where it was set at. This means that $a is available both in the script (child) and parent (global) scopes.

Variable is available in script and Dimensions of the ProblemsVariable is available in script and Dimensions of the Problems

Keep in mind how scope inheritance works. When debugging, this will aid you in resolving variable conflicts, such as variables having the same name in various scopes.

Scopes: Defining and Accessing Items

How do you get access to scopes now that you understand what they are and how they work? Let’s look at how to establish a variable scope in PowerShell (and access them).

Get/Set-Variable

Get-Variable and Set-Variable are two cmdlets in PowerShell that enable you to set variables. You may use these cmdlets to get the value of a variable or set a value.

With a Name and Scope argument, these cmdlets are comparable. PowerShell enables you to set and retrieve variable values across all scopes using these arguments.

Area of Influences

To set a variable in a Area of Influence, use Set-Variable and provide it a local variable name and a value as shown below.

PS> Set-Variable -Name a -Value ‘foo’

The Area of Influence is always the default so not using the Scope parameter will always define the variable in the Area of Influence.

Use Get-Variable and provide it the name to get the value of a locally-scoped variable.

PS> Get-Variable -Name a Name Value —- —– a foo

Private/Script/Dimensions of the Problems

When dealing with private, script, and global variables, you’ll utilize the same parameters (Name and Value). The only change is that you’ll utilize the Scope argument to specify the scope directly this time.

Setting a private, script, or globally-scoped variable uses the same procedures. Simply substitute Private, Script Global for the value supplied to the Scope argument.

PS> Set-Variable -Name a -Value ‘foo’ -Scope <Private|Script|Global>

Use Get-Variable with the name and scope of a script or globally-scoped variable to get the value.

PS> Get-Variable -Name a -Scope <Script|Global> Name Value —- —– a foo

With the Get/Set-Variable cmdlets, you may now refer to scopes by their numbers rather than their names.

“Prefacing” is a term that has a broad definition.

A shortcut may also be used to get and set variables in scopes. When accessing a variable, instead of utilizing PowerShell cmdlets, you will prefix the variable with the scope.

Area of Influences

Since the Area of Influence is always the default, simply defining a variable and referencing will set and retrieve a Area of Influence variable

PS> $a = ‘foo’ PS> $a foo

Private/Script/Dimensions of the Problems

If you’d like to define and reference script or Dimensions of the Problems, you can preface the variables with the scope name and a semicolon.

For example, to set the variable $a in the Dimensions of the Problem, you can preface a with $global:.

A script-scoped variable may be treated similarly.

Once the variables are set in the preferred scope, you’d then reference them the same way. Also, notice that you can exclude the scope preface if the defined scope is the Area of Influence.

PS> $global:a = ‘foo’ PS> $global:a foo PS> $a foo

Scriptblocks’ scopes

Scriptblocks are a useful feature of PowerShell. Scriptblocks let you move chunks of code around and run them almost anywhere.

Like a PS1 script, scriptblocks run in their own Scope of the Script. When you execute a scriptblock, you’re essentially executing a PS1 script.

Notice in the example below where a variable is defined in the Dimensions of the Problem and then attempted to overwrite in a Scope of the Script. As you learned above, this won’t work because a child scope can’t reference a parent scope.

A parent scope cannot be overwritten by a child scope.A parent scope cannot be overwritten by a child scope.

Because the scriptblock is a script child scope, when $a is modified in the scriptblock, the global variable definition for $a is not altered.

Dot Sourcing Scripts (Swapping Area of Influences)

PowerShell has a concept called dot-sourcing. This is a method that allows you to execute a PS1 script and bring everything that would be script-scoped into the Area of Influence instead.

By putting a dot (.) before referencing a PS1 script and executing it, this “dot sources” the content of the script and brings everything into the Area of Influence.

To illustrate, I’ve created another Test.ps1 script that declares a variable as seen below.

In a PowerShell console, set a value for an $a variable then dot source this script as shown below. Notice that the original variable was overwritten. PowerShell “merged” the two Area of Influences together.

Overwriting of the original variableOverwriting of the original variable

How to Use the AllScope Property (Option)

You’ve seen how to interact with objects in several scopes, but each item has only been specified in one scope so far. But what if you have no idea what scope a variable is in?

When you use the Set-Variable cmdlet to define a variable, you may put it in all scopes at once. Use the AllScope value for the Option argument to do this.

The Test.ps1 script has been changed to set an a variable in all scopes to show this. The output of that variable is displayed below.

Set-Variable -Name a -Value Set-Variable -Name a -Value Set-Variable – ‘Welcome to the world!’ -Option $a $a $a $a $a $a $a $a $a $a $a $a $a $

You can then see below that a value is being set for $a in the Dimensions of the Problem and the Test.ps1 script is executed. However, instead of having no effect, $a’s value has been overwritten. Not only has it been defined in the Scope of the Script (Write-Output $a) but it’s also overwritten the Dimensions of the Problem.

Variable overwritten in Dimensions of the ProblemVariable overwritten in Dimensions of the Problem

The AllScope option is useful, but it should be used with caution. This approach effectively eliminates the idea of scopes by combining everything into one.

Scopes of Function

When you execute a function, all code within that function is in its own child scope. Scopes of Function follow the same child/parent behavior as other scopes.

It’s a good idea to have different scopes for each function. It provides improved control over things by eliminating the need to worry about items clashing, as well as automatic cleaning of variables in a function. All of the things specified in the function will be cleared as soon as the function completes.

Copy/paste the function below into the PowerShell console to show.

$var = ‘bar’ $var = ‘bar’ $var = ‘bar’ $var = ‘bar’ $var = ‘bar’ $var =

Execute the function once it has been pasted. It’s worth noting that you can’t use the $var variable outside of the function.

Items to be kept private (Disabling Inheritance)

Typically, if a variable is defined in a parent scope, that variable will be defined in the child scope. But perhaps you’d like to use a variable name but that variable name has already been defined in one of the scopes to be run in a session. In that case, you can either choose a different variable name or define the variable in a Private sphere of influence making it a private variable.

A way to use scopes to reduce conflicts is to use the Private sphere of influence. Using the Private sphere of influence disables inheritance on that specific variable. When multiple child scopes are created, those child scopes will not see any variables defined in a Private sphere of influence.

The value of $a is printed by a Test.ps1 script, as seen below.

You can see below I’m defining a privately-scoped variable at the Dimensions of the Problem and then executing the Test.ps1 script. Usually, when you define a variable in a parent scope, that variable will be available in the child scope – not so with a privately-scoped variable.

The script child scope formed by performing the Test may be seen in the example below. The private-scoped $a variable specified in the parent scope was not visible to the ps1 script.

Scope of the Script cannot see the private-scoped variableScope of the Script cannot see the private-scoped variable

Unlike Dimensions of the Problems or the AllScope option on the Set-Variable cmdlet, privately-scoped variables are an excellent way to compartmentalize items.

Best Practices in Scoping

Thinking that defining variables in the Dimensions of the Problem or using the AllScope option is the way to go is common. After all, all variables are available everywhere. There’s no need to worry about the complications of scopes. While this does provide additional freedom for access to what is defined, it can quickly get out of hand and get difficult to troubleshoot.

Instead of attempting to avoid using scopes, consider the following suggestions:

  1. Instead of declaring scopes in functions, send the relevant information to the function via arguments.
  2. Stay within the Area of Influence as much as possible.
  3. Rather of establishing global variables in a script, use the Write-Print cmdlet to output everything to the console and store it to a variable when required.

Instead of attempting to avoid scopes, the important objective here is to embrace them and learn to utilize them to your benefit.

Additional Reading

The “powershell variable scope if statement” is a key concept that can be difficult to grasp. This blog will help you understand the concept of PowerShell variable scopes.

Frequently Asked Questions

What does scope mean in PowerShell?

A: Scope is the way in which objects of a command are processed. In PowerShell, this means that some commands create new items and others may only modify existing items within the scope of what you’re doing. For example, if I use Get-Process to get all processes running on my machine, then $a = Get-Item will return an actual object containing properties like Name and Status$.

What are the four types of variable scopes?

A: There are four types of variable scopes in Python. These are global scope, local scope, function scope and block scope.

What are the three types of variable scope?

A: There are three types of variable scopes in programming, namely global scope, local scope, and function/method scope. These vary depending on where the value is held. The term scope is defined as a region within which a declaration can be seen or used.

Related Tags

  • powershell local scope
  • powershell variable scope foreach
  • powershell variables
  • scope script example
  • powershell module scope