{"id":12001,"date":"2011-11-23T00:01:00","date_gmt":"2011-11-23T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2011\/11\/23\/use-the-powershell-debugger-to-check-variable-values\/"},"modified":"2011-11-23T00:01:00","modified_gmt":"2011-11-23T00:01:00","slug":"use-the-powershell-debugger-to-check-variable-values","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/use-the-powershell-debugger-to-check-variable-values\/","title":{"rendered":"Use the PowerShell Debugger to Check Variable Values"},"content":{"rendered":"<p><b>Summary<\/b>: Learn how to inspect variable values by using the Windows PowerShell debugger.<\/p>\n<p>&nbsp;<\/p>\n<p>Microsoft Scripting Guy Ed Wilson here. In <a href=\"http:\/\/blogs.technet.com\/b\/heyscriptingguy\/archive\/2011\/11\/22\/use-the-powershell-debugger-to-troubleshoot-scripts.aspx\">yesterday&rsquo;s post<\/a>, I talked about using the <b>Set-PSBreakpoint<\/b> cmdlet to set a breakpoint on a specific script. Today, I want to continue looking at the <b>Set-PSBreakpoint<\/b> cmdlet.<\/p>\n<p>One of the things I mentioned was that when setting a breakpoint on a script, the script specified must be the same script that breaks. For example, if I set a breakpoint for the c:\\fso\\mydebug.ps1 script, the only script that breaks when a breakpoint reaches is the c:\\fso\\mydebug.ps1 script. This is the exact script, from the exact location.<\/p>\n<p>If, on the other hand, I do not specify the script when I create the breakpoint, any script I run causes the breakpoint to trigger. To test this out, I create a script with several commands in it. The script is shown here:<\/p>\n<p style=\"padding-left: 30px\"><b>Get-Process.ps1<\/b><\/p>\n<p style=\"padding-left: 30px\">Get-EventLog application -Newest 1<\/p>\n<p style=\"padding-left: 30px\">get-process powershell<\/p>\n<p style=\"padding-left: 30px\">Get-Date<\/p>\n<p>I also use the test script from yesterday. The mydebug.ps1 script is shown here:<\/p>\n<p style=\"padding-left: 30px\"><b>MyDebug.ps1<\/b><\/p>\n<p style=\"padding-left: 30px\">$cn = &#8220;localhost&#8221;<\/p>\n<p style=\"padding-left: 30px\">$process = &#8220;notepad&#8221;<\/p>\n<p style=\"padding-left: 30px\">Get-WmiObject -Class win32_bios -cn $cn<\/p>\n<p style=\"padding-left: 30px\">Start-Process $process<\/p>\n<p style=\"padding-left: 30px\">Get-Process $process<\/p>\n<p>I use the <b>Set-PSBreakpoint<\/b> cmdlet to create a breakpoint that will break when the command <b>Get-Process<\/b> appears in a script. The command and associated output are shown here:<\/p>\n<p style=\"padding-left: 30px\">PS C:\\&gt; Set-PSBreakpoint -Command get-process<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&nbsp; ID Script&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Line Command&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Variable<\/p>\n<p style=\"padding-left: 30px\">&nbsp; &#8212; &#8212;&#8212;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8212;- &#8212;&#8212;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8212;&#8212;&#8211;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp; 1&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; get-process<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">PS C:\\&gt;<\/p>\n<p>When the <b>Get-Process<\/b> command from the MyDebug.ps1 script appears, the debugger breaks into the script. This allows for the use of debugging commands (the commands appear in a table from yesterday&rsquo;s article). The <i>C <\/i>command tells the debugger to continue. In the Get-Process.ps1 script, the script also contains a call to <b>Get-Process<\/b>, so that script causes the breakpoint to break as well. These two scripts and the associated output including debugger are shown in the following figure.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/5751.hsg-11-23-11-1.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/5751.hsg-11-23-11-1.png\" alt=\"Image of two scripts and associated output including debugger\" title=\"Image of two scripts and associated output including debugger\" \/><\/a><\/p>\n<p>One of the really cool things to do with a breakpoint is to specify an action to take when a condition occurs. The action to occur is placed inside a scriptblock. In the following command, I specify that when the <b>Get-Process<\/b> command appears, the debugger will start the <b>notepad<\/b> process:<\/p>\n<p style=\"padding-left: 30px\">Set-PSBreakpoint -Command get-process -Action {notepad}<\/p>\n<p>I modify the Mydebug.ps1 script so that I comment out the <b>Start-Process<\/b> line. The revised script is shown in the following figure.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/6404.hsg-11-23-11-2.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/6404.hsg-11-23-11-2.png\" alt=\"Image of modified Mydebug.ps1 script\" title=\"Image of modified Mydebug.ps1 script\" \/><\/a><\/p>\n<p>When run, the script generates an error because it attempts to use <b>Get-Process<\/b> to retrieve a nonexistent process. In the breakpoint previously specified, however, when the breakpoint is reached, the scriptblock creates the <b>notepad<\/b> process, so the script works without causing an exception. This is shown in the following figure.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/0268.hsg-11-23-11-3.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/0268.hsg-11-23-11-3.png\" alt=\"Image of script working without causing an exception\" title=\"Image of script working without causing an exception\" \/><\/a><\/p>\n<p>When debugging a script, often I am concerned about the value of a variable. There are three ways to break on a variable. The three ways are <b>read<\/b>, <b>write<\/b>, and <b>readwrite<\/b>. The default value is <b>write<\/b>. When working with breakpoints on variables, <b>read<\/b><i> <\/i>or <b>write<\/b><i> <\/i>do not talk about the way the variable is declared in the script, but each determines when the script breaks. For example, when breaking on a variable in <b>write<\/b><i> <\/i>mode, it means the script breaks before a new value is written to a variable. In the case of a variable that is not yet declared, the script breaks just before a value is written or assigned to the variable. I used the code that follows to set a breakpoint on the variable <b>cn<\/b><i> <\/i>when a value is written to the variable:<\/p>\n<p style=\"padding-left: 30px\">Set-PSBreakpoint -Variable cn -Mode write<\/p>\n<p>I run the script, and the script breaks before the value &ldquo;localhost&rdquo; is assigned to the <b>$cn<\/b> variable. I then check the value of the <b>$cn<\/b> variable; nothing is displayed because the variable has not been created. Next, I use the <i>L<\/i> command to see the code, and I see the script is on the first line, waiting to assign a value to the <b>$cn<\/b> variable. I then use the <i>C <\/i>command, and continue execution of the script. The error is generated because I have commented out the <b>Start-Process<\/b> command (this can be seen in the code listing from the previous command).<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/8750.hsg-11-23-11-4.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/8750.hsg-11-23-11-4.png\" alt=\"Image of generated error\" title=\"Image of generated error\" \/><\/a><\/p>\n<p>In the following figure, I run the C:\\fso\\debug.ps1 script. The script hits the <b>$cn<\/b> variable breakpoint and breaks into the script. I check the value of the <b>$cn<\/b> variable and see it has not been set; thereforem nothing returns. I then assign the value <b><span style=\"text-decoration: underline\">mred<\/span><\/b><i> <\/i>to the <b>$cn<\/b> variable, and I use the <i>L <\/i>command to view the code. Next, I use the <i>S <\/i>command to step to the next line in the script. I see that it sets the value <b>notepad<\/b><i> <\/i>for the <b>$process<\/b> variable. I then step (<i>S<\/i>) to the next line in the script where I see that it will make a WMI call to retrieve BIOS information via the <b>Win32_BIOS<\/b> WMI class. I then step past that (<i>S<\/i>) and see that the script is getting ready to retrieve process information about the <b>notepad<\/b><i> <\/i>process. However, Notepad is not running because the <b>Start-Process<\/b> command is commented out. I therefore type <b>Start-Process $Process<\/b><i> <\/i>and then step into the remainder of the script.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/2337.hsg-11-23-11-5.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/2337.hsg-11-23-11-5.png\" alt=\"Image of running the C:\\fso\\debug.ps1 script\" title=\"Image of running the C:\\fso\\debug.ps1 script\" \/><\/a><\/p>\n<p>When I break on a variable in <b>read<\/b><i> <\/i>mode, the value of the variable has already been read. This means I can inspect the value of the variable to ensure the script works as intended. In the code that follows, I remove all the current breakpoints, and then I create a new breakpoint that watches the variable <b>$cn<\/b> to see when it reads the value of the variable. When the value of the <b>$cn<\/b> variable is read, the script breaks and enters the debugger:<\/p>\n<p style=\"padding-left: 30px\">Get-PSBreakpoint | Remove-PSBreakpoint<\/p>\n<p style=\"padding-left: 30px\">Set-PSBreakpoint -Variable cn -Mode read<\/p>\n<p>When I query the value of the <b>$cn<\/b> variable inside the debugger, I see that the variable contains the value &ldquo;localhost.&rdquo; That is what I want, so I step over the remainder of the code, thereby executing the remainder of the script. These commands and associated output appear in the following figure.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/7801.hsg-11-23-11-6.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/7801.hsg-11-23-11-6.png\" alt=\"Image of commands and associated output\" title=\"Image of commands and associated output\" \/><\/a><\/p>\n<p>That&rsquo;s it for now. Join me tomorrow for more fun with Windows PowerShell.<\/p>\n<p>&nbsp;<\/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>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summary: Learn how to inspect variable values by using the Windows PowerShell debugger. &nbsp; Microsoft Scripting Guy Ed Wilson here. In yesterday&rsquo;s post, I talked about using the Set-PSBreakpoint cmdlet to set a breakpoint on a specific script. Today, I want to continue looking at the Set-PSBreakpoint cmdlet. One of the things I mentioned was [&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":[295,3,4,45],"class_list":["post-12001","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-debug","tag-scripting-guy","tag-scripting-techniques","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>Summary: Learn how to inspect variable values by using the Windows PowerShell debugger. &nbsp; Microsoft Scripting Guy Ed Wilson here. In yesterday&rsquo;s post, I talked about using the Set-PSBreakpoint cmdlet to set a breakpoint on a specific script. Today, I want to continue looking at the Set-PSBreakpoint cmdlet. One of the things I mentioned was [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/12001","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=12001"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/12001\/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=12001"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=12001"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=12001"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}