Debugging PowerShell Script Using the ISE Editor

Hi writers and consumers of buggy scripts.

This post explains the basics of the Graphical Debugger in the ISE. There’s a lot of good stuff, with some tips and tricks.

The debugger support got the cmdlets and user interface.  The cmdlets include  Enable/Disable/Get/Set/Remove-PsBreakpoint and Get-PsCallStack.

The general feel is to place breakpoints across the script, continue (F5) to jump from breakpoint to breakpoint, and step over, step into, and step out to move around. You can also get the call stack, and hover over variables to get their values.


Line breakpoints are easy to add, with F9 or context menu (Enable Breakpoint) on any script. However they can only be added to saved scripts. So if you have untitled.ps1, please save it to “powershellmademesaveyou.ps1” first. psm1 files also work. Lots of types of lines can have breakpoints, I’ve seen them work in for each loops, in script blocks, in if and else blocks, in traps, and so on.

Special breakpoints can be added using Set-PSBreakpoint (alias “sbp”). For example, “sbp -command write-error” will take you to the command whenever it executes, and “sbp -variable servername” will stop when $servername is set (or accessed). Theses breakpoints are not displayed on screen, and need to be enabled/removed using the cmdline.

Go to Debug->List Breakpoints to see a list of them.

They can also easily be removed through the context menu, or F9 (or the debug menu, or remove-psbreakpoint cmdlet…)

Breakpoints can also be added when the debugger breaks, but you can’t add a breakpoint while the script is busy running.

Navigation and Exploration

Navigating and exploring is smooth in the ISE. To jump from breakpoint to breakpoint, use Continue (F5). To step over, press F10, step into, F11, and step out, Shift-F11. It’s easy to add more breakpoints while navigating, so you can use that to jump around.

The ISE will automatically open the script that the function you called came from.

Once you’re at an interesting spot, you can:

–          Hover over a variable to see its value. This is a very quick way to see what’s going on

–          Execute a selection using F6. You can execute the if-block condition to see the results. You can execute part of a line in your script, instead of the whole thing.

–          Execute a command in the command pane. You can try out complicated expressions with everything set up. You can also modify variable values here.

–          Get the call stack (Ctrl-Shift-D) to see how deep in trouble you are

–          Get Help on a cmdlet, by selecting it with your mouse and pressing F1

It might also be a good time to stop debugging (Shift-F5) and restart. Scripts are locked during debugging, so you need to stop debugging to continue editing your scripts.

Fun ISE Extensions for debugging

–          Get Last exception

o   $psISE.CustomMenu.Submenus.Add(‘Show Exception’, {$error[$Error.Count – 1].Exception | fl -f *}, “Ctrl+Shift+E”)

–          Dump selection info

o   $psISE.CustomMenu.Submenus.Add(‘Get-Member’, {iex $psISE.CurrentOpenedFile.Editor.SelectedText | gm | ft; iex $psISE.CurrentOpenedFile.Editor.SelectedText | fl -f *; }, “Ctrl+D”)

–          Go to definition

o   function GotoDefinition($commandName)
    $command = gcm -CommandType Function $commandName
    $file = $command.ScriptBlock.File
    $position = $command.ScriptBlock.StartPosition
    $runspace = $psISE.CurrentOpenedRunspace
    ($runspace.OpenedFiles | ?{$_.FullPath -eq $file}).Editor.SetCaretPosition($position.StartLine, $position.StartColumn)
$psISE.CustomMenu.Submenus.Add(“GotoDefinition”, {GotoDefinition $psISE.CurrentOpenedFile.Editor.SelectedText}, “Ctrl+Shift+G”)

GotoDefinition won’t work until the functions are defined, but you can customize it to do more.


Debugger Pics


Hope this Helps,

Ibrahim Abdul Rahim [MSFT]