Hey, Scripting Guy! A Scripting Overview of Windows PowerShell 2.0 (Part 2)

ScriptingGuy1

Bookmark and Share

(Note: Today’s Hey, Scripting Guy! Blog post is an edited excerpt from a forthcoming SAPIEN Press book authored by Don Jones and Jeffery Hicks. Don has published more than 30 books about IT pro topics; you can also find him in TechNet Magazine, on ScriptingAnswers.com, and on concentratedtech.com. Jeffery has authored or co-authored several books in the SAPIEN TFM series; he is a Windows PowerShell MVP, a columnist and contributing editor for Redmondmag.com, and a columnist for MCPMag.com. Find out more about Jeffery at http://jdhitsolutions.com/blog.

Today is part 2 of 2. Part 1 was published yesterday. Thanks again, Don and Jeffery!)

———-

Scripting Basics

Keep in mind that everything we’re covering related to scripting works fine when you’re using the shell interactively. So, you can use everything we’re about to show you even if you’re not planning on writing scripts at all.

Scope

Now that you’re going to begin working with scripts, you’re going to run up against a concept called scope, which is very important in Windows PowerShell. So far, we’ve just been working interactively in the shell, which is referred to as the global scope. When you’re just working interactively in the shell, everything occurs in the global scope, so it’s like there’s no scope at all.

However, when you run a script, Windows PowerShell creates a new script scope, which contains the script. The script scope is a child of the global scope; the global scope is referred to as the script scope’s parent. Some special rules govern interaction between the two scopes:

·         The parent scope cannot see “inside” the child scope.

·         The child scope can read elements of the parent scope but can modify them only if a special syntax is used.

·         If a child scope attempts to modify a parent scope element without using the special syntax, a new element of the same name is created within the child scope, and the child scope effectively “loses” access to the parent scope element of that name.

Elements, in the above rules, refer primarily to variables and functions. To reiterate these rules in a variable-centric sense:

·         The parent scope cannot access variables, which are defined in a child scope.

·         The child scope can read variables defined in the parent scope but can modify them only if a special syntax is used.

·         If a child scope attempts to modify a parent scope variable without using the special syntax, a new variable of the same name is created within the child scope, and the child scope effectively “loses” access to the parent scope variable of that name.

When you create a function—either by defining it in the global scope or, more commonly, within a script—the function itself is a local scope, and is considered a child of whatever scope it was created in. Here’s a quick example—we haven’t discussed functions yet, but this one isn’t complicated, so we hope it’ll help illustrate this scope stuff:

1.  $var1 = “Hello”

2.  Function MyFunction {Write-Host $var1

3.   $var1 = “Goodbye”

4.   Write-Host $var1

5.  }

6.  Write-Host $var1

7.  MyFunction

8.  Write-Host $var1


If you were to run this script, here’s the output you’d see:

Hello

Hello

Goodbye

Hello


Why is this true? The first executable line in this script is the first line, which sets the variable $var1 equal to the value “Hello”. Next, a function is defined, but not yet executed. Windows PowerShell skips over the function definition to line 7, where the contents of $var1 are displayed—our first line of output. Next, line 8 calls MyFunction. This enters the function, which is a child scope of the script scope. Line 3 displays the contents of $var1. Because $var1 hasn’t been defined in this scope, Windows PowerShell looks to the parent scope to see if $var1 exists there. It does, and so our second line of output is also “Hello”. Line 4 assigns a new value to $var1. Because a scope cannot directly modify its parent’s variables; however, line 4 is actually creating a new variable called $var1. When line 5 runs, $var1 now exists in the local scope, so our third line of output is “Goodbye”. When we exit the function, its scope is discarded. When line 9 runs, $var1 still contains its original value—the function never modified this $var1—so our last line of output is “Hello” again.

Now take a look at this slight revision:

1.  $var1 = “Hello”

2.  Function MyFunction {

3.   Write-Host $var1

4.   $script:var1 = “Goodbye”

5.   Write-Host $var1

6.  }

7.  Write-Host $var1

8.  MyFunction

9.  Write-Host $var1


We made the one line we changed (line 4) bold. This time, you’ll see:

Hello

Hello

Goodbye

Goodbye


Inside the function we’ve used the special syntax that allows a child scope to explicitly modify its parent’s variables. When we first look at $var, it has a value of “Hello”. Then we call the function, which reads $var from the parent scope. Then we make our special change using a scope identifier. There are four of these scope identifiers that Windows PowerShell recognizes:

·         $global: works with objects in the global scope.

·         $script: works with objects in the parent script scope.

·         $local: works with objects in the local scope.

·         $private: works with objects in a private scope.

When we attempt to read $var again, it is now set to “Goodbye”. When the script ends, the parent scope has been modified, and $var still equals “Goodbye”.

There’s another technique, called dot sourcing, which impacts scope. Take a look at our original example script, this time with additional modifications:

$var1 = “Hello”

Function MyFunction {

 Write-Host $var1

 $var1 = “Goodbye”

0 comments

Discussion is closed.

Feedback usabilla icon