HBoPS #3: Avoid using write-host

It once was said to avoid using write-host in any script, since every time you use it, a puppy dies ( )… Whilst this was certainly true in version up to PS5, starting this version write-host has become a wrapper for write-information in an attempt to save the puppies.

What is write-host?

Write-host is one of those easy cmdlets to tell the user what is going on in a script. Kind of funny, isn’t it? We’re writing scripts to automate things, but we still want people to know what is going on…

One of the major issues with write-host before PowerShell 5 is that it simly puts a text on the console. There is no way for the end-user to save, redirect, or ignore it.

So in essence you would not be able to pass the text you’re writing on to any other pipelines, making write-host just a very dumb tool that does not fit the general flexible environment of PowerShell.


A better alternative to using write-host is write-output. It is able to be saved, redirected, or ignored if so desired by the end-user, and generally is better at handling objects!

The downside, of course there always has to be a downside, is that it doesn’t allow you to write beautifully colored messages… Then again, there are ways around that 🙂

write-output and colored messages

One way (I’m certain there are more!) would be to change the $host.UI.RawUI.ForegroundColor property to the color you want displayed. Alas, this changes the setting for the entire console, so you would have to set it back to the previous color after running your write-output command.

# Saving previous Foreground color
$previousForegroundColor = $host.UI.RawUI.ForegroundColor

# Setting color to 'Red'
$host.UI.RawUI.ForegroundColor = 'Red'

# Write message to console
Write-Output "Hello World!"

# Setting color back
$host.UI.RawUI.ForegroundColor = $previousForegroundColor

That’s a lot of code for showing colored text on the console, but it’s easily made in to a function:

function Invoke-ColorOutput{
[ValidateSet('Black', 'DarkBlue', 'DarkGreen', 'DarkCyan', 'DarkRed', 'DarkMagenta', 'DarkYellow', 'Gray', 'DarkGray', 'Blue', 'Green', 'Cyan', 'Red', 'Magenta', 'Yellow', 'White')]
[ConsoleColor] $ForegroundColor,
[ValidateSet('Black', 'DarkBlue', 'DarkGreen', 'DarkCyan', 'DarkRed', 'DarkMagenta', 'DarkYellow', 'Gray', 'DarkGray', 'Blue', 'Green', 'Cyan', 'Red', 'Magenta', 'Yellow', 'White')]
[ConsoleColor] $BackgroundColor,
# Save previous colors
$previousForegroundColor = $host.UI.RawUI.ForegroundColor
$previousBackgroundColor = $host.UI.RawUI.BackgroundColor
Try{ # Catching non-terminating errors $ErrorActionPreference = 'Stop' Foreach($I in $object){ # Set BackgroundColor if available if($BackgroundColor -ne $null){ $host.UI.RawUI.BackgroundColor = $BackgroundColor } # Set $ForegroundColor if available if($ForegroundColor -ne $null){ $host.UI.RawUI.ForegroundColor = $ForegroundColor } # Always write (if we want just a NewLine) if($Object -eq $null){ $Object = "" } # Writ to Console if($NoNewline){ [Console]::Write($Object) }else{ Write-Output $Object } } }Catch{ Write-Warning "Oops... Something went wrong! ($($Error[0].Exception.GetType().FullName))" }Finally{ # restoring error action preference $ErrorActionPreference = 'Continue' } }End{ # Restore previous colors $host.UI.RawUI.ForegroundColor = $previousForegroundColor $host.UI.RawUI.BackgroundColor = $previousBackgroundColor }


HBoPS #1: Use a proper editor!
HBoPS #2: Error handling and you!
HBoPS #3: Avoid using Write-Host (and save puppies!)
HBoPS #4: Variables, Parameters, and Battlestar Galactica
HBoPS #5: Reduce, Reuse, Recycle
HBoPS #6: Handling Credentials

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Close Menu
%d bloggers like this: