Udostępnij za pośrednictwem


Deceiving scopes of variables in a function

I was recently troubleshooting a script when I came across a problem where a variable with defined scope was not retaining its value even though scope seemed correct. Let’s look at simplified example below:

 Function Global:Name-ofaFunction
{
$Global:VariableinQuestion = $null
$VariableinQuestion = "Value"
$VariableinQuestion
}

Name-ofaFunction
$VariableinQuestion

The function “Name-ofaFunction” when called, creates a variable with global scope and sets its value to null. Next, it sets the value of a variable and prints current value to host. Part of the script, I am also calling variable after running the function. This helps me verify the value.

When you run this script, however, you will notice that it prints current value (“Value”) of the variable only once.

If you debug the code, you will notice that the variable is set to null when exiting the function! Interesting why that is happening when you have defined the variable scope to be global in line 3!!!

So let’s try this code.

 Function Global:Name-ofaFunction
{
#$Global:VariableinQuestion = $null
$global:VariableinQuestion = "Value"
$VariableinQuestion
}

Name-ofaFunction
$VariableinQuestion

If you notice the difference, I have commented out line 3. Also, in line 4, I have added global scope to the variable. If you run this code, you will get the value of the variable printed to the host twice. Once inside the function and second time after the function!

How did that happen? The code doesn’t look much different. Only difference is where I define global scope. Why should that matter? Let me explain.

Although I am not sure if it is a feature or a bug, it seems PowerShell is resetting variable scope to local in line 4 in first example. Because it resets the scope to local, the variable loses its value and is set to null when exiting the function. This is because the variable is created inside the function and is scoped as local for the function. This is fixed in second example by defining it as global right where I am setting its value.

As you can imagine, there are many uses of setting correct scope of the variable. i.e. You may want to use the value returned by the function in another function. When you set the scope properly, the values are retained in appropriate scopes which can be used by other piece of code like functions of cmdlets run on host.

For more information on scope, you can read my previous blog post “PowerShell Variables and Scopes” and TechNet article “about_Scopes”.