Scope is awesome; it really is. In my mind, it is a protectionary layer to ensure things like variables are somewhat protected from say, modification. It can become a necessary concept for people using Powershell to understand. As I worked through some ideas recently, I ended up writing a function — this has been known to happen. As I sat there and fully comprehended what I had written, I began to realize that it may be worth sharing, so others can see it too. Sometimes we just need a simple example and a corresponding explanation. That has kind of been my goal over the years. Anyway, let’s focus on this function and I’ll explain what it is we have here and what it is doing.
The function is named, Get-TheVariable
and it contains four commands and four comments, although two of those comments are just dashed lines. I don’t usually write comments anything like this, but I really want to break up the commands into two segments, to make sure I am as clear as I can be, as we walk through this, together. Those segments are the Global scope and the Local scope, but we will get to that soon enough. Down beneath the function are two separate commands separated by a semi-colon. The first command just clears the screen — because sometimes I need that to stay clear-headed — and the second invokes the Get-TheVariable
function. Have a peek at the function now and then we will discuss it further below.
function Get-TheVariable { # Set and then get the GLOBAL version of the "Variable1" variable. # ---------------------------------------------------------------- Set-Variable -Name Variable1 -Value 'G' -Scope Global -Description 'Scope:Global' Get-Variable -Name Variable1 -Scope Global | Select-Object -Property Name,Value,Description # Set and then get the LOCAL version of the "Variable1" variable. # --------------------------------------------------------------- Set-Variable -Name Variable1 -Value 'L' -Scope Local -Description 'Scope:Local/Function' Get-Variable -Name Variable1 -Scope Local | Select-Object -Property Name,Value,Description } Clear-Host; Get-TheVariable
So what is happening here? Before we go there, know something about how Set
commands usually work. They work like New
commands, unless whatever we are to trying to create already exists. In that case, they just make modifications.
The first two commands create, or modify a variable (if it already exists) and then return the variable. It is named “Variable1,” its value — like what it stores — is “G,” it is globally scoped, and it includes a description indicating that. It is created by the function, but not inside the function. It is created outside of the function, in the global scope.
The second two commands kind of do the same things, They create, or modify a variable (if it already exists) and then return the variable. It is named “Variable1,” its value — what it stores — is “L,” it is locally scoped, and it includes a description indicating that. It is also created by the function, but it is inside of the function. It is created inside of the function, in the local scope. While these variables have many things in common, such as their name, they are different.
In the end — and sorry for all the repetition — there are going to be two variables with the same name. This is perfectly okay since they are going to be created in different scopes. In real life, I would recommend not using the same name for variables even if they are scoped differently. For this example, and for fully understanding this concept, it is important we do it this way.
The below output is created by our function. In the first line, we have information about our globally scoped “Variable1” variable that was created by the function, outside of the function. Because it is globally scoped it is going to persist outside of the function. In the second line, we have information about our locally scoped “Variable1” variable that was created by the function, inside the function. Because it is locally scoped, it is not going to persist outside the function.
During the invocation of the function, the function’s scope is the local scope. When the function’s invocation is done and over, the local scope is the global scope (again). The local scope is always the current scope.
Name Value Description ---- ----- ----------- Variable1 G Scope:Global Variable1 L Scope:Function
When the function has ended, the locally scoped “Variable1” variable stops existing. The global version, however, is still alive and well. Let’s prove it.
Get-Variable -Name Variable1 -Scope Global | Select-Object -Property Name,Value,Description Name Value Description ---- ----- ----------- Variable1 G Scope:Global
In the above example, using -Scope Global
was not necessary. Why? It’s because, again, we’re in the global scope and so there’s no need to tell the command to check a scope we are already in.
But, look at this.
Get-Variable -Name Variable1 -Scope Local | Select-Object -Property Name,Value,Description Name Value Description ---- ----- ----------- Variable1 G Scope:Global
What, the local variable still exists!? Uh, no, not the one created by the function for inside the function. This is kind of a recap — maybe the third or fourth one now, who knows. Again, now that we are outside of the function and back in the global scope, the Local
parameter value returns the globally scoped variable, too. See the Value and Description properties? They are the same as the global variable because the local variable is the global variable when we are in the global scope.
I am beginning to think I should have left this topic to someone else. Read it a few times and if maybe I have confused you — ask questions, Read more on about_Scopes. I feel good about this post, I just likely need to read it like 10 more times and ensure it mostly makes sense.
I do want to mention this real quick because it comes up often, and good for you for reading this far; it may just pay off. If you are invoking a function and you reference a variable that has not been created or defined in the function, PowerShell will look for it outside of its local scope. That’s to say that it will go looking for the variable you didn’t assign, in the global scope, also known as the parent scope. And with the introduction of that new term, the function’s scope has another name, too. It is the child scope. Okay, I’m done. Hopefully, this didn’t confuse anyone. Phew.