It is clear that Write-Host and Write-Output are different and they behave differently. One difference I have noticed is that if you redirect output to a file they are some different and interesting behaviours. First I added some Write-Host and Write-Output calls to a .ps1 file to test with. Executing this file from within a PowerShell prompt or an operating system prompt show all the output as you would expect. However, if you redirect the output to a file with > output.txt then from a PowerShell prompt Write-Host is still displayed but Write-Output goes to the file, from the operating system prompt calling PowerShell with the name of the .ps1 file then the output all goes to the file. Interestingly Write-Error output works just like Write-Host, except of course it outputs red text on a black background, which does make it stand out, which is good.

There is also Write-Verbose and Write-Debug, however these need to be used differently as generally speaking their output it not shown. Furthermore you also need to work with them differently at the script level, so, here's an example:

            HelpMessage="Please specify a file to process")]

            HelpMessage="This is to enable verbose output")]

            HelpMessage="This is to enable debug output")]


Function TestOutput() {
    $Message = "FileName [$($FileName)] Page Size [$($page)]"
    Write-Host "Writing to host [$($Message)]"
    Write-Output "Writing to output [$($Message)]"
    Write-Verbose "Writing to verbose! [$($Message)]"
    Write-Debug "Writing to debug! [$($Message)]"
    Write-Error "No real error... [$($Message)]"

Write-Host "Starting...."
Write-Host "Param: VerboseMode: $($VerboseMode)"
Write-Host "Param: DebugMode: $($DebugMode)"

if ($VerboseMode) { $VerbosePreference = "Continue"}
if ($DebugMode) { $DebugPreference = "Continue" }


Write-Host "Finished"
I suggest you save this as a file and execute it and then just experiment and see how you get on, it certainly helped me understand what is going on, it is also worth redirecting its output to a file as well. It is also worth mentioning that you can simplify the above by using -verbose as a parameter when running your script, which I only learnt after doing the above! You can alternatively or additionally add -debug, however this will cause a prompt about whether you want to continue or not, so my approach does have one advantage over this. It is very important to note that -verbose does not work without a correctly configured parameter in the param section. Therefore I would suggest adding a param block and just documenting the use of the verbose and debug options.

It is worth noting that the default value for $DebugPreference is SilentlyContinue, which means output nothing and carry on. If you have a param block and then use -Debug this will set $DebugPreference to Inquire which means execution stops at the first Write-Debug and it asks you what you want to do next, whereas my -DebugMode above sets $DebugPreference to Continue, which just outputs the text and carries on.

So, now we are getting to grips with Write-Host and Write-Output it is worth mentioning that some people argue you should not use either, see Get-PowerShellBlog: Let’s Kill Write-Output for some explanation but in brief it comes down to performance and doing things in a PowerShell pipeline way. It is worth reading Write-Host Considered Harmful | Jeffrey Snover's blog on using Write-Host, as it explains why it is wrong. The only real use of it is for colour output but generally that is rare.

Reading about_CommonParameters shows that -Verbose is a Common Parameter, like -Debug and they can both be used with functions to control output. In Use PowerShell to Write Verbose Output - Hey, Scripting Guy! Blog - Site Home - TechNet Blogs this topic is discussed further, but also see ps - Powershell script support for -verbose - Stack Overflow.

See also:

More useful links: