Why I Use WriteHost In PowerShell
I’m very aware that using Write-Host cmdlet in PowerShell is generally frowned upon by PowerShell experts, mainly because it bypasses the pipeline, so it limits what you can do with that info. The reason I like to use it in my scripts is that generally I plan to write to the console in a variety of colours in order to convey the information and to highlight that there has been a change. If a cube is only partially processed it generally means that there is a partition within a measure group that is not processed, and when you have hundreds of partitions stored away it really can become a mammoth task to find out which one is unprocessed. So I have a script that searches all partitions with a status of unprocessed and write it to the screen in red-on-black writing. Little did I know that Write-Error existed that does the exact same thing!
Jeffrey Snover
But still there are times when I want other flashy colours, so for the time being I will stick with outputting console data using Write-Host, regardless of what other cmdlets are available, to hell with what the naysayers may say! What if though, I want to do more than just write data to the console? As mentioned, Write-Host writes to the console and nothing else, so if we were to try to redirect the Write-Host I will get nothing. Here the best cmdlet to use is Write-Output. And if this script is run on a scheduled task, then if I use Write-Host, whatever is written will be lost. Here’s a nice little example concerning how Write-Output can be piped whilst Write-Host cannot:
#example one
function Test-Output {
Write-Output "Example using Write-Output"
}
Test-Output
#example two
function Test-Host {
Write-Host "Example using Write-Host" -foregroundcolor DarkGreen -backgroundcolor White
}
Test-Host
#example three
function Test-Output {
Write-Output "Example using Write-Output"
}
function Receive-Function {
process { Write-Host $_ -foregroundcolor Red -backgroundcolor Black }
}
Test-Output | Receive-Function
#example four
function Test-Host {
Write-Host "Example using Write-Host" -foregroundcolor DarkGreen -backgroundcolor White
}
function Receive-Function {
process { Write-Host $_ -foregroundcolor Red -backgroundcolor Black }
}
Test-Host | Receive-Function
If you were to run the first example the function would just get the output “Hello World” written to the console. If you do the same with Test-Host, the second function, things will be much the same because we’re not doing anything other than just writing to the console. But what if we want to pipe the function and do something with the text? In the third example, we use the Test-Output function and pipe it into the Receive-Function, and as we are using Write-Output we can manipulate it; It may just be a small example, but we were able to take the output of the Test-Output function and manipulate it in some way. If we tried that with the Test-Host function in the fourth example, we don’t get the same results. The colours are still the same despite the fact that we are piping into the Receive-Function
So, things are looking decidedly negative for Write-Host. But it is not all bad for Write-Host; there has to be a reason for creating such a cmdlet in the first place? The answer to this is of course that if all you want to do is write to the screen then Write-Host is your go to cmdlet: Even Jeffrey Snover has been known to remark, “you know, Write-Host isn’t all bad… so long as your verb is Show." Plus, if you tried to use the “-foregroundcolor DarkGreen -backgroundcolor White” with Write-Output, it won’t change the colours, so you’d need to pipe it into a Write-Host function, which (as we’ve seen above) is probably the correct way to organize your script in the first place! So it turns out that the reason I want to use Write-Host is right all along. However for a lot of my scripts, where I want to Show and nothing else, I need to go refactor a lot of my verbs!