With PowerShell, how can I get Write-Debug output to appear in the console?

tl;dr:

  • Run $DebugPreference = 'Continue' to start seeing output from Write-Debug calls.

  • When you're done, restore preference variable $DebugPreference to its default value, using $DebugPreference = 'SilentlyContinue'

  • To turn on debug output for a given cmdlet or advanced function only, use the -Debug common parameter.

    • Caveat: In Windows PowerShell (but no longer in PowerShell [Core] v6+, this will present an interactive debugging prompt for every Write-Debug statement encountered.

Whether output from Write-Debug statements is printed is controlled by two mechanisms:

  • Scope-wide: by the value of the $DebugPreference preference variable - see Get-Help about_Preference_Variables.

  • Ad-hoc, command-scoped, when calling a cmdlet or advanced script/function (which overrides the $DebugPreference value) with the -Debug common parameter - see Get-Help about_CommonParameters.

$DebugPreference defaults to SilentlyContinue, which explains why you don't see any output from Write-Debug statements by default.

When you use common parameter -Debug, you effectively set $DebugPreference for the invoked command only, and:

  • in Windows PowerShell, you invariably set it to the value Inquire, which not only prints Write-Debug messages, but also pauses at every such statement to ask how you want to proceed.

  • in PowerShell [Core] v6+, the value is now (more sensibly) set to Continue.

    • For a custom script or function to support the -Debug common parameter, it must be an advanced one, declared with the [CmdletBinding()] attribute for its param() block, as Mathias' answer shows.

Since, in Windows PowerShell, this prompt-at-every-Write-Debug-call behavior can be disruptive, $DebugPreference = 'Continue' may be the better approach. As stated, in PowerShell [Core] v6+ this is no longer a concern.

Note: If, from inside an advanced function or script, you want to distinguish between $DebugPreference having been set as a preference variable by the caller vs. common parameter -Debug having been passed (which is translated to a function/script-local $DebugPreference variable), use $PSBoundParameters.ContainsKey('Debug'); $true indicates that -Debug was used.


Reference official documentation: https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/write-debug

By default, debug messages are not displayed in the console, but you can display them by using the Debug parameter or the $DebugPreference variable.


You'll need a CmdletBinding attribute in your script if you want support for common parameters (including -Debug):

[CmdletBinding()]
param()

Write-Debug Start
Write-Debug End

I'd suggest having a look at the about_Functions_CmdletBindingAttribute help file

Tags:

Powershell