{"id":3865,"date":"2013-04-07T00:01:00","date_gmt":"2013-04-07T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2013\/04\/07\/scope-in-action\/"},"modified":"2013-04-07T00:01:00","modified_gmt":"2013-04-07T00:01:00","slug":"scope-in-action","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/scope-in-action\/","title":{"rendered":"Scope in Action"},"content":{"rendered":"<p><strong style=\"font-size: 12px\">Summary<\/strong><span style=\"font-size: 12px\">: Microsoft PowerShell MVPs, Don Jones and Jeffery Hicks, talk about the impact of Windows PowerShell scope when creating tools.<\/span><\/p>\n<p>Microsoft Scripting Guy, Ed Wilson, is here. This week we will not have our usual <strong>PowerTip<\/strong>. Instead we have excerpts from seven books from Manning Press. In addition, each blog will have a special code for 50% off the book being excerpted that day. Remember that the code is valid only for the day the excerpt is posted. The coupon code is also valid for a second book from the Manning collection.<\/p>\n<p class=\"Body\" align=\"left\">This excerpt is from <a href=\"http:\/\/www.manning.com\/jones4\/\" target=\"_blank\">Learn PowerShell Toolmaking in a Month of Lunches<\/a><br \/> &nbsp; By Don Jones and Jeffery Hicks<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/4762.wes-4-7-13-1.jpg\"><img decoding=\"async\" style=\"border: 0px currentColor\" title=\"Photo of book cover\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/4762.wes-4-7-13-1.jpg\" alt=\"Photo of book cover\" \/><\/a><\/p>\n<p class=\"Body1\" align=\"left\">More than likely, your toolmaking projects will be on the complex side, and if you don&rsquo;t understand scope, you may end up with a bad tool. Scope is a system of containerization. In some senses, it&rsquo;s designed to help keep things in Windows PowerShell from conflicting with one another. In this blog, which is based on Chapter 5 of <a href=\"http:\/\/www.manning.com\/jones4\/\" target=\"_blank\">Learn PowerShell Toolmaking in a Month of Lunches<\/a>, you get to see scope in action<\/p>\n<p class=\"Body1\" align=\"left\">If you ran a script that defined a variable named <strong>$x<\/strong>, you&rsquo;d be pretty upset if some other script also used <strong>$x<\/strong>&nbsp;and somehow messed up your script. Scope is a way of building walls between and around different scripts and functions, so that each one has its own little sandbox to play in without fear of messing up something else.<\/p>\n<p class=\"Body\" align=\"left\">There are several elements within Windows PowerShell that are affected by scope:<\/p>\n<ul>\n<li>Variables<\/li>\n<li>Functions<\/li>\n<li>Aliases<\/li>\n<li>PSDrives<\/li>\n<li>PSSnapins (but oddly not modules, so as things migrate mainly to modules and away from PSSnapins, this won&rsquo;t matter much)<\/li>\n<\/ul>\n<p class=\"Body1\" align=\"left\">The shell itself is the top-level, or global, scope. That means that every new Windows PowerShell window you open is an entirely new, standalone, global scope&mdash;with no connection to any other global scope. The ISE lets you have multiple global scopes&nbsp;within the same window, which can be a bit confusing. In the ISE, when you click the <strong>New PowerShell<\/strong> tab on the <strong>File<\/strong> menu, you&rsquo;re creating a new Windows PowerShell runspace&mdash;which is equivalent to opening a new console window. Each of those tabs within the ISE is its own global scope. The following image shows what that looks like in the ISE. Note that it&rsquo;s the top, rectangular tabs that represent separate global scopes. The rounded tabs that hold script files live within that runspace, or global scope.<\/p>\n<p class=\"Body1\" align=\"left\"><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/5857.wes-4-7-13-2.png\"><img decoding=\"async\" style=\"border: 0px currentColor\" title=\"Image of menu\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/5857.wes-4-7-13-2.png\" alt=\"Image of menu\" \/><\/a><\/p>\n<p class=\"Body1\" align=\"left\">Each script that you run creates its own script scope. If a script calls a script, the second script gets its own script scope. Functions have their own scope, and a function that contains a function gets its own scope. As you can imagine, this can result in a pretty deep hierarchy, which the following image illustrates with a few global scope examples. There&rsquo;s even terminology for the scopes&rsquo; relationships: a scope&rsquo;s containing scope is called its parent; any scopes contained within a scope are its children. So the global scope is only a parent (because it&rsquo;s the top-level scope), and it contains children.<\/p>\n<p class=\"Body1\" align=\"left\"><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/8078.wes-4-7-13-3.png\"><img decoding=\"async\" style=\"border: 0px currentColor\" title=\"Image of scope examples\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/8078.wes-4-7-13-3.png\" alt=\"Image of scope examples\" \/><\/a><\/p>\n<p class=\"Body1\" align=\"left\">So here&rsquo;s the deal: If you create a variable within a script, that variable belongs to that script&rsquo;s scope. Everything inside that same scope can &ldquo;see&rdquo; that variable and its contents. The scope&rsquo;s parent can&rsquo;t see the variable.<\/p>\n<p class=\"Body1\" align=\"left\">Any child scopes, however, have an interesting behavior. Imagine a script named C:\\Tools.ps1, in which we create a variable named <strong>$computer<\/strong>. Within that script, we have a function named <strong>Get-OSInfo<\/strong>. (Sound familiar?) If <strong>Get-OSInfo<\/strong> attempts to access the contents of <strong>$computer<\/strong>, the operation will work.<\/p>\n<p class=\"Body1\" align=\"left\">But if <strong>Get-OSInfo<\/strong> attempts to change the contents of <strong>$computer<\/strong>, it will create a new variable, also named <strong>$computer<\/strong>, within its own scope. From then on, the function will be accessing its private version of <strong>$computer<\/strong>, which will be independent of the <strong>$computer<\/strong>&nbsp;in the script scope. This, as you imagine, can be crazy confusing, so let&rsquo;s see it in action to clarify. The following listing is a script that will help demonstrate scope.<span style=\"font-size: 12px\">&nbsp;<\/span><\/p>\n<p class=\"Body\" align=\"left\"><strong>Listing 1: Script.ps1 demonstrating scope<\/strong><span style=\"font-size: 12px\">&nbsp;<\/span><\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">$var = &#8216;hello!&#8217;<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&nbsp;<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">function My-Function {<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; Write-Host &#8220;In the function; var contains &#8216;$var'&#8221;<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; $var = &#8216;goodbye!&#8217;<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; Write-Host &#8220;In the function; var is now &#8216;$var'&#8221;<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">}<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">&nbsp;<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">Write-Host &#8220;In the script; var is &#8216;$var'&#8221;<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">Write-Host &#8220;Running the function&#8221;<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">My-Function<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">Write-Host &#8220;Function is done&#8221;<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">Write-Host &#8220;In the script; var is now &#8216;$var'&#8221;<\/p>\n<p class=\"Code\"><span style=\"font-size: 12px\">Let&rsquo;s run that and check out the results:<\/span><\/p>\n<p class=\"Body\" style=\"padding-left: 30px\" align=\"left\"><span style=\"font-size: 12px\">PS C:\\&gt; .\\script.ps1<\/span><\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">In the script; var is &#8216;hello!&#8217;<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">Running the function<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">In the function; var contains &#8216;hello!&#8217;<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">In the function; var is now &#8216;goodbye!&#8217;<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">Function is done<\/p>\n<p class=\"Code\" style=\"padding-left: 30px\">In the script; var is now &#8216;hello!&#8217;<\/p>\n<p class=\"Callout\" align=\"left\"><strong>Try it now&hellip;<\/strong> &nbsp;<\/p>\n<p class=\"Callout\" align=\"left\">Please, definitely run this script on your own&mdash;we want you to see the results for real, right in front of your eyes. It&rsquo;ll make it all clearer.<\/p>\n<p class=\"Callout\" align=\"left\">Read through the script&rsquo;s output. Notice that at the start of the script, <strong>$var<\/strong>&nbsp;contains hello! because that&rsquo;s what the first line in the script set it to. Then the function runs, and it sees that <strong>$var<\/strong> contains hello! That&rsquo;s because <strong>$var<\/strong> doesn&rsquo;t exist in the function&rsquo;s scope, so when it tries to access <strong>$var<\/strong>, Windows PowerShell goes to the scope&rsquo;s parent. Lo and behold, there&rsquo;s a <strong>$var<\/strong> there! So that&rsquo;s what the function sees.<\/p>\n<p class=\"Body\" align=\"left\">But then the function assigns goodbye! to <strong>$var<\/strong>. Windows PowerShell sees that <strong>$var<\/strong> still doesn&rsquo;t exist in the function&rsquo;s scope, so it creates the variable and puts goodbye! into it. There are now two copies of <strong>$var<\/strong> running around: one in the function&rsquo;s scope and one (which still contains hello!) in the script&rsquo;s scope. The global scope is still clueless about either of these; there&rsquo;s no <strong>$var<\/strong> in its scope, and it can&rsquo;t see the variables of its child scopes.<\/p>\n<p class=\"Body1\" align=\"left\">You have seen that scope creates walls between scripts and functions so that each one has space to play&mdash;messing up something else. The elements within Windows PowerShell that are affected by scope are variables, functions, aliases, PSDrives, and PSSnapins. We demonstrated that if you create a variable within a script, that variable belongs to that script&rsquo;s scope. Everything inside that same scope can see that variable and its contents, but the scope&rsquo;s parent can&rsquo;t see the variable.<\/p>\n<p class=\"Body\" align=\"left\">~Don and Jeffrey<\/p>\n<p style=\"padding-left: 30px\"><strong>Here is the code for the discount offer today at <\/strong><a href=\"http:\/\/www.manning.com\/\" target=\"_blank\">www.manning.com<\/a>: <strong>scriptw7<\/strong><br \/> Valid for 50% off <a href=\"http:\/\/www.manning.com\/jones4\/\" target=\"_blank\">Learn PowerShell Toolmaking in a Month of Lunches<\/a> and <a href=\"http:\/\/www.manning.com\/harryman\/\" target=\"_blank\">SharePoint 2010 Owner&#8217;s Manual<\/a> <br \/> Offer valid from April 7, 2013 12:01 AM until April 8, midnight (EST)<\/p>\n<p>I invite you to follow me on <a href=\"http:\/\/bit.ly\/scriptingguystwitter\" target=\"_blank\">Twitter<\/a> and <a href=\"http:\/\/bit.ly\/scriptingguysfacebook\" target=\"_blank\">Facebook<\/a>. If you have any questions, send email to me at <a href=\"mailto:scripter@microsoft.com\" target=\"_blank\">scripter@microsoft.com<\/a>, or post your questions on the <a href=\"http:\/\/bit.ly\/scriptingforum\" target=\"_blank\">Official Scripting Guys Forum<\/a>. See you tomorrow. Until then, peace.<\/p>\n<p><strong>Ed Wilson, Microsoft Scripting Guy<\/strong><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summary: Microsoft PowerShell MVPs, Don Jones and Jeffery Hicks, talk about the impact of Windows PowerShell scope when creating tools. Microsoft Scripting Guy, Ed Wilson, is here. This week we will not have our usual PowerTip. Instead we have excerpts from seven books from Manning Press. In addition, each blog will have a special code [&hellip;]<\/p>\n","protected":false},"author":596,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[64,56,65,3,4,45],"class_list":["post-3865","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-don-jones","tag-guest-blogger","tag-jeffery-hicks","tag-scripting-guy","tag-scripting-techniques","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>Summary: Microsoft PowerShell MVPs, Don Jones and Jeffery Hicks, talk about the impact of Windows PowerShell scope when creating tools. Microsoft Scripting Guy, Ed Wilson, is here. This week we will not have our usual PowerTip. Instead we have excerpts from seven books from Manning Press. In addition, each blog will have a special code [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/3865","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\/596"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=3865"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/3865\/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=3865"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=3865"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=3865"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}