First rule of PowerShell scoping rules...
- Written by Alexander Riedel
- Last Updated: 21 April 2016
- Created: 06 March 2013
- Hits: 10198
… never talk about PowerShell scoping rules.
Judging from the posts, emails and questions we get about variable scope in PowerShell Studio forms, PowerShell scoping rules are shrouded in mystery. When you read about_scopes you get a lot of information. When you come from any other scripting language, for example VBScript, you are used to two scopes; global and local. The default scope of a variable in VBScript depends on its first use or its declaration. So if you want a variable to have a specific scope you just declare it with a DIM statement.
This code sample illustrates the simple scoping rules in VBScript. A variable is global or local and yes, a local variable can shadow a global one with the same name.
The output is very much what you expect:
Now let’s do that in PowerShell:
And the result is:
The keen observer will immediately notice that $globalvariable never produces any output. That is because a variable in PowerShell is not global unless you specifically say so by using $global:globalvariable. Always. At every use. So what is the scope of $globalvariable in our example? It’s ‘local’, local to the global scope to be precise. Unless specified otherwise nothing is ever global.
So how do you set a variable from a child context?
1. You can use a return value of a function
2. You can pass the variable as a parameter reference
Note that you cannot just assign a value to $globalvariable, that would just create a local variable of that name shadowing the parameter. You are passing a reference object, so you have to use the value property.
3. Use $global: or $script: to modify the scope of the variable.
If you are five levels removed from the definition or in a completely different context, for example in the event handler for a button in a Windows form, this might be the simplest solution.
One last final remark and we will not talk about this anymore. Read the about article on scope. Try the examples. You will need it.