The PowerShell team has added some new script debugging features for version 5.0. I’ll be talking about these new features in a series of blogs starting with the new PowerShell Break All command. PowerShell 5.0 has been released as a preview over the last few months. While PowerShell is in preview new features are continually evolving so if you want to try them out you should ensure you have the latest preview version. The script debugging features I’ll be discussing require the latest preview release which at this writing is the November 2014 release. You can down load PowerShell 5.0 preview as part of the Windows Management Framework (WMF) 5.0 preview from HERE.
Simply put the new Break All command lets you break running script into the PowerShell script debugger. Why would you want to do this? Well the scenario we are covering is when you are running a complex script and based on the output data you suspect it is not working as you expect it to. Instead of stopping the script and setting breakpoints so you can start it at the beginning to debug it, you can now force the running script to immediately drop into the debugger. This works both in the PowerShell console and the PowerShell ISE (Integrated Script Environment).
In the PowerShell console you use the Ctrl+Break key combination to break into the debugger.
Try this simple experiment.
In the PowerShell console type the following:
PS C:\> 1..100 | foreach { Start-Sleep –Milliseconds 200; “Output $_” }
While the script runs type Ctrl+Break.
As you can see the script was stopped after iteration 12 and you are now in the PowerShell console line based script debugger. From here you can use the script debugger to step through the code, view variables, view environment state, execute commands at the debugger prompt, and all of the other great things you've been able to do with PowerShell script debugging since V2. Type ‘h’ or ‘?’ at the debugger prompt to see all of the available debugger commands.
When you are done debugging there are two ways to proceed. You can type the ‘continue’ debugger command at the prompt to let the script continue running. You can then type Ctrl+Break again if you want to once more break into the debugger.
Or you can type the ‘quit’ debugger command to stop the script from running and be returned to your normal console prompt.
You may have noticed that while debugging script in the PowerShell console is great in a pinch, it is not a wonderful user experience. Fortunately the Break All command also works in the PowerShell ISE which provides a much better graphic debugging experience. In the ISE you use the Ctrl+B keyboard combination to break into the debugger. Unfortunately it is a different keyboard combination than what you use in the console but this is because Ctrl+Break is already reserved in the ISE to stop script from running (since Ctrl+C can be used for copy operation). Alternatively you can use the ISE Debug -> Break All menu command.
To see how this works in the ISE just follow these simple steps.
Open a script file in the ISE (make sure the script running duration is a few seconds so that you have time to select the Break All command before it completes).
Run the script file.
While the script is running select the Debug -> Break All menu command.
As with the PowerShell console the debugger breaks at the next execution point in the script. But this time you see the script file opened in the ISE script pane and you get a much nicer GUI debugging experience.
One important thing to keep in mind is that the PowerShell script debugger works only for running scripts, that is, scripts that are executing script lines, statements, and expressions. But scripts can also call native commands. While the command is running the script engine waits for the command to complete and during this time cannot break into the debugger. So if your script is stuck waiting for a native command to complete the Break All command will not be effective. And if the command seems to be hung your only option is to use a managed/native code debugger to investigate the problem. Visual Studio or WinDbg.exe with the managed SOS extension can both be useful in this case. But if your script is actually running then the script debugger is excellent since it allows you to see all of your script variables and state that is difficult or impossible to see in a native debugger.
One last thing to note is that the Break All command also works over an interactive remote session such as you can create with the Enter-PSSession cmdlet or the ISE File -> New Remote PowerShell Tab… menu selection. Again you use the Ctrl+Break key combination for interactive remote sessions in PowerShell console, and Ctrl+B or Debug -> Break All menu command in the PowerShell ISE.
I’ll talk more about remote session debugging in the ISE in the next blog.
Paul Higinbotham [MSFT]
Windows PowerShell Development