Click to Rate and Give Feedback
TechNet
TechNet Library
Scripting
Windows PowerShell
 about_Debugger
about_Debugger

TOPIC

Debugging Windows PowerShell Scripts

Short Description

You can use the features of the Windows PowerShell debugger to examine a Windows PowerShell script, function, or ScriptCmdlet while it is running.

The Windows PowerShell debugger consists of a set of cmdlets that let you set and manage breakpoints, step through the script, and view the call stack.

Note:
The current Windows PowerShell debugger is a preview of the fully featured debugger. Some of the features of the debugger might not yet work properly.

Long Description

Debugging is the process of examining a script while it is running in order to identify and correct errors in the script instructions. Windows PowerShell offers several different ways to debug scripts, functions, and commands. You can debug on a local or remote computer.

  • The Set-PSDebug cmdlet offers basic script debugging features, including stepping and tracing.
  • Add diagnostic statements to a script, such as statements that display the value of variables, read input from the command line, or report the current instruction. Use the Write-* cmdlets for this task, such as Write-Host, Write-Debug, Write-Warning, and Write-Verbose.
  • Use the Windows PowerShell debugger cmdlets to set breakpoints, step through the script, perform actions at the breakpoint, and display the call stack.

The Windows PowerShell debugger is designed to help you examine and identify errors and inefficiencies in your scripts. The debugger consists of the following set of cmdlets:

  • New-PSBreakpoint: Sets breakpoints on lines, columns, variables, functions, and commands. By default, when you hit a breakpoint, Windows PowerShell stops execution and opens a nested debugging prompt, but you can also specify alternate actions, such as setting breakpoint conditions, logging, reporting, or running a diagnostic script.
  • Get-PSBreakpoint: Gets breakpoints in the current console.
  • Remove-PSBreakpoint: Deletes breakpoints from the current console.
  • Disable-PSBreakpoint: Turns off breakpoints in the current console.
  • Enable-PSBreakpoint: Re-enables breakpoints in the current console.
  • Step-Into: Executes the script one statement at a time.
  • Step-Over: Executes the script one statement at a time, but skips functions and calls to other scripts. The function or other script is executed, but the debugger does not stop at each statement in the function or script.
  • Step-Out: Exits the current breakpoint and continues running the script until completion or the next breakpoint. If used while stepping through a function, it exits the function and steps to the next statement.
  • Get-PSCallStack: Displays the current call stack.

You can also use an "Exit" statement, which exits the current breakpoint and runs the script until completion or the next breakpoint, even if used while stepping through a function.

By using these cmdlets, you can run a script, stop on a point of concern, examine the values of variables and the state of the system, and continue running the script until you have identified a problem.

Example

This test script detects the version of the operating system and displays a system-appropriate message. It includes a function, a function call, and a variable.

The following command displays the contents of the test script file.

c:>\PS-test> get-content test.ps1

function psversion {
"Windows Powershell " + $psversiontable.psversion
if ($psversiontable.psversion.major -lt 2) {
"Upgrade to Windows PowerShell 2.0!"
}
else {
"Have you run a background job today (start-psjob)?"
}
}
$scriptname = "test.ps1"
psversion
"Done $scriptname."

To start, set a breakpoint at a point of interest in the script, such as a line, command, variable, or function. We start by creating a line breakpoint on the first line of the Test.ps1 script in the current directory.

PS C:\ps-test> new-psbreakpoint -script test.ps1 -line 1

The command returns a line-breakpoint object (System.Management.Automation.LineBreakpoint).

Column : 0
Line : 1
Action :
Enabled: True
HitCount : 0
Id : 0
Script : C:\ps-test\test.ps1
ScriptName : C:\ps-test\test.ps1

Now, start the script.

PS C:\ps-test> .\test.ps1

The script hits the breakpoint. The breakpoint messages include a generic hit message and a message describing the current breakpoint. The extra carets (>) in the prompt indicate that you are in a nested debugging prompt. (Prompts can be multiply nested. To check the prompt level, type $NestedPromptLevel.)

