Okay… I hope I’m not the last person in the world to have figured this out or I’ll feel dumber than I already do.
I’ve been messing with PowerShell a lot and couldn’t figure out what the difference was between write-output and write-host, two cmdlets that both APPEAR to do the same thing. But now I get it.
My first clue was that the alias write points to write-output… so, although nearly EVERY example you see on the Internet uses write-host to produce output in the shell, it seemed as if write-output, with its convenient write alias, SHOULD be the one we all use.
And it should.
Some background is required: First, understand that the guts of PowerShell are really a big ‘old DLL, not an EXE. When you run Powershell.exe, you’re running what’s called a hosting application. In this case, the hosting app does nothing but host what I’ll call the Shell Engine, which is that big ol’ DLL. However, there are other hosting applications in the universe, such as the Exchange 2007 MMC. Obviously, not all hosting apps are equal: The Exch2007 MMC does lots more than just host the PowerShell Engine, even if that’s all Powershell.exe really does.
The Write-Output cmdlet (and the Write alias, therefore) spews output that’s meant to be displayed. In Powershell.exe, that results in text being displayed on the command line; in the Exch2007 MMC something else happens – perhaps a dialog box is displayed, depending on the circumstances. Remember, the Exch2007 MMC works by hosting PowerShell and calling on PoSH cmdlets to do its work; Write-Output becomes the primary means by which PoSH delivers output to the GUI. For example, Get-Mailbox might “write” a bunch of mailbox objects. In Powershell.exe, that results in a text-based list; the GUI, however, might render those objects as a set of icons.
Write-Host, on the other hand, is intended to write output to the hosting app itself, not necessarily for display to the end user. In the case of Powershell.exe, the hosting app just converts the output to test, so the result looks similar to Write-Output. But Write-Host is intended to communicate with the hosting app, not to communicate (necesarily) with the app’s user.
So: If you’re writing scripts which will be used entirely from Powershell.exe (e.g., the command-line), there’s no a ton of difference. However, if your scripts will ever run within a different hosting app, there’s a difference between what write-host does and what write-output does. For consistency, you should stick with Write-Output (or the Write alias) when you’re wanting to output something that’s meant for the user to see.
Here’s an example: Suppoe your script gets loaded into some future PowerShell Super Debugger. Write-Output might spit output into an “output” window, showing you what the user of your script would see; Write-Host might write seperate messages to a “trace” window, communicating with the hosting application to display status messages about your script’s execution (yes, there’s a Write-Debug which does this for this particular circumstance… but this is just an example).
Now, this whole business of “the shell isn’t just a command-line” and “the shell is hosted within other applications” is something I haven’t fully integrated into my own personal worldview <grin> yet, but I’m working on it… so if I’ve got this wrong (or if I’m right but you have a better example)… please drop me a line or post a comment.