{"id":11991,"date":"2011-11-24T00:01:00","date_gmt":"2011-11-24T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2011\/11\/24\/use-the-debugger-in-the-windows-powershell-ise\/"},"modified":"2011-11-24T00:01:00","modified_gmt":"2011-11-24T00:01:00","slug":"use-the-debugger-in-the-windows-powershell-ise","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/use-the-debugger-in-the-windows-powershell-ise\/","title":{"rendered":"Use the Debugger in the Windows PowerShell ISE"},"content":{"rendered":"<p><span style=\"font-family: Segoe;font-size: small\"><b>Summary<\/b>: Learn how to use the debugging tools in the Windows PowerShell ISE to speed development of scripts.<\/span><\/p>\n<p><span class=\"Apple-style-span\" style=\"font-family: Segoe;font-size: small\">Microsoft Scripting Guy, Ed Wilson, is here. Today I want to talk a little bit about using the Windows PowerShell ISE to debug a script. This is actually the third article this week in which I talk about using Windows PowerShell to debug scripts. In the first article, I talked about <\/span><a href=\"http:\/\/blogs.technet.com\/b\/heyscriptingguy\/archive\/2011\/11\/20\/change-a-powershell-preference-variable-to-reveal-hidden-data.aspx\" target=\"_blank\" style=\"font-family: Segoe;font-size: small\">working at the Windows PowerShell console<\/a><span class=\"Apple-style-span\" style=\"font-family: Segoe;font-size: small\"> and using the Windows PowerShell debugger to help with debugging scripts. I discussed setting breakpoints on scripts by using the <\/span><b style=\"font-family: Segoe;font-size: small\">Set-PSBreakPoint<\/b><span class=\"Apple-style-span\" style=\"font-family: Segoe;font-size: small\"> cmdlet. Next, I talked about <\/span><a href=\"http:\/\/blogs.technet.com\/b\/heyscriptingguy\/archive\/2011\/11\/21\/make-a-simple-change-to-powershell-to-prevent-accidents.aspx\" target=\"_blank\" style=\"font-family: Segoe;font-size: small\">setting breakpoints on variables<\/a><span class=\"Apple-style-span\" style=\"font-family: Segoe;font-size: small\">&nbsp;and examining the variables from inside the debugger. I also talked about specifying an action to take when a breakpoint is reached.<\/span><\/p>\n<p><span style=\"font-family: Segoe;font-size: small\">One thing to keep in mind when you are working with the debugger in the Windows PowerShell ISE, is that it is still the same Windows PowerShell debugger. For example, if I am working on a Windows PowerShell script, but I have not yet saved the script with a file name, I cannot set a breakpoint; this option is not available.<\/span><\/p>\n<p><span style=\"font-family: Segoe;font-size: small\">Once I have saved the script with a file name, I can select a line, and use the <b>Toggle Breakpoint<\/b> action from the <b>Debug<\/b> menu to set a breakpoint on the specific line. Once set, the line changes color. When I run the script and the breakpoint is hit, the script enters debugger mode. I can use the immediate window (the execution pane that is normally the bottom pane) to type commands for the debugger. The output pane (normally the middle pane) shows that the script is in debugger mode, and it displays the current output. I can use the normal debugger commands to step into, step over, list the call stack, or other actions that are detailed in the following table.<\/span><\/p>\n<p><span style=\"font-size: small\"><span style=\"font-family: Segoe\">(Note: This table is copied from my Microsoft Press book, <\/span><span style=\"font-family: segoe\"><a href=\"http:\/\/www.amazon.com\/Windows-PowerShell-2-0-Best-Practices\/dp\/0735626464\/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1255959455&amp;sr=8-1\" target=\"_blank\"><span>Windows PowerShell 2.0 Best Practices<\/span><\/a><\/span><span style=\"font-family: Segoe\">.)<\/span><\/span><\/p>\n<p><span style=\"font-size: small\"><span style=\"font-family: Segoe\"><\/span><\/span>&nbsp;<\/p>\n<table border=\"1\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td valign=\"top\" width=\"115\">\n<p class=\"TableHead\"><span style=\"font-family: Segoe Semibold;font-size: small\">Keyboard shortcut<\/span><\/p>\n<\/td>\n<td valign=\"top\" width=\"108\">\n<p class=\"TableHead\"><span style=\"font-family: Segoe Semibold;font-size: small\">Command name<\/span><\/p>\n<\/td>\n<td valign=\"top\" width=\"343\">\n<p class=\"TableHead\"><span style=\"font-family: Segoe Semibold;font-size: small\">Command meaning<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"115\">\n<p class=\"TableText\"><span style=\"font-size: small\"><span style=\"font-family: Segoe\">s<\/span><\/span><\/p>\n<\/td>\n<td valign=\"top\" width=\"108\">\n<p class=\"TableText\"><span style=\"font-size: small\"><span style=\"font-family: Segoe\">Step-into<\/span><\/span><\/p>\n<\/td>\n<td valign=\"top\" width=\"343\">\n<p class=\"TableText\"><span style=\"font-size: small\"><span style=\"font-family: Segoe\">Executes the next statement and then stops.<\/span><\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"115\">\n<p class=\"TableText\"><span style=\"font-size: small\"><span style=\"font-family: Segoe\">v<\/span><\/span><\/p>\n<\/td>\n<td valign=\"top\" width=\"108\">\n<p class=\"TableText\"><span style=\"font-size: small\"><span style=\"font-family: Segoe\">Step-over<\/span><\/span><\/p>\n<\/td>\n<td valign=\"top\" width=\"343\">\n<p class=\"TableText\"><span style=\"font-size: small\"><span style=\"font-family: Segoe\">Executes the next statement, but skips functions and invocations. The skipped statements are executed, but not stepped through.<\/span><\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"115\">\n<p class=\"TableText\"><span style=\"font-size: small\"><span style=\"font-family: Segoe\">o<\/span><\/span><\/p>\n<\/td>\n<td valign=\"top\" width=\"108\">\n<p class=\"TableText\"><span style=\"font-size: small\"><span style=\"font-family: Segoe\">Step-out<\/span><\/span><\/p>\n<\/td>\n<td valign=\"top\" width=\"343\">\n<p class=\"TableText\"><span style=\"font-size: small\"><span style=\"font-family: Segoe\">Steps out of the current function up one level if nested. If in the main body, it continues to the end or the next breakpoint. The skipped statements are executed, but not stepped through.<\/span><\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"115\">\n<p class=\"TableText\"><span style=\"font-size: small\"><span style=\"font-family: Segoe\">c<\/span><\/span><\/p>\n<\/td>\n<td valign=\"top\" width=\"108\">\n<p class=\"TableText\"><span style=\"font-size: small\"><span style=\"font-family: Segoe\">Continue<\/span><\/span><\/p>\n<\/td>\n<td valign=\"top\" width=\"343\">\n<p class=\"TableText\"><span style=\"font-size: small\"><span style=\"font-family: Segoe\">Continues to run until the script is complete or until the next breakpoint is reached. The skipped statements are executed, but not stepped through.<\/span><\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"115\">\n<p class=\"TableText\"><span style=\"font-size: small\"><span style=\"font-family: Segoe\">l<\/span><\/span><\/p>\n<\/td>\n<td valign=\"top\" width=\"108\">\n<p class=\"TableText\"><span style=\"font-size: small\"><span style=\"font-family: Segoe\">List<\/span><\/span><\/p>\n<\/td>\n<td valign=\"top\" width=\"343\">\n<p class=\"TableText\"><span style=\"font-size: small\"><span style=\"font-family: Segoe\">Displays the part of the script that is executing. By default, it displays the current line, five previous lines, and 10 subsequent lines. To continue listing the script, press ENTER.<\/span><\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"115\">\n<p class=\"TableText\"><span style=\"font-size: small\"><span style=\"font-family: Segoe\">l &lt;m&gt;<\/span><\/span><\/p>\n<\/td>\n<td valign=\"top\" width=\"108\">\n<p class=\"TableText\"><span style=\"font-size: small\"><span style=\"font-family: Segoe\">List<\/span><\/span><\/p>\n<\/td>\n<td valign=\"top\" width=\"343\">\n<p class=\"TableText\"><span style=\"font-size: small\"><span style=\"font-family: Segoe\">Displays 16 lines of the script beginning with the line number specified by &lt;m&gt;.<\/span><\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"115\">\n<p class=\"TableText\"><span style=\"font-size: small\"><span style=\"font-family: Segoe\">l &lt;m&gt; &lt;n&gt;<\/span><\/span><\/p>\n<\/td>\n<td valign=\"top\" width=\"108\">\n<p class=\"TableText\"><span style=\"font-size: small\"><span style=\"font-family: Segoe\">List<\/span><\/span><\/p>\n<\/td>\n<td valign=\"top\" width=\"343\">\n<p class=\"TableText\"><span style=\"font-size: small\"><span style=\"font-family: Segoe\">Displays &lt;n&gt; lines of the script, beginning with the line number specified by &lt;m&gt;.<\/span><\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"115\">\n<p class=\"TableText\"><span style=\"font-size: small\"><span style=\"font-family: Segoe\">q<\/span><\/span><\/p>\n<\/td>\n<td valign=\"top\" width=\"108\">\n<p class=\"TableText\"><span style=\"font-size: small\"><span style=\"font-family: Segoe\">Stop<\/span><\/span><\/p>\n<\/td>\n<td valign=\"top\" width=\"343\">\n<p class=\"TableText\"><span style=\"font-size: small\"><span style=\"font-family: Segoe\">Stops executing the script, and exits the debugger.<\/span><\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"115\">\n<p class=\"TableText\"><span style=\"font-size: small\"><span style=\"font-family: Segoe\">k<\/span><\/span><\/p>\n<\/td>\n<td valign=\"top\" width=\"108\">\n<p class=\"TableText\"><span style=\"font-size: small\"><span style=\"font-family: Segoe\">Get-PsCallStack<\/span><\/span><\/p>\n<\/td>\n<td valign=\"top\" width=\"343\">\n<p class=\"TableText\"><span style=\"font-size: small\"><span style=\"font-family: Segoe\">Displays the current call stack.<\/span><\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"115\">\n<p class=\"TableText\"><span style=\"font-size: small\"><span style=\"font-family: Segoe\">&lt;Enter&gt;<\/span><\/span><\/p>\n<\/td>\n<td valign=\"top\" width=\"108\">\n<p class=\"TableText\"><span style=\"font-size: small\"><span style=\"font-family: Segoe\">Repeat<\/span><\/span><\/p>\n<\/td>\n<td valign=\"top\" width=\"343\">\n<p class=\"TableText\"><span style=\"font-size: small\"><span style=\"font-family: Segoe\">Repeats the last command if it was Step (s), Step-over (v), or List (l). Otherwise, represents a submit action.<\/span><\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"115\">\n<p class=\"TableText\"><span style=\"font-size: small\"><span style=\"font-family: Segoe\">h or ?<\/span><\/span><\/p>\n<\/td>\n<td valign=\"top\" width=\"108\">\n<p class=\"TableText\"><span style=\"font-size: small\"><span style=\"font-family: Segoe\">Help<\/span><\/span><\/p>\n<\/td>\n<td valign=\"top\" width=\"343\">\n<p class=\"TableText\"><span style=\"font-size: small\"><span style=\"font-family: Segoe\">Displays the debugger command Help.<\/span><\/span><\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><span style=\"font-family: Segoe;font-size: small\">One thing that is a bit annoying when debugging a script with the Windows PowerShell ISE is that debugging commands that are typed while in debug mode do not appear in the ISE output pane like they do when using the Windows PowerShell debugger in the Windows PowerShell console. If I query a variable, or set a value for a variable, those commands appear in the output pane, but commands from the previous table do not appear. <\/span><\/p>\n<p><span style=\"font-family: Segoe;font-size: small\">In the following image, I set a breakpoint for the second line of the script by using the Toggle Breakpoint command from the <b>Debug<\/b> menu. I then ran the script. It hit the breakpoint on the second line and entered debug mode. This is indicated in the output pane as [DBG]. Next, I used the <i>l (L)<\/i> command to list the lines from the script. The output from this command is visible, but there is no indication of the command that was typed. I then queried the value of the <b>$a<\/b> variable a second time, and both the command and output appeared. Finally, I used the <i>o (O)<\/i> command to step over the last line of code, and the script exited. <\/span><\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/5037.hsg-11-24-11-1.png\"><img decoding=\"async\" alt=\"Image of script\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/5037.hsg-11-24-11-1.png\" title=\"Image of script\" \/><\/a><\/p>\n<p><span style=\"font-family: Segoe;font-size: small\">To remove all the breakpoints in a script, I can choose the <b>Remove All Breakpoints<\/b> command from the <b>Debug<\/b> menu. I can also use the <b>Get-PSBreakpoint<\/b> cmdlet to get all the breakpoints, and then use <b>Remove-PSBreakpoint<\/b> to remove the breakpoints, as shown here:<\/span><\/p>\n<p style=\"padding-left: 30px\"><span style=\"font-family: Segoe;font-size: small\">Get-PSBreakpoint | Remove-PSBreakpoint<\/span><\/p>\n<p><span style=\"font-family: Segoe;font-size: small\">These commands are shown in the following image.<\/span><\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/7455.hsg-11-24-11-2.png\"><img decoding=\"async\" alt=\"Image of script\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/7455.hsg-11-24-11-2.png\" title=\"Image of script\" \/><\/a><\/p>\n<p><span style=\"font-family: Segoe;font-size: small\">So, how is all this helpful? For one thing, I can use this to see what Windows PowerShell thinks is going to happen before it actually happens. I can also see what actually took place, just after it happened. In the following image, I am still using the single breakpoint. When the script breaks on line 2, it has not yet executed line 2. First, I check the value that is stored in <b>$a<\/b>. That value is 55, which according to the script, is correct. Next, I look to see what is stored in variable <b>$b<\/b>, and it reports back as 29. This should actually be null because the second line has not yet executed. <\/span><\/p>\n<p><span style=\"font-family: Segoe;font-size: small\">I figure out that the value comes from the previous time I ran the script. I then change the value of <b>$b<\/b> to 45. I query the <b>$b<\/b> variable, and sure enough, it is 45. I then type the <i>s (S) <\/i>command in the debugger, to step into the line and to actually execute the second line of code. I query the value of <b>$b<\/b>, and I see that it is now set back to 29. This proves that the debugger breaks before executing the line of code. I then set it back to 45, and query value of the variable, and I see that it is now set to 45. When the script finishes running, I check the value of <b>$c<\/b>, and see that it is 100 (however, this output is off screen in the following image).<\/span><\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/4617.hsg-11-24-11-3.png\"><img decoding=\"async\" alt=\"Image of script\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/4617.hsg-11-24-11-3.png\" title=\"Image of script\" \/><\/a><\/p>\n<p><span style=\"font-family: Segoe;font-size: small\">From the <b>Debug<\/b> menu, I can only toggle a breakpoint on a line in the script. If I want to do something more sophisticated (such taking an action when a variable value is written to), I need to use the <b>Set-PSBreakPoint<\/b> cmdlet like I used in <a href=\"http:\/\/blogs.technet.com\/b\/heyscriptingguy\/archive\/2011\/11\/21\/make-a-simple-change-to-powershell-to-prevent-accidents.aspx\" target=\"_blank\">yesterday&rsquo;s Hey! Scripting Guy Blog<\/a>.<\/span><\/p>\n<p><span style=\"font-family: Segoe;font-size: small\">In the following image, I use the <b>Set-PSBreakpoint<\/b> cmdlet to write out the value of the variable <b>$c<\/b> to the console in blue, when the value of the <b>$c<\/b> variable is written to. Here is the <b>Set-PSBreakPoint<\/b> cmdlet command I use:<\/span><\/p>\n<p style=\"padding-left: 30px\"><span style=\"font-family: Segoe;font-size: small\">Set-PSBreakpoint -Variable c -Mode write -Action {write-host $c -f blue}<\/span><\/p>\n<p><span style=\"font-family: Segoe;font-size: small\">After I set the breakpoint, I run the script. When the breakpoint is reached, the <i>action<\/i> portion of the command executes, and the value contained in the <b>$c<\/b> variable is written to the output pane in blue. I then use the <b>List Breakpoints<\/b> command from the <b>Debug<\/b> menu (this is the same as typing the <b>Get-PSBreakPoint<\/b> command) to display all breakpoints. As seen in the following image, only one breakpoint is currently in effect. <\/span><\/p>\n<p><span style=\"font-family: Segoe;font-size: small\"><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/2642.hsg-11-24-11-4.png\"><img decoding=\"async\" alt=\"Image of script\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/2642.hsg-11-24-11-4.png\" title=\"Image of script\" \/><\/a><\/span><\/p>\n<p><span style=\"font-family: Segoe;font-size: small\">As you can see, working with the debugger in the Windows PowerShell ISE is the same as working at the Windows PowerShell prompt. There is the <b>Debug<\/b><i> <\/i>menu, but it ties back to the Windows PowerShell debugger itself. That is it for now.<\/span><\/p>\n<p><span style=\"font-family: Segoe;font-size: small\">Join me tomorrow when I will talk about more cool things to do with Windows PowerShell. <\/span><\/p>\n<p><span style=\"font-size: small\"><span style=\"font-family: Segoe\">I invite you to follow me on <\/span><a href=\"http:\/\/bit.ly\/scriptingguystwitter\" target=\"_blank\"><span>Twitter<\/span><\/a><span style=\"font-family: Segoe\"> and <\/span><a href=\"http:\/\/bit.ly\/scriptingguysfacebook\">Facebook<\/a><span style=\"font-family: Segoe\">. If you have any questions, send email to me at <\/span><a href=\"mailto:scripter@microsoft.com\" target=\"_blank\"><span>scripter@microsoft.com<\/span><\/a><span style=\"font-family: Segoe\">, or post your questions on the <\/span><span style=\"font-family: Segoe\"><a href=\"http:\/\/bit.ly\/scriptingforum\" target=\"_blank\">Official Scripting Guys Forum<\/a><\/span><span style=\"font-family: Segoe\">. See you tomorrow. Until then, peace.<\/span><\/span><\/p>\n<\/p>\n<p><span style=\"font-size: small\"><b>Ed Wilson, Microsoft Scripting Guy<\/b><\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summary: Learn how to use the debugging tools in the Windows PowerShell ISE to speed development of scripts. Microsoft Scripting Guy, Ed Wilson, is here. Today I want to talk a little bit about using the Windows PowerShell ISE to debug a script. This is actually the third article this week in which I talk [&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":[294,3,4,45],"class_list":["post-11991","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-debugging","tag-scripting-guy","tag-scripting-techniques","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>Summary: Learn how to use the debugging tools in the Windows PowerShell ISE to speed development of scripts. Microsoft Scripting Guy, Ed Wilson, is here. Today I want to talk a little bit about using the Windows PowerShell ISE to debug a script. This is actually the third article this week in which I talk [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/11991","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=11991"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/11991\/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=11991"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=11991"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=11991"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}