A nested prompt is a complete Windows Powershell environment that inherits its properties from the parent environment. You can execute any commands, scripts, or functions in the nested prompt that you can in the parent prompt. In addition, you can use the debugging commands.

DEBUG: Hit breakpoint(s) on 'C:\ps-test\test.ps1:1'
DEBUG:Line breakpoint on 'C:\ps-test\test.ps1:1'
PS C:\ps-test>>>

Windows PowerShell debugger line breakpoints stop execution before the statement on the specified line is executed. In this case, the breakpoint is hit before the first statement in the script is executed.

Use the Step-Into cmdlet to preview the first statement in the script, which begins a function definition. The function is not yet defined (just displayed).

PS C:\ps-test>>> step-into
DEBUG: Stepped to 'C:\ps-test\test.ps1:function psversion {
'
PS C:\ps-test>>>

Use another Step-Into command to execute the current statement and preview the next statement in the script. (To repeat the last command, press the up-arrow key) or type "r", the alias for the Invoke-History cmdlet.)

PS C:\ps-test>>> step-into
DEBUG: Stepped to 'C:\ps-test\test.ps1:$scriptname = "test.ps1"
'
PS C:\ps-test>>>

At this point, the function has been defined, and the preview in the Debug message shows an assignment statement. (Notice that Step-Into steps between statements, not lines in the file.)

The second statement assigns the name of the script to the $scriptname variable. However, because Step-Into displays, but does not execute the statement, the $scriptname variable should still be $null (not yet assigned). To verify, display the value of $scriptname.

PS C:\ps-test>>> $scriptname
PS C:\ps-test>>> 

The $null value confirms that the statement has not yet been executed. Use another Step-Into command to execute the assignment statement and preview the next statement of the script.

PS C:\ps-test>>> step-into
DEBUG: Stepped to 'C:\ps-test\test.ps1:psversion
'
PS C:\ps-test>>>

At this point, the assignment should be complete. To verify the assignment, display the value of the $scriptname variable again.

PS C:\ps-test>>> $scriptname
test.ps1

This time, the variable contains the name of the script. Execute another Step-Into command. This time, the preview in the Debug message shows that Statement 4 of the script is a call to the PsVersion function.

PS C:\ps-test>>> step-into
DEBUG: Stepped to 'C:\ps-test\test.ps1:psversion
'
PS C:\ps-test>>>

The function call is previewed, but not executed. Use a Step-Into command to execute the function call.

PS C:\ps-test>>> step-into
DEBUG: Stepped to 'C:\ps-test\test.ps1:"Windows Powershell " + $psversiontable.psversion
PS C:\ps-test>>>'

Now, the Debug message includes a preview of the statement in the function. To execute this statement and preview the next statement in the function, you can use a Step-Into command. But, in this case, use a Step-Out command. It completes the execution of the function (unless it hits a breakpoint) and steps to the next statement in the script.

PS C:\ps-test>>> step-out
Windows Powershell 2.0
Have you run a background job today (start-psjob)?
DEBUG: Stepped to 'C:\ps-test\test.ps1:"Done $scriptname"
'
PS C:\ps-test>>>

Since we are on the last statement in the script, a Step-Into, Step-Out, or Exit command will have the same effect. In this case, use Step-Out.

PS C:\ps-test>>> step-out
Done test.ps1
PS C:\ps-test>>>

Now, we will run the debugger again. First, to delete the current breakpoint, use the Get-PsBreakpoint and Remove-PsBreakpoint cmdlets. (If you think you might re-use the breakpoint, use the Disable-PsBreakpoint cmdlet instead of Remove-PsBreakpoint.)

PS C:\ps-test> Get-PsBreakpoint | Remove-PSBreakpoint

This time, create a breakpoint on the $scriptname variable.

PS C:\ps-test> new-psbreakpoint -script test.ps1 -variable scriptname

Now, start the script. The script hits the variable breakpoint.

PS C:\ps-test> .\test.ps1
DEBUG: Hit breakpoint(s) on 'C:\ps-test\test.ps1:11'
DEBUG:Variable breakpoint on 'C:\ps-test\test.ps1:$scriptname' (Write access)
PS C:\ps-test>>>

Display the current value of the $scriptname variable.

PS C:\ps-test>>> $scriptname

test.ps1

PS C:\ps-test>>>

In this case, the value has already been assigned to the variable. Because the default mode for a variable breakpoint is WRITE access, execution stops after the value assignment. Use a Step-Into command preview the next statement in the script.

PS C:\ps-test>>> step-into
DEBUG: Stepped to 'C:\ps-test\test.ps1:psversion
'
PS C:\ps-test>>>

The next statement is a call to the PsVersion function. To skip over the function, but still execute it, use a Step-Over command. If you are already in the function when you use Step-Over, it is not effective, but at this point, the function callis only displayed, not executed.

PS C:\ps-test>>> step-over
Windows Powershell 2.0
Have you run a background job today (start-psjob)?
DEBUG: Stepped to 'C:\ps-test\test.ps1:"Done $scriptname"
'

The Step-Over command executes the function and it previews the next statement in the script, which prints the final line. Use an Exit or Step-Out statement to complete the execution of the script. (These commands will stop at breakpoints, but no other breakpoints are set.)

PS C:\ps-test>>> exit
Done test.ps1
PS C:\ps-test>

To delete the breakpoints, use the Get-PsBreakpoint and Remove-PsBreakpoint cmdlets.

PS C:\ps-test> Get-PsBreakpoint | Remove-PSBreakpoint

Create a new function breakpoint on the PsVersion function.

PS C:\ps-test> New-PsBreakpoint -script test.ps1 -function psversion

Now, run the script.

PS C:\ps-test> .\test.ps1
DEBUG: Hit breakpoint(s) on 'C:\ps-test\test.ps1:12'
DEBUG:Function breakpoint on 'C:\ps-test\test.ps1:psversion'
PS C:\ps-test>>>

The script hits the breakpoint at the function call. At this point, the function has not yet been called. This gives you the opportunity to use the Action parameter of New-PsBreakpoint to set conditions for the execution of the breakpoint or to perform preparatory or diagnostic tasks, such as starting a log or invoking a diagnostic or security script.

To set an action, use an Exit command to exit the script, and a Remove-PsBreakpoint command to delete the current breakpoint. (Breakpoints are read-only, so you cannot add an action to the current breakpoint.)

PS C:\ps-test>>> exit
Windows Powershell 2.0
Have you run a background job today (start-psjob)?
Done test.ps1
PS C:\ps-test> Get-PSBreakpoint | Remove-PsBreakpoint
PS C:\ps-test>

Now, create a new function breakpoint with an action. In this case, the function breakpoint is executed only if Windows PowerShell 1.0 is running in the console.

The BREAK keyword in the action directs the debugger to execute the breakpoint. You can also use the CONTINUE keyword to direct the debugger to execute without breaking. Because the default is CONTINUE, you must specify BREAK to stop execution.

PS C:\ps-test> new-psbreakpoint -script test.ps1 -function psversion -action { if ($psversiontable.psversion.major -eq 1) { break }}

When you run the script, execution stops at the PsVersion function call only if you are running Windows PowerShell 1.0.

You can also add actions that perform tasks at the breakpoint, instead of stopping execution. The following command creates a function breakpoint that logs the current value of the $scriptname variable when it hits the breakpoint. Because the BREAK keyword isn't used in the action, execution does not stop.

PS C:\ps-test> new-psbreakpoint -script test.ps1 -function psversion -action { add-content "The value of `$scriptname is $scriptname." -path action.log}

This example demonstrates just a few of many ways to use the Windows PowerShell debugger.

See Also



Tags What's this?: Add a tag
Community Content   What is Community Content?
Add new content RSS  Annotations
Processing
© 2008 Microsoft Corporation. All rights reserved. Terms of Use  |  Trademarks  |  Privacy Statement
Page view tracker