Of course. You can create conditional breakpoints in PowerShell, using the Set-PSBreakpoint
cmdlet. Consider the following code. Save it as a script file, and execute it. There are in-line comments to help you understand what's going on.
Keep in mind that there are three different types of breakpoints:
Command Breakpoint
This code example is using the command breakpoint type, because I am telling it to only set breakpoints on Get-WmiObject
commands. You can alternately specify a specific line number or a variable breakpoint type. You use the -Action
parameter to specify the conditions under which you want the breakpoint to be set. You must use the break
keyword somewhere inside the -Action
ScriptBlock
in order to instruct the debugger to pause execution of the PowerShell script.
# 1. Reset $Error to $null
$WmiError = $null;
# 2. Clean up any existing breakpoints
Get-PSBreakpoint | Remove-PSBreakpoint;
# 3. Set breakpoint, but only on Get-WmiObject commands, when the $WmiError variable is not $null
Set-PSBreakpoint -Command Get-WmiObject -Action { if ($WmiError) { break; } };
# 4. Failed Get-WmiObject command
Get-WmiObject -Class Win32_NonExistentClass -ErrorVariable WmiError;
# 5. Successful Get-WmiObject command
# PowerShell breaks here, because:
# - It's a Get-WmiObject command
# - The $WmiError variable is not null
Get-WmiObject -Class Win32_BIOS;
Since you mentioned using Write-Error
, you could set a PSBreakpoint
on lines where Write-Error
appears. Here is an example of how to do that:
Set-PSBreakpoint -Command Write-Error -Action { break; };
Pretty easy, right?
Variable Breakpoint
This example uses the variable PSBreakpoint
type, but only when the variable's contents are modified. You can use the -Mode
parameter to determine under what conditions the variable breakpoint is hit:
Code:
# 1. Clean up any existing breakpoints
Get-PSBreakpoint | Remove-PSBreakpoint;
# 2. Set a PSBreakpoint of type "variable" on a variable named "Data," but only when it has changed
Set-PSBreakpoint -Action { Write-Host -ForegroundColor Green -Object ('The $Data variable has changed! Value is: {0}' -f $Data); break; } -Variable Data -Mode Write;
# 3. No break on this line, because we are not changing the variable
Write-Host -Object $Data;
# 4. Execution is paused on this line, because we change the variable
$Data = 1;
Line Breakpoint
Now that we've looked at the variable and command PSBreakpoint
types, the last type of breakpoint to explore is the line breakpoint. If you were to copy/paste the code below, save it, and execute it, you would see that the code breaks on the Write-Host line (which happens to be line 9), but only when the Name
property of the $Service
variable is equal to WinRM
. That is what the conditional statement in the -Action
parameter's ScriptBlock
defines.
# 1. Clean up any existing breakpoints
Get-PSBreakpoint | Remove-PSBreakpoint;
# 2. Set a PSBreakpoint of type "line" on line #8, but only if the $Service variable's Name property equals 'winrm'
Set-PSBreakpoint -Action { if ($Service.Name -eq 'winrm') { break; } } -Line 9 -Script $MyInvocation.MyCommand.Path;
# 3. Get a list of Windows Services and iterate over them
foreach ($Service in (Get-WmiObject -Class Win32_Service)) {
Write-Host -Object ('Service name is: {0}' -f $Service.Name);
}