Summary: Provide code support by using Verbose and Debug streams.
Honorary Scripting Guy and Windows PowerShell MVP, Boe Prox, here today filling in for my good friend, The Scripting Guy. This is the first part in a series of five posts about troubleshooting Windows PowerShell scripts and functions. The series includes:
- Provide Support by Using Verbose and Debug Streams (this post)
- Troubleshoot by Using Set-PSDebug
- Enforce Better Script Practices by Using Set-StrictMode
- Trace Your Commands by Using Trace-Command
- Use the PowerShell Debugger
When you write a script or function, you want to make sure that things work correctly and that you have provided enough information for the individuals who will be using the code in their day-to-day activities. Although you have Get-Help and inline comments in the code, sometimes they don’t provide the kind of troubleshooting that is needed when you are not getting the results that you are expecting.
We need a way to provide on-screen information that can be turned on or off without much more than a simple parameter. If only we had some sort of Verbose or Debug capability that could make this happen…
Oh, wait!
We have this built-in with Windows PowerShell!
Whenever a script or function is being built, all we have to do is add a couple of lines at the beginning of the code block to enable the Verbose and Debug parameters. As shown here, those pieces are [cmdletbinding()] and Param():
[cmdletbinding()]
Param ()
You must have these attributes available to have this capability. After this is accomplished, you can use Write-Verbose and Write-Debug in your code to provide more information when the script runs. Of course, you could use Write-Host, but that doesn’t turn off unless you provide your own parameter (a switch) and then use some logic to run the command if the parameter is used.
Using Verbose and Debug provides a cleaner approach to providing output by having a single line (Write-Verbose or Write-Debug) that provides information to the users (or to yourself) when someone is attempting to figure out why a script isn’t running the way it should. Another great feature that was introduced in Windows PowerShell 3.0 is that you can redirect the streams to a file if needed.
Note June Blender wrote an excellent post that you can read for more information: Understanding Streams, Redirection, and Write-Host in PowerShell.
So how should I use Write-Verbose and Write-Debug? In the end, it depends on what you want to use them for. In my case, I use them in the following ways:
- Write-Verbose
More for the user experience to show what is happening during the execution of the script. - Write-Debug
More for the code writer to show various points in the code, such as variables and their current values, that I can use to troubleshoot issues.
Knowing what I need to do to use Verbose and Debug streams, I can add those to a function and give it a run to see what happens. The following function provides an example to show using Verbose and Debug:
Function Invoke-Action {
[cmdletbinding()]
Param (
$Computername,
[hashtable]$Options,
$Timeout
)
$PSBoundParameters.GetEnumerator() | ForEach {
Write-Debug "[PSBoundParameters] $($_)"
}
If ($PSBoundParameters['Options']) {
$Options.GetEnumerator() | ForEach {
Write-Debug "[Options] $($_.Name) -> $($_.Value)"
}
}
ForEach ($Computer in $Computername) {
Write-Verbose "Testing $Computer"
}
}
Running this with both the –Verbose and –Debug parameters will give us a couple of streams that we can use to help determine what is going on in the script when it is running. Notice that I do not have to specify –Verbose or –Debug when I use Write-Verbose and Write-Debug. I will have to specify these parameters when I call the function in order to see the desired results.
Invoke-Action -Computername 'Computer1','Computer2','Computer3' -Options @{SkipIfOffline=$True;TestIsAdmin=$False} -Timeout 100 -Verbose -Debug
As you can see in this image, I have Debug showing the values of my bound parameters and listing the values in my options parameter. When you use –Debug in the function, it automatically sets the $DebugPreference for the scope of the function to ‘Inquire’, which works by prompting for user interaction.
I opted to use Verbose to say what was happening with the action being performed in the script. I could do more with either of these parameters, such as adding a time stamp, which can make it easier to see when each action is happening. I could also add a line number so myself or someone else can know exactly where the action is taking place.
As mentioned earlier, it is my preference to use Debug and Verbose, and not everyone might share this approach. When you use these in your code to provide some sort of simple troubleshooting of a script, you really can’t go wrong. The idea is to provide an approach so that you or someone else using your script can track down a possible issue and hopefully resolve it.
That is all there is to using the Verbose and Debug streams in a script or function to provide a way to troubleshoot scripts. Tomorrow I will show you how to use the Set-PSDebug cmdlet to troubleshoot scripts.
We invite you to follow the Scripting Guy on Twitter and Facebook. If you have any questions, send email to the Scripting Guy at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. Until then, see ya!
Boe Prox, Windows PowerShell MVP and Honorary Scripting Guy