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.

Image of logo

     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:

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.

Image of command output

I now use the redirection operator to redirect the verbose stream output to a text file:

Image of command output

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