Write-Host – The gremlin of PowerShell

The good
Whenever you want output on your screen in different colours, Write-Host is your tool.
There’s even a TechNet article on it: ‘Display Output in Color Using Windows PowerShell‘.

The bad
“Every time you use Write-Host, you kill a puppy…”
That’s one of my favorite quotes from the (in)famous PowerShell MVP Don Jones.
The bad very well explained by Jeffrey Snover (PowerShell daddy) in his blog post ‘Write-Host Considered Harmful‘.
In a nutshell: It interferes with automation.
The whole point of PowerShell is automation!

The ugly
People starting to listen. They’re not using Write-Host anymore.
But they still want to use colours, so for blue Write-Verbose is what they use.
For yellow, they use Write-Warning.
In my opinion, this is also terribly wrong!
Why? Write-Verbose doesn’t show itself by default. You’ll have to use the -Verbose parameter in order to get it to show output.
Write-Error provides an output like an error, in red. Not just the text you provide as input, but a bunch of stuff you’ll probably don’t want if your goal is to have red output.

So that leaves us Write-Warning. This gives a nice yellow output with no fluffy stuff like Write-Error does… just the input you’ve provided in the colour yellow.

But Write-Host offers more colours than just these three. So I can understand, from a colour perspective, why people started to abuse the Write-* cmdlets.

A practical look.
Whenever I script, I want to pipe output to another command which in turn uses it as input.
Using Write-Host will make that impossible…

Try it with Write-Output:

And now the same with Write-Host:

A few months ago I had the pleasure to script against a product called AppAssure from Dell.
Well, they use Write-Host in their cmdlets.
All the output provided by those cmdlets was useless to me.
I wasn’t able to use their output and therefor had to do me some fancy scripting to check if my action had any result.
It would have been much, much easier if I could just have checked the output fmo the command and be done with it.
But apparenly they thought that would have been to easy, or something…

The alternative
The goal would be to output text in a colour. That’s it, pure and simple.
In my opinion, Microsoft doesn’t provide a viable alternative to Write-Host in that perspective.
So, here’s where the PowerShell community steps in 🙂 Jeffery Hicks, PowerShell MVP, has written a function called ‘Out-ConsoleGraph‘.

This allows you to use the colours as you did with Write-Host, and much, much more.
Just take a look, I’m pretty sure you’re going to like it 🙂

The solution
I would love for Microsoft to include something native in PowerShell which allows colourized output.
Maybe a parameter attached to Write-Output, or a new cmdlet all together in order not to possibly break any existing scripts out there.
For now, just remember: Don’t use Write-Host unless you don’t care about the output and automation of the task.

4 comments

  1. Victor Vogelpoel says:

    I personally believe that Write-Host is very useful. Not for returning objects, like you are stating, but for tracing and logging! In the PowerShell frameworks I write, I like to have loads of tracing/logging information on what the scripts and commands are doing. Everything is logged automatically to a transcript file; if an (unattended) script failed somehow, the transcript file will help me to trace the issue.

    I’m using my own replacement Write-Host function that identifies the server where the Write-Host was executed in a remoted/workflow scenario by automatically prefixing text with “[servername]” and logging the text to a server specific log file. (the framework uses a controller script to coordinate installations and configurations on several servers at once, so it’s very useful to see what text came from what server). My Write-Host function ultimately calls the the PowerShell native version.

    The best practice is to use Write-Verbose for outputting tracing text to the host, but i started to dislike the “Verbose:” prefix (and the explicit use of -verbose switch). If the requirement would be not to use Write-Host anymore, I would introduce my own Write-Verbose (framework specific “Write-FrmwrkVerbose”) to use instead of Write-Host for verbose output combined with a $FrmwrkVerbosePreference global variable

    I’d love to show you what we’ve built.

    @victorvogelpoel

  2. Jeff Wouters says:

    Hi Victor,
    You’ve basically touched possible single exception to the rule 🙂
    I’ve done something similar, using write-host to output results (not objects) to the screen.
    If an error occurs, the line is shown in the colour ‘red’ and therefor the helpdesk can immediatly see something is going wrong.
    … and that’s where the alternative by Jeffery Hicks comes into play… no need for Write-Host 🙂
    As for your example, why not use PowerShell remoting and and do Write-output (“[“+($Env:ComputerName)+”][Just some message]”).
    I totally feel your comment about write-verbose though. That’s why I stated there isn’t a viable alternative, in my opinion, built into the shell.
    Jeff.

  3. Cody says:

    When Microsoft gives us a flag to:

    * Remove the VERBOSE: prefix from Write-Verbose.
    * Remove the nonsensical additional information returned in Write-Error

    Then they can pry Write-Host from my cold, dead fingers.

  4. Jeff Wouters says:

    Hi, Cody,
    Take a look at the VerbosePreference variable.
    Regarding Write-Error, it outputs .net error objects and should be used as such.
    I think the question becomes what you use Write-Error for.
    It’s my personal believe that a script should always be able to run non-interactively and therefor any user-interaction becomes mute.
    Write-Host writes to the host, to the user.

    However, if you want/need colorful output to the screen, I agree with you that write-host has a valid use-case.
    The problem I have with it is that you can’t do anything with it, like redirect the output to a file.

    The right command for the right use-case. If Write-Host fits your needs, personally have no issue with you using it 🙂

    Jeff.

Leave a Reply

Your email address will not be published. Required fields are marked *