Ironman Software Forums
Continue the conversion on the Ironman Software forums. Chat with over 1000 users about PowerShell, PowerShell Universal, and PowerShell Pro Tools.
Learn how to use the built in debugging commands to step through scripts in the PowerShell terminal.
Although VS Code, PSScriptPad and Visual Studio provide ways of debugging PowerShell scripts, you can also debug scripts without leaving your terminal. Use the built in debugging commands to pause on breakpoints, step and evaluate state in scripts.
For the purposes of this blog post, we’ll use the following script that we’ll save as process.ps1
.
function New-Process {
param($NewProcess)
Write-Debug "Starting process $NewProcess"
Start-Process $NewProcess
}
$NewProcess = "Notepad"
New-Process $NewProcess
$Variable = (Get-Process).Length
Write-Host $Variable
In order to pause the debugger, you will need to either use the $DebugPreference
variable, the Set-PSBreakpoint
cmdlet or the Wait-Debugger
cmdlet.
The $DebugPreference
variable defines what happens when Write-Debug
is called. One of the options is to set the $DebugPreference
to Break
. This will cause the debugger to break whenever it hits a Write-Debug
call.
For example, when update the variable and then call our script the debugger will break at the Write-Debug
call.
$DebugPreference = 'Break'
.\process.ps1
PS C:\Users\adamr> C:\Users\adamr\Desktop\process.ps1
Entering debug mode. Use h or ? for help.
At C:\Users\adamr\Desktop\process.ps1:4 char:2
+ Write-Debug "Starting process $NewProcess"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Set-PSBreakpoint
can be used to set a breakpoint within a PowerShell script. To use this cmdlet for a file, you’ll need the path and line number. Line numbers start at 1.
Set-PSBreakpoint -Script .\process.ps1 -Line 8
ID Script Line Command Variable Action
-- ------ ---- ------- -------- ------
1 process.ps1 8
.\process.ps1
Hit Line breakpoint on 'C:\Users\adamr\Desktop\process.ps1:8'
At C:\Users\adamr\Desktop\process.ps1:8 char:1
+ $NewProcess = "Notepad"
+ ~~~~~~~~~~~~~~~~~~~~~~~
The Wait-Debugger
cmdlet can be used to cause the debugger to break where the cmdlet is called. We’ll update our script as follows.
Wait-Debugger
function New-Process {
param($NewProcess)
Write-Debug "Starting process $NewProcess"
Start-Process $NewProcess
}
$NewProcess = "Notepad"
New-Process $NewProcess
$Variable = (Get-Process).Length
Write-Host $Variable
Running the script will cause the debugger to break on line 1.
.\powershell.ps1
At C:\Users\adamr\Desktop\powershell.ps1:1 char:1
+ Wait-Debugger
+ ~~~~~~~~~~~~~
Once you have stopped in a script, you can use the debugging commands to move through the execution of scripts. Let’s assume we have the Wait-Debugger
on the first line of the script.
When the debugger breaks, you can enter the following commands:
s, stepInto Single step (step into functions, scripts, etc.)
v, stepOver Step to next statement (step over functions, scripts, etc.)
o, stepOut Step out of the current function, script, etc.
c, continue Continue operation
q, quit Stop operation and exit the debugger
d, detach Continue operation and detach the debugger.
k, Get-PSCallStack Display call stack
l, list List source code for the current script.
Use "list" to start from the current line, "list <m>"
to start from line <m>, and "list <m> <n>" to list <n>
lines starting from line <m>
<enter> Repeat last command if it was stepInto, stepOver or list
?, h displays this help message.
For instructions about how to customize your debugger prompt, type "help about_prompt".
Command v
Step over will move to the next line. If the current line contains a function call, it won’t step into the execution of that function. It’ll just execute it. For example, if the current execution is on the New-Process
command, it will execute the function but not step into it.
[DBG]: PS C:\Users\adamr>> v
At C:\Users\adamr\Desktop\process.ps1:10 char:1
+ New-Process $NewProcess
+ ~~~~~~~~~~~~~~~~~~~~~~~
[DBG]: PS C:\Users\adamr>> v
At C:\Users\adamr\Desktop\process.ps1:12 char:1
+ $Variable = (Get-Process).Length
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Command: s
Step into will move to the next line. If the current line contains a function call, the next line will be within that function. For example, if we are on the New-Process
call, we will move into the function rather than over it.
[DBG]: PS C:\Users\adamr>> v
At C:\Users\adamr\Desktop\process.ps1:10 char:1
+ New-Process $NewProcess
+ ~~~~~~~~~~~~~~~~~~~~~~~
[DBG]: PS C:\Users\adamr>> s
At C:\Users\adamr\Desktop\process.ps1:2 char:22
+ function New-Process {
+ ~
Command: o
Once within a function, you can step out of a function by use the step out command. This will execute the rest of the function and move to the next line in the stack frame above the current.
[DBG]: PS C:\Users\adamr>> s
At C:\Users\adamr\Desktop\process.ps1:2 char:22
+ function New-Process {
+ ~
[DBG]: PS C:\Users\adamr>> o
At C:\Users\adamr\Desktop\process.ps1:12 char:1
+ $Variable = (Get-Process).Length
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Command: c
When you issue the continue command, it will cause the script to run into the end or until it hits another breakpoint.
[DBG]: PS C:\Users\adamr>> o
At C:\Users\adamr\Desktop\process.ps1:12 char:1
+ $Variable = (Get-Process).Length
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[DBG]: PS C:\Users\adamr>> c
328
Command: k
Issuing the Get-PSCallstack
command allows you see where in the source stack you are running. For each function call, you will move down in the call stack. Using Get-PSCallstack
allows you to find your way back to where the current lined was called from.
In this example, we are within the New-Process
function.
[DBG]: PS C:\Users\adamr>> s
At C:\Users\adamr\Desktop\process.ps1:2 char:22
+ function New-Process {
+ ~
[DBG]: PS C:\Users\adamr>> k
Command Arguments Location
------- --------- --------
New-Process {NewProcess=Notepad} process.ps1: line 2
process.ps1 {} process.ps1: line 10
<ScriptBlock> {} <No file>
Additionally, while you are broken in a script, you can execute any PowerShell command as well as evaluate variables.
[DBG]: PS C:\Users\adamr>> s
At C:\Users\adamr\Desktop\process.ps1:2 char:22
+ function New-Process {
+ ~
[DBG]: PS C:\Users\adamr>> $NewProcess
Find this useful? Please consider sharing this article. Have a question about PowerShell? Contact us and we'll write a post about it.
Continue the conversion on the Ironman Software forums. Chat with over 1000 users about PowerShell, PowerShell Universal, and PowerShell Pro Tools.
Receive once-a-month updates about Ironman Software. You'll learn about our product updates and blogs related to PowerShell.