Controlling the output of Windows PowerShell commands
Windows PowerShell features several cmdlets for writing data. Knowing which commands do what can help control the output of your functions and keep your pipelines clean.
Past articles on Windows PowerShell have covered two of the three things to consider when writing production-quality functions – input and error handling. Now it’s time to look at the final factor: output.
Output of scripts and commands has long been troublesome and inconsistent, even within the same tool. Users didn’t know what to expect to the point that these days we have entire toolsets (like Awk, sed or grep) and skill sets based around “converting” output into the most desired data. One of the key tenants of Windows PowerShell is to have the kind of output users expect while avoiding the need to parse text. How does PowerShell do this? The answer is with objects, as I explained in my previous article, What makes Windows PowerShell unique?
Before we look at the cmdlets provided by PowerShell to write data, it’s important to understand how PowerShell deals with output. Most shells have a concept of data streams, the most common ones being stdout and stderr. PowerShell has a similar concept, only we call them pipelines.
In PowerShell there are three basic paths for data:
Output -- This is what is generally called the pipeline. It’s where data is passed from command to command.
Host -- This is written directly to the console.
Error -- This is written directly to the console, but is also stored in $error.
PowerShell has many cmdlets for “writing” data, the two main ones being:
Write-Host -- This is a simple cmdlet. It writes data directly to the console, bypassing the pipeline. It is useful if you want to provide information to the user without polluting the pipeline.
Write-Output -- This is used to explicitly write data directly to the pipeline. I say “explicitly” because if you don’t specify anything the default behavior is to write to the pipeline.
Other write cmdlets include:
Write-Debug -- Writes debug statements to the console if $DebugPreference is set to “continue”.
Write-Error -- Writes directly to the Error stream.
Write-EventLog -- Writes to the event log.
Write-Progress -- Here you are allowed you to write a progress bar to the screen for the user. This is generally used for long wrong commands where you can track progress.
Write-Verbose -- Writes to the host if $VerbosePreference is set to “continue”.
Write-Warning -- Writes to the host using a “warning” label.
As you can see, there are many ways to provide feedback to users. The key to success is to use your tools wisely. For example, to display a message to a user you’d want to use write-host instead of write-output. Why? Because you don’t want to pollute your output with notes to users, as it’s important to keep your pipeline flowing with objects the user expects. With a clean pipeline a user can expect consistent data with expected properties that they can access without the need to parse data.
In other words, a clean pipeline makes for a happy user.
Miss a column? Check out our Scripting School archive.
ABOUT THE AUTHOR
Brandon Shell has been in the IT industry since 1994. He started out as a PC tech and general fix-it guy for numerous companies. In 2007, he joined the PowerShell MVP ranks, and Shell has spent the past several years building his PowerShell knowledge and helping others build theirs.