{"id":12021,"date":"2011-11-21T00:01:00","date_gmt":"2011-11-21T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2011\/11\/21\/make-a-simple-change-to-powershell-to-prevent-accidents\/"},"modified":"2011-11-21T00:01:00","modified_gmt":"2011-11-21T00:01:00","slug":"make-a-simple-change-to-powershell-to-prevent-accidents","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/make-a-simple-change-to-powershell-to-prevent-accidents\/","title":{"rendered":"Make a Simple Change to PowerShell to Prevent Accidents"},"content":{"rendered":"<p><b>Summary<\/b>: Learn how a simple change to a preference variable can help prevent accidental changes when using Windows PowerShell.<\/p>\n<p>&nbsp;<\/p>\n<p>Microsoft Scripting Guy Ed Wilson here. When I was teaching my Windows PowerShell Best Practices class out in Irvine, California, recently, I was talking to the class about the <i>whatif <\/i>parameter. I did my usual introduction to the feature, which goes something like this:<\/p>\n<p>&ldquo;How many of you have ever typed a command at the command line, and you did not know in advance exactly what the command would do?&rdquo; (Most of the hands in the room rise). &ldquo;Okay, now, how many of you have ever done that on a production server?&rdquo; (Most of the hands lower, but a considerable number are still up. I note for the benefit of the class that my hand is still up.)<\/p>\n<p>One reason so many hands were up was that, when troubleshooting servers or attempting to repair servers that have problems, it is common to find a TechNet article that says open the command prompt and type these dozen cryptic commands and press Enter. It is not that network administrators are cowboys who go riding happily off into uncharted territory, but it is that they are put into the unenviable situation of having to make hard choices. Type the command and hope for the best, or suffer along and hope the server stays up for a bit longer.<\/p>\n<p>I boldly proclaim that if they use the <i>whatif <\/i>switch on Windows PowerShell commands, it will add at least a fractional percentage point to their system up time. I have no research to back this up, but it does stand to reason. A student in California raised her hand, and asked this:<\/p>\n<p>&ldquo;But what if the admin does not use the <i>whatif <\/i>switch? Then what?&rdquo;<\/p>\n<p>Well, at first, I felt like saying, &ldquo;I guess you are out of luck.&rdquo; But then I remembered a little-known and little-used preference variable&mdash;the <b>$WhatIfPreference<\/b> variable. The <b>$WhatIfPreference<\/b> variable is hanging out on the <b>Variable<\/b> drive with a value of <b>false<\/b><i>. <\/i>This is shown in the following code:<\/p>\n<p style=\"padding-left: 30px\">PS C:\\&gt; dir Variable:\\WhatIfPreference<\/p>\n<p style=\"padding-left: 30px\"><span style=\"text-decoration: underline\">Name<\/span>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style=\"text-decoration: underline\">Value<\/span><\/p>\n<p style=\"padding-left: 30px\">WhatIfPreference&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; False<\/p>\n<p>What the <b>$WhatIfPreference<\/b> variable does is flip the <i>whatif <\/i>parameter to on, for every Windows PowerShell cmdlet that supports a <i>whatif <\/i>switch. This means that every cmdlet that changes system state will no longer change system state by default. To illustrate, I am going to start an instance of Notepad. I will then use the <b>Get-Process<\/b> to retrieve the process, and pipe it to <b>Stop-Process<\/b>&mdash;and the Notepad process goes away. This is shown here:<\/p>\n<p style=\"padding-left: 30px\">PS C:\\&gt; $ErrorView = &#8220;CategoryView&#8221;<\/p>\n<p style=\"padding-left: 30px\">PS C:\\&gt; notepad<\/p>\n<p style=\"padding-left: 30px\">PS C:\\&gt; get-process notepad | Stop-Process<\/p>\n<p style=\"padding-left: 30px\">PS C:\\&gt; get-process notepad<\/p>\n<p style=\"padding-left: 30px\">ObjectNotFound: (notepad:String) [Get-Process], ProcessCommandException<\/p>\n<p>Next, I change and use the <i>whatif <\/i>parameter when calling the <b>Stop-Process<\/b> cmdlet. The <i>whatif <\/i>parameter, lets me know that it would stop an instance of the Notepad process, the one with the process ID of 6052, if the command ran without the <i>whatif <\/i>parameter. I then use the <b>Get-Process<\/b> cmdlet to confirm that the instance of Notepad with the process ID of 6052 still runs. These commands and associated output are shown here:<\/p>\n<p style=\"padding-left: 30px\">PS C:\\&gt; notepad<\/p>\n<p style=\"padding-left: 30px\">PS C:\\&gt; get-process notepad | Stop-Process -WhatIf<\/p>\n<p style=\"padding-left: 30px\">What if: Performing operation &#8220;Stop-Process&#8221; on Target &#8220;notepad (6052)&#8221;.<\/p>\n<p style=\"padding-left: 30px\">PS C:\\&gt; get-process notepad<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\"><span style=\"text-decoration: underline\">Handles<\/span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style=\"text-decoration: underline\">NPM(K)<\/span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style=\"text-decoration: underline\">PM(K)<\/span>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style=\"text-decoration: underline\">WS(K)<\/span>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style=\"text-decoration: underline\">VM(M)<\/span>&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style=\"text-decoration: underline\">CPU(s)<\/span>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style=\"text-decoration: underline\">ID ProcessName<\/span><\/p>\n<p style=\"padding-left: 30px\">79 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;9 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;4220&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8976 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;82 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 0.03 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;6052 notepad<\/p>\n<p>As my student asked, what happens when I forget to use the <i>whatif <\/i>statement? Well of course, the Notepad process goes away, and there is no prompt, no anything. There&rsquo;s not even any sign that the process no longer runs. The only way to confirm that Notepad went away is to use <b>Get-Process<\/b>. These commands and associated output are shown in the following figure.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/4401.hsg-11-21-11-1.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/4401.hsg-11-21-11-1.png\" alt=\"Image of commands and associated output\" title=\"Image of commands and associated output\" \/><\/a><\/p>\n<p>The solution is to turn on the <b>$WhatIfPreference<\/b>, which I do by setting the value to <b>$true<\/b>:<\/p>\n<p style=\"padding-left: 30px\">$WhatIfPreference = $true<\/p>\n<p>After the <b>$WhatIfPreference<\/b> is set to <b>$true<\/b>, any command that would change system state (and therefore any cmdlet that supports the <i>whatif <\/i>switched parameter) runs with <i>whatif, <\/i>and therefore does not actually execute the command, as shown here:<\/p>\n<p style=\"padding-left: 30px\">PS C:\\&gt; $WhatIfPreference = $true<\/p>\n<p style=\"padding-left: 30px\">PS C:\\&gt; notepad<\/p>\n<p style=\"padding-left: 30px\">PS C:\\&gt; get-process notepad | Stop-Process<\/p>\n<p style=\"padding-left: 30px\">What if: Performing operation &#8220;Stop-Process&#8221; on Target &#8220;notepad (7840)&#8221;.<\/p>\n<p style=\"padding-left: 30px\">PS C:\\&gt;<\/p>\n<p>This includes commands to create a new folder (because it makes a change to the system). This is shown here:<\/p>\n<p style=\"padding-left: 30px\">PS C:\\&gt; md c:\\fso4<\/p>\n<p style=\"padding-left: 30px\">What if: Performing operation &#8220;Create Directory&#8221; on Target &#8220;Destination: C:\\fso4&#8221;.<\/p>\n<p style=\"padding-left: 30px\">PS C:\\&gt; test-path c:\\fso4<\/p>\n<p style=\"padding-left: 30px\">False<\/p>\n<p>If I want to execute a command that changes system state, I need to set the value for <i>whatif <\/i>to false. When doing this, I must use <b>$False<\/b>, and not simply <b>false<\/b>:<\/p>\n<p style=\"padding-left: 30px\">PS C:\\&gt; get-process notepad | Stop-Process -whatif:false<\/p>\n<p style=\"padding-left: 30px\">InvalidArgument: (:) [Stop-Process], ParameterBindingException<\/p>\n<p style=\"padding-left: 30px\">PS C:\\&gt; get-process notepad | Stop-Process -whatif:$false<\/p>\n<p style=\"padding-left: 30px\">PS C:\\&gt; get-process notepad<\/p>\n<p style=\"padding-left: 30px\">ObjectNotFound: (notepad:String) [Get-Process], ProcessCommandException<\/p>\n<p>Keep in mind that forcing <i>whatif <\/i>to <b>$False<\/b><i> <\/i>is per command, so a subsequent call to a command that changes system state will execute the <i>whatif <\/i>behavior unless I once again override the value. This is shown here:<\/p>\n<p style=\"padding-left: 30px\">PS C:\\&gt; md c:\\fso4<\/p>\n<p style=\"padding-left: 30px\">What if: Performing operation &#8220;Create Directory&#8221; on Target &#8220;Destination: C:\\fso4&#8221;.<\/p>\n<p style=\"padding-left: 30px\">PS C:\\&gt; md c:\\fso4 -WhatIf:$false&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; Directory: C:\\&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\"><span style=\"text-decoration: underline\">Mode<\/span>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style=\"text-decoration: underline\">LastWriteTime<\/span>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style=\"text-decoration: underline\">Length Name<\/span><\/p>\n<p style=\"padding-left: 30px\">d&#8212;-&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 11\/11\/2011&nbsp;&nbsp; 6:57 PM&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fso4<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">PS C:\\&gt; test-path c:\\fso4<\/p>\n<p style=\"padding-left: 30px\">True<\/p>\n<p>The above commands and associated output are shown in the following figure.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/5722.hsg-11-21-11-2.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/5722.hsg-11-21-11-2.png\" alt=\"Image of commands and associated output\" title=\"Image of commands and associated output\" \/><\/a><\/p>\n<p>After I close Windows PowerShell and open it up again, the value of the <b>$WhatIfPreference<\/b> variable resets to <b>$False<\/b>. I no longer have the added protection of the <i>whatif <\/i>switch on by default. This appears in the following figure.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/5584.hsg-11-21-11-3.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/5584.hsg-11-21-11-3.png\" alt=\"Image of $WhatIfPreference variable resetting to $False\" title=\"Image of $WhatIfPreference variable resetting to $False\" \/><\/a><\/p>\n<p>The solution, of course, is to add the <b>$WhatIfPreference<\/b> to the Windows PowerShell profile. I have a number of Hey, Scripting Guy! Posts that talk about <a href=\"http:\/\/blogs.technet.com\/b\/heyscriptingguy\/archive\/tags\/windows+powershell\/profiles\/\">working with Windows PowerShell profiles<\/a> or adding items to profiles. I also have an <a href=\"http:\/\/blogs.technet.com\/b\/heyscriptingguy\/archive\/2009\/11\/23\/hey-scripting-guy-how-can-i-use-profiles-with-windows-powershell.aspx\">excerpt<\/a> from my <i>Windows PowerShell 2.0 Best Practices<\/i> book that covers the different Windows PowerShell profiles. You will need to decide if you want to enable the preference variable on workstations, servers, or nothing&mdash;or for just certain users. Personally, I do not have it enabled on any of my systems, but there have been a couple of times when it might have come in handy. For highly available systems, it might be a very good thing to implement.<\/p>\n<p>&nbsp;<\/p>\n<p>That is all there is to using the <b>$WhatIfPreference <\/b>variable. Join me tomorrow for more Windows PowerShell stuff.<\/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\">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>&nbsp;<\/p>\n<p><b>Ed Wilson, Microsoft Scripting Guy<\/b><\/p>\n<p><b>&nbsp;<\/b><\/p>\n<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summary: Learn how a simple change to a preference variable can help prevent accidental changes when using Windows PowerShell. &nbsp; Microsoft Scripting Guy Ed Wilson here. When I was teaching my Windows PowerShell Best Practices class out in Irvine, California, recently, I was talking to the class about the whatif parameter. I did my usual [&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":[51,144,3,4,45],"class_list":["post-12021","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-getting-started","tag-profiles","tag-scripting-guy","tag-scripting-techniques","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>Summary: Learn how a simple change to a preference variable can help prevent accidental changes when using Windows PowerShell. &nbsp; Microsoft Scripting Guy Ed Wilson here. When I was teaching my Windows PowerShell Best Practices class out in Irvine, California, recently, I was talking to the class about the whatif parameter. I did my usual [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/12021","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=12021"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/12021\/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=12021"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=12021"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=12021"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}