Summary: Microsoft Scripting Guy, Ed Wilson, continues his Scripting Games 2014 wrap up with a discussion of error and verbose message streams.
Microsoft Scripting Guy, Ed Wilson, is here. Things are starting to settle down here in the scripting household. Windows PowerShell Saturday #007 was a rousing success in Charlotte, North Carolina. Valentine’s Day was cool and a special treat for the Scripting Wife and I, and the 2014 Winter Scripting Games have concluded. So what’s to do? Well, today I am sipping a nice cup of Charleston Breakfast tea. I added peppermint, spearmint, honey, fresh lemon, and a cinnamon stick to the mixture. It is quite refreshing. Charleston Breakfast tea is one of the teas that is grown at the Charleston Tea Plantation. It has a nice robust flavor when steeped for four minutes in 208 degree water.
Note This is the fourth in a series of blog posts in which I talk about things I noticed whilst grading submissions for the
2014 Winter Scripting Games. In case you missed the previous episodes:
- 2014 Winter PowerShell Scripting Games Wrap Up #1
Talked about best practices for using aliases and for formatting of Windows PowerShell scripts. - 2014 Winter PowerShell Scripting Games Wrap Up #2
Talked about the need for and the use of structured error handling. - 2014 Winter PowerShell Scripting Games Wrap Up #3
Talked about using standard Windows folders from within Windows PowerShell scripts.
In today’s post, I’ll talk about using the Write-Verbose and Write-Error streams in Windows PowerShell scripts.
Alternative output message streams
One of the things I saw while grading scripts for the 2014 Winter Scripting Games was people creating their own alternate message streams. For example, they might do something like the following:
If($verbose) {Write-Host "This is verbose output"}
ELSE {Write-Host "This is normal output"}
Although this sort of thing might actually work (at least to an extent), it is not optimal. In fact, it causes a lot of extra work. This is because Windows PowerShell already has several message streams including:
- Normal output
- Errors
- Warnings
- Verbose output
- Debug messages
Whether these messages display anything is due to the configuration of one of the following Preference variables:
- DebugPreference
- ErrorActionPreference
- VerbosePreference
- WarningPreference
The neat thing is that I implement my script in the proper Windows PowerShell fashion, then I can capture these alternate message streams in a text file via the redirection operators introduced in Windows PowerShell 3.0. The following table lists the redirection operators.
Note The 2>, 2>>, and 2&1 operators existed in Windows PowerShell 1.0.
Operator | Description | Example |
> | Sends output to the specified file | Get-Process > Process.txt |
>> | Appends the output to the contents of the specified file | dir *.ps1 >> Scripts.txt |
2> | Sends errors to the specified file | Get-Process none 2> Errors.txt |
2>> | Appends errors to the contents of the specified file | Get-Process none 2>> Save-Errors.txt |
2>&1 | Sends errors (2) and success output (1) to the success output stream | Get-Process none, Powershell 2>&1 |
3> | Sends warnings to the specified file | Write-Warning "Test!" 3> Warnings.txt |
3>> | Appends warnings to the contents of the specified file | Write-Warning "Test!" 3>> Save-Warnings.txt |
3>&1 | Sends warnings (3) and success output (1) to the success output stream | Function Test-Warning {Get-Process PowerShell; Write-Warning "Test!" } Test-Warning 3>&1 |
4> | Sends verbose output to the specified file | Import-Module * -Verbose 4> Verbose.txt |
4>> | Appends verbose output to the contents of the specified file | Import-Module * -Verbose 4>> Save-Verbose.txt |
4>&1 | Sends verbose output (4) and success output (1) to the success output stream | Import-Module * -Verbose 4>&1 |
5> | Sends debug messages to the specified file | Write-Debug "Starting" 5> Debug.txt |
5>> | Appends debug messages to the contents of the specified file | Write-Debug "Saving" 5>> Save-Debug.txt |
5>&1 | Sends debug messages (5) and success output (1) to the success output stream | Function Test-Debug { Get-Process PowerShell; Write-Debug "PS" } Test-Debug 5>&1 |
*> | Sends all output types to the specified file | Function Test-Output { Get-Process PowerShell, none; Write-Warning "Test!"; Write-Verbose "Test Verbose"; Write-Debug "test debug"} ; Test-Output *> Test-Output.txt |
*>> | Appends all output types to the contents of the specified file | Test-Output *>> Test-Output.txt |
*>&1 | Sends all output types (*) to the success output stream | Test-Output *>&1 |
An example of how to use the alternate message streams is shown here:
$desktopPath = [System.Environment]::GetFolderPath("Desktop")
Function Out-VerboseStream
{
BEGIN { $oldVerbosePreference = $VerbosePreference }
PROCESS {
$VerbosePreference = "Continue"
Write-Verbose "This is verbose output"
"This is regular output" }
END {$VerbosePreference = $oldVerbosePreference }
}
The key features are to set the preference variable to “Continue” to permit it to output. As a best practice, you should set it back when you are finished. As shown in the following image, I first run the function, and the verbose stream and the regular stream appear in the output pane.
I now use the redirection operator to redirect the verbose stream output to a text file:
Now when I use the redirection operator to redirect the verbose stream, it goes in a text file.
The following table illustrates the different type of redirection characters that are used to represent the message streams.
Character | Meaning |
* | All output |
1 | Success output |
2 | Errors |
3 | Warning messages |
4 | Verbose output |
5 | Debug messages |
That is all there is to using different output streams. 2014 Winter PowerShell Scripting Games Wrap-Up Week continues tomorrow when I will talk about using the Switch statement.
I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.
Ed Wilson, Microsoft Scripting Guy