PowerShell 5.0: Debugging Background Jobs

By now, you’ve probably already heard about the Microsoft Windows PowerShell 5.0 September 2014 Preview. If you haven’t already, you really need to download it and get familiar with all of the new features that are coming out with it. PowerShell 5.0 is also included in the Windows 10 Technical Preview, so you can build a Microsoft Azure virtual machine in the public cloud to play around with it.

If you follow my YouTube channel (pcgeek86), you might have noticed that I published a new video last night around one of the new features in PowerShell 5.0, namely the ability to debug PowerShell Background Jobs. This video is brief, at only two minutes long, but it demonstrates the very powerful capability of debugging PowerShell background jobs that are running locally. In addition to debugging local background jobs, you can also debug background jobs that are running on a remote computer (yes, really!), or inside of the PowerShell Workflow engine (PSWorkflow jobs).

# Debug-Job Command The Debug-Job command is new to PowerShell 5.0, and allows you to break into the debugger for a PowerShell Background Job. You can specify the Background Job object itself, or its ID, Name, or Instance ID (an automatically-assigned, globally unique ID) properties as input to the Debug-Job command. You can use the Get-Job command to view a list of PowerShell Background Jobs that are available in the current PowerShell session. Once you’re inside the debugging context, you can use the normal debugging commands such as Step Over or Step Into. If you’re inside the debugging context of a PowerShell Background Job, and you call exit, the Background Job will automatically resume execution from the current line. Let’s take a look at how to use the Debug-Job command to pause execution of a Background Job and invoke the debugging context.

If you execute the above script in the PowerShell ISE by hitting the F5 key, you’ll probably get an error from Debug-Job stating the following:

Debug-Job : The provided job and all child jobs were examined but no jobs were found that could be debugged. In order to debug a job or child job the job must support debugging and also be in a running state.

This exception message appears because the PowerShell Background Job must be in the Running state in order to be debugged. However, because Debug-Job is called before the Background Job has enough time to become fully initialized, the exception appears. Instead, start by running all of the code up to, but not including, the call to Debug-Job. Within a couple of seconds, execute the Debug-Job command, and you will enter the debugging context. If you wait too long, then the PowerShell ScriptBlock will return, causing the Background Job to change into the Completed state. If that occurs, then you will not be able to use Debug-Job to enter the debugging context for the Background Job.

Wait-Debugger Command

The Wait-Debugger command is also new to PowerShell 5.0. This new command will cause a PowerShell Background Job to change into the AtBreakpoint state. Previous versions of PowerShell do not support the AtBreakpoint state for Background Jobs, because they did not support debugging. It’s important to note that the Wait-Debugger command is not supported in PowerShell Workflow.

Using the same example as above, we can replace the Start-Sleep command with Wait-Debugger, which will more reliably await for the debugger to be attached.

NOTE: You will want to run the above script in sections, otherwise the Background Job status may not display correctly. Run everything including the Start-Job command, and then stop. Manually run the $Job.State command to examine the job state, and then the Debug-Job command to enter the debugging context.

Conclusion

During the course of this article, we have examine the new ability in Microsoft Windows PowerShell 5.0 to debug PowerShell Background Jobs. Thanks for reading and watching the related YouTube video. Please come back for more PowerShell content!