{"id":51333,"date":"2010-02-11T00:01:00","date_gmt":"2010-02-11T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2010\/02\/11\/hey-scripting-guy-a-scripting-overview-of-windows-powershell-2-0-part-2\/"},"modified":"2010-02-11T00:01:00","modified_gmt":"2010-02-11T00:01:00","slug":"hey-scripting-guy-a-scripting-overview-of-windows-powershell-2-0-part-2","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/hey-scripting-guy-a-scripting-overview-of-windows-powershell-2-0-part-2\/","title":{"rendered":"Hey, Scripting Guy! A Scripting Overview of Windows PowerShell 2.0 (Part 2)"},"content":{"rendered":"<h2><a href=\"http:\/\/www.addthis.com\/bookmark.php?v=250&amp;pub=scriptingguys\" class=\"addthis_button\"><img decoding=\"async\" height=\"16\" width=\"125\" src=\"http:\/\/s7.addthis.com\/static\/btn\/v2\/lg-share-en.gif\" alt=\"Bookmark and Share\"><\/a><\/p>\n<p>(Note: Today&#8217;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 <em>TechNet Magazine<\/em>, 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 <a href=\"http:\/\/jdhitsolutions.com\/blog\">http:\/\/jdhitsolutions.com\/blog<\/a>.<\/p>\n<p>Today is part&nbsp;2 of 2. Part&nbsp;1 was published <a href=\"http:\/\/blogs.technet.com\/heyscriptingguy\/archive\/2010\/02\/10\/hey-scripting-guy-february-10-2010.aspx\" title=\"yesterday\">yesterday<\/a>. Thanks again, Don and Jeffery!)<\/p>\n<p>&#8212;&#8212;&#8212;-<\/p>\n<p><span><span style=\"font-size: small\">  <\/p>\n<h2><span><span style=\"font-family: Arial Black;font-size: medium\">Scripting Basics<\/span><\/span><span style=\"font-size: medium\"><\/p>\n<p><\/span><\/h2>\n<p class=\"MsoNormal\"><span>Keep in mind that everything we&rsquo;re covering related to scripting works fine when you&rsquo;re using the shell interactively. So, you can use everything we&rsquo;re about to show you even if you&rsquo;re not planning on writing scripts at all. <\/p>\n<p><\/span><\/p>\n<h2><span><span style=\"font-family: Arial Black;font-size: small\">Scope<\/span><\/span><\/p>\n<\/h2>\n<p class=\"MsoNormal\"><span>Now that you&rsquo;re going to begin working with scripts, you&rsquo;re going to run up against a concept called <i>scope<\/i>, which is very important in Windows PowerShell. So far, we&rsquo;ve just been working interactively in the shell, which is referred to as the <i>global scope<\/i>. When you&rsquo;re just working interactively in the shell, everything occurs in the global scope, so it&rsquo;s like there&rsquo;s no scope at all.<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>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&rsquo;s parent. Some special rules govern interaction between the two scopes:<\/p>\n<p><\/span><\/p>\n<p class=\"BulletedList\"><span><span>&middot;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><span>The parent scope cannot see &ldquo;inside&rdquo; the child scope.<\/p>\n<p><\/span><\/p>\n<p class=\"BulletedList\"><span><span>&middot;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><span>The child scope can read elements of the parent scope but can modify them only if a special syntax is used.<\/p>\n<p><\/span><\/p>\n<p class=\"BulletedList\"><span><span>&middot;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><span>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 &ldquo;loses&rdquo; access to the parent scope element of that name.<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>Elements, in the above rules, refer primarily to variables and functions. To reiterate these rules in a variable-centric sense:<\/p>\n<p><\/span><\/p>\n<p class=\"BulletedList\"><span><span>&middot;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><span>The parent scope cannot access variables, which are defined in a child scope.<\/p>\n<p><\/span><\/p>\n<p class=\"BulletedList\"><span><span>&middot;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><span>The child scope can read variables defined in the parent scope but can modify them only if a special syntax is used.<\/p>\n<p><\/span><\/p>\n<p class=\"BulletedList\"><span><span>&middot;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><span>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 &ldquo;loses&rdquo; access to the parent scope variable of that name.<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>When you create a function&mdash;either by defining it in the global scope or, more commonly, within a script&mdash;the function itself is a local scope, and is considered a child of whatever scope it was created in. Here&rsquo;s a quick example&mdash;we haven&rsquo;t discussed functions yet, but this one isn&rsquo;t complicated, so we hope it&rsquo;ll help illustrate this scope stuff:<\/p>\n<p><\/span><\/p>\n<div>\n<p class=\"CodeStart\"><span><span>1.<span>&nbsp; <\/span><\/span><\/span><span>$var1 =\n&#8220;Hello&#8221;<\/p>\n<p><\/span><\/p>\n<\/p><\/div>\n<p class=\"CodeMiddle\"><span><span>2.<span>&nbsp; <\/span><\/span><\/span><span>Function MyFunction {Write-Host $var1<\/p>\n<p><\/span><\/p>\n<p class=\"CodeMiddle\"><span><span>3.<span>&nbsp; <\/span><\/span><\/span><span><span>&nbsp;<\/span>$var1 = &#8220;Goodbye&#8221;<\/p>\n<p><\/span><\/p>\n<p class=\"CodeMiddle\"><span><span>4.<span>&nbsp; <\/span><\/span><\/span><span><span>&nbsp;<\/span>Write-Host $var1<\/p>\n<p><\/span><\/p>\n<p class=\"CodeMiddle\"><span><span>5.<span>&nbsp; <\/span><\/span><\/span><span>}<\/p>\n<p><\/span><\/p>\n<p class=\"CodeMiddle\"><span><span>6.<span>&nbsp; <\/span><\/span><\/span><span>Write-Host $var1<\/p>\n<p><\/span><\/p>\n<p class=\"CodeMiddle\"><span><span>7.<span>&nbsp; <\/span><\/span><\/span><span>MyFunction<\/p>\n<p><\/span><\/p>\n<div>\n<p class=\"CodeEnd\"><span><span>8.<span>&nbsp; <\/span><\/span><\/span><span>Write-Host $var1<\/p>\n<p><\/span><\/p>\n<\/p><\/div>\n<p class=\"MsoNormal\"><span><br \/>If you were to run this script, here&rsquo;s the output you&rsquo;d see:<\/p>\n<p><\/span><\/p>\n<div>\n<p class=\"CodeStart\"><span>Hello<\/p>\n<p><\/span><\/p>\n<\/p><\/div>\n<p class=\"CodeMiddle\"><span>Hello<\/p>\n<p><\/span><\/p>\n<p class=\"CodeMiddle\"><span>Goodbye<\/p>\n<p><\/span><\/p>\n<div>\n<p class=\"CodeEnd\"><span>Hello<\/p>\n<p><\/span><\/p>\n<\/p><\/div>\n<p class=\"MsoNormal\"><span><br \/>Why is this true? The first executable line in this script is the first line, which sets the variable <b>$var1<\/b> equal to the value &ldquo;Hello&rdquo;. Next, a function is defined, but not yet executed. Windows PowerShell skips over the function definition to line 7, where the contents of <b>$var1<\/b> are displayed&mdash;our first line of output. Next, line 8 calls <b>MyFunction<\/b>. This enters the function, which is a child scope of the script scope. Line 3 displays the contents of <b>$var1<\/b>. Because <b>$var1<\/b> hasn&rsquo;t been defined in this scope, Windows PowerShell looks to the parent scope to see if <b>$var1<\/b> exists there. It does, and so our second line of output is also &ldquo;Hello&rdquo;. Line 4 assigns a new value to <b>$var1<\/b>. Because a scope cannot directly modify its parent&rsquo;s variables; however, line 4 is actually creating a new variable called <b>$var1<\/b>. When line 5 runs, <b>$var1<\/b> now exists in the local scope, so our third line of output is &ldquo;Goodbye&rdquo;. When we exit the function, its scope is discarded. When line 9 runs, <b>$var1<\/b> still contains its original value&mdash;the function never modified this <b>$var1<\/b>&mdash;so our last line of output is &ldquo;Hello&rdquo;\n again.<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>Now take a look at this slight revision:<\/p>\n<p><\/span><\/p>\n<div>\n<p class=\"CodeStart\"><span><span>1.<span>&nbsp; <\/span><\/span><\/span><span>$var1 = &#8220;Hello&#8221;<\/p>\n<p><\/span><\/p>\n<\/p><\/div>\n<p class=\"CodeMiddle\"><span><span>2.<span>&nbsp; <\/span><\/span><\/span><span>Function MyFunction {<\/p>\n<p><\/span><\/p>\n<p class=\"CodeMiddle\"><span><span>3.<span>&nbsp; <\/span><\/span><\/span><span><span>&nbsp;<\/span>Write-Host $var1<\/p>\n<p><\/span><\/p>\n<p class=\"CodeMiddle\"><b><span><span>4.<span>&nbsp; <\/span><\/span><\/span><\/b><b><span><span>&nbsp;<\/span>$script:var1 = &#8220;Goodbye&#8221;<\/p>\n<p><\/span><\/b><\/p>\n<p class=\"CodeMiddle\"><span><span>5.<span>&nbsp; <\/span><\/span><\/span><span><span>&nbsp;<\/span>Write-Host $var1<\/p>\n<p><\/span><\/p>\n<p class=\"CodeMiddle\"><span><span>6.<span>&nbsp; <\/span><\/span><\/span><span>}<\/p>\n<p><\/span><\/p>\n<p class=\"CodeMiddle\"><span><span>7.<span>&nbsp; <\/span><\/span><\/span><span>Write-Host $var1<\/p>\n<p><\/span><\/p>\n<p class=\"CodeMiddle\"><span><span>8.<span>&nbsp; <\/span><\/span><\/span><span>MyFunction<\/p>\n<p><\/span><\/p>\n<div>\n<p class=\"CodeEnd\"><span><span>9.<span>&nbsp; <\/span><\/span><\/span><span>Write-Host $var1<\/p>\n<p><\/span><\/p>\n<\/p><\/div>\n<p class=\"MsoNormal\"><span><br \/>We made the one line we changed (line 4) bold. This time, you&rsquo;ll see:<\/p>\n<p><\/span><\/p>\n<div>\n<p class=\"CodeStart\"><span>Hello<\/p>\n<p><\/span><\/p>\n<\/p><\/div>\n<p class=\"CodeMiddle\"><span>Hello<\/p>\n<p><\/span><\/p>\n<p class=\"CodeMiddle\"><span>Goodbye<\/p>\n<p><\/span><\/p>\n<div>\n<p class=\"CodeEnd\"><span>Goodbye<\/p>\n<p><\/span><\/p>\n<\/p><\/div>\n<p class=\"MsoNormal\"><span><br \/>Inside the function we&rsquo;ve used the special syntax that allows a child scope to explicitly modify its parent&rsquo;s variables. When we first look at <b>$var<\/b>, it has a value of &ldquo;Hello&rdquo;. Then we call the function, which reads <b>$var<\/b> 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:<\/p>\n<p><\/span><\/p>\n<p class=\"BulletedList\"><span><span>&middot;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><b><span>$global<\/span><\/b><span>: works with objects in the global scope.<\/p>\n<p><\/span><\/p>\n<p class=\"BulletedList\"><span><span>&middot;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><b><span>$script<\/span><\/b><span>: works with objects in the parent script scope.<\/p>\n<p><\/span><\/p>\n<p class=\"BulletedList\"><span><span>&middot;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><b><span>$local<\/span><\/b><span>: works with objects in the local scope.<\/p>\n<p><\/span><\/p>\n<p class=\"BulletedList\"><span><span>&middot;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><b><span>$private<\/span><\/b><span>: works with objects in a private scope.<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>When we attempt to read <b>$var<\/b> again, it is now set to &ldquo;Goodbye&rdquo;. When the script ends, the parent scope has been modified, and <b>$var<\/b> still equals &ldquo;Goodbye&rdquo;.<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>There&rsquo;s another technique, called dot sourcing, which impacts scope. Take a look at our original example script, this time with additional modifications:<\/p>\n<p><\/span><\/p>\n<div>\n<p class=\"CodeStart\"><span>$var1 = &#8220;Hello&#8221;<\/p>\n<p><\/span><\/p>\n<\/p><\/div>\n<p class=\"CodeMiddle\"><span>Function MyFunction {<\/p>\n<p><\/span><\/p>\n<p class=\"CodeMiddle\"><span><span>&nbsp;<\/span>Write-Host $var1<\/p>\n<p><\/span><\/p>\n<p class=\"CodeMiddle\"><span><span>&nbsp;<\/span>$var1 = &#8220;Goodbye&#8221;<\/p>\n<p><\/span><\/p>\n<p class=\"CodeMiddle\">\n<p><\/span><\/span><\/p>\n<\/h2>\n","protected":false},"excerpt":{"rendered":"<p>(Note: Today&#8217;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 [&hellip;]<\/p>\n","protected":false},"author":595,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[64,51,56,65,3,4,45],"class_list":["post-51333","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-don-jones","tag-getting-started","tag-guest-blogger","tag-jeffery-hicks","tag-scripting-guy","tag-scripting-techniques","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>(Note: Today&#8217;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 [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/51333","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/users\/595"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=51333"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/51333\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media\/87096"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media?parent=51333"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=51333"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=51333"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}