Over the years, there has been a lot of debate around the PowerShell Write-Host
cmdlet on whether you need to use it. As in most cases, the answer is maybe and dependent on your needs.
To understand Write-Host
and when to use it, let’s quickly explore the history of Write-Host
and learn how best to use this useful cmdlet.
Modern Use of PowerShell Write-Host
Often in a script or PowerShell function, you need to convert information to a user about what is happening that is informational and does not directly relate to the output of a function.
Why do we say the modern use of
Write-Host
? Prior to PowerShell 5.x,Write-Host
was not tied to stream (such as the success, error, or warning streams). Therefore it was discouraged in use since it was not as controllable as the other output types.
Let’s take this simple example of a script that gives the user some information about how long a script is going to take to process.
Write-Host "Starting the gathering of information, be patient, this could take a while!"
Write-Host "- Gathering Process`r`n- Gathering Files`r`n- Gathering Users"
Write-Output "Display the information here..."
Write-Host "Information Gathering Complete!"
You’ll notice that this simply outputs information to the host which the end-user of your script can utilize to make further decisions. You may find yourself asking about pipeline content.
If you are sending objects from one cmdlet or function to another, but still want to display informational messages, can you do that? Thankfully, PowerShell’s Write-Host
cmdlet does not affect pipeline output! Let’s show how that works below.
Function Get-Information {
Write-Host "Starting the gathering of information, be patient, this could take a while!`r`n"
Write-Host "- Gathering Data`r`n- Returning Data`r`n"
[PSCustomObject]@{
"Test1" = "Value1"
"Test2" = "Value2"
}
Write-Host "Information Gathering Complete!"
}
Function Convert-Information {
Param(
[Parameter(ValueFromPipeline=$true)]$Param
)
$Param | ConvertTo-JSON
}
If you pipe the output of Get-Information
to Convert-Information
, it will not take into account any of the statements and only operate on the PSCustomObject
that is output.
Formatting Messages for Readability
Another very useful aspect of Write-Host
is the ability to format colors and output. Since this can be used for easier readability, this can greatly help PowerShell script users to understand what is happening and when actions may need to be taken.
-ForegroundColor
– The color of the information text.-BackgroundColor
– The color of the background behind the text.-Separator
– For objects that are outputWrite-Host
use the supplied separator instead of a space. This can be a carriage return and newline character such as"
rn"
.-NoNewLine
– Don’t output a newline character at the end of the output.
Let’s explore how we can construct a useful information message leveraging the various formatting parameters. In the below code, we are constructing an informational message about the number of results for an array and applying formatting to make it easier to view.
Multiple objects can be passed in to
Write-Host
to display as seen below. Typically a scripter will separate these messages by a space, but with the separator parameter, you can control how these are output to the console.
$Array = @(1,2,3,4,5)
Write-Host "Results Count:" -BackgroundColor DarkBlue -ForegroundColor White -NoNewline
Write-Host "" $Array.Count "Items`r`n" -ForegroundColor Red
Write-Host $Array -Separator "`r`n"
Write-Host "" "End of results." -ForegroundColor Green -Separator "`r`n"
By controlling the output with colors, newline, and separator output, we can craft a useful message that will give information about the script to the user. An example of this scenario is when you create an informational menu, among other use cases.
Redirecting Write-Host
Stream Output
Since Write-Host
is now controllable by stream output, there are a few ways to control and redirect the output. The InformationAction
preference is partly taken into account with Write-Host
messages. -InformationAction Ignore
will effectively suppress Write-Host
messages, but the $InformationPreference
and InformationAction
parameter does not affect the Write-Host
cmdlet.
Did you know that
Write-Host
is just a wrapper around theWrite-Information
cmdlet? This enables the output ofWrite-Host
to be contained within the information stream. This means that you can modify whereWrite-Host
messages go using the information stream.
That being said, you can still redirect the output of the Write-Host
messages to a different stream using the redirection operators. For example, output all Write-Host
messages to a log file. Taking that same example as seen above, let’s redirect all that output to a log file.
Write-Host "Results Count:" -BackgroundColor DarkBlue -ForegroundColor White -NoNewline 6>> .\log.txt
Write-Host "" $Array.Count "Items`r`n" -ForegroundColor Red 6>> .\log.txt
Write-Host $Array -Separator "`r`n" 6>> .\log.txt
Write-Host "" "End of results." -ForegroundColor Green -Separator "`r`n" 6>> .\log.txt
As you can see, PowerShell now redirects the output to a log but the formatting may not be exactly what you intended. That’s because the -NoNewLine
parameter isn’t really respected since that is mostly a host formatting tool. This may not be a big deal, but something to keep in mind when redirecting the stream output.
Conclusion
With the changes in PowerShell 5.x and on, Write-Host
is perfectly allowed for use and encouraged when you need to display informational messages to the user. Since a PowerShell user will have the necessary level of control over an informational message the same as an output or verbose message, the use of Write-Host
or Write-Information
is encouraged and recommended for use as necessary.