Friday, January 22, 2016

Powershell: Write-Host vs Write-Output in Functions?

This comes up every so often. This is the question I saw recently:

I like to have my scripts and functions display a minimal level of progress on-screen by default, with more detailed progress listed by using -verbose. Write-Host works fine for the minimal progress display, but I keep reading horror stories of how the sky will fall if you use Write-Host instead of Write-Output in Powershell. However ... Write-Output seems to pollute the pipeline when trying to use the results of a function in a pipeline.

Is there a best practice for this? Should you use Write-Verbose for everything, or is Write-Host ok sometimes, or is there some other common process? - /u/dnisthmnace

One could argue that he has a solid understanding of it and you is on the right track. You can write a lot of code for yourself this way and everything would be OK.

The higher level discussion is that use of Write-Host is often a mental crutch that will slow your advancement of your Powershell skills. The problem is not so much that you are using it but why you think you need to be using it. But don't get hung up on that right now.

My advice is to start breaking your scripts into smaller pieces. Think of them as either tools or controller scripts. Tools are generic and reusable. The tools should be single purpose (do one thing and do that thing well). In your tools, use Write-Verbose.

Your controller scripts glue together your tools. Its OK for them to have a little more polish for the end user. This is where write-host would belong if you are using it (Purists can still use Write-Output). But the thing is that this a end of the line script. This is not a script that should be consumed by other scripts.

Personally, I use write-verbose for everything that I don't want on the pipe (even in my controller scripts). I do this so I can choose when I see the output and when I don't. When you start reusing code, this becomes more and more important. Before you know it, you have functions calling functions calling functions or functions executing with hundreds of data points. I can even set verbose on a function call but let that function suppress noisy sub functions.

I use Write-Verbose in my controller scripts because they can easily turn into tools and I don't have to go back and change the output.

I hope that sheds some light on the discussion. It's not the end of the world to use Write-Host, just know that you don't need to use it. Once you understand that, you will start writing better Powershell.

No comments: