One handy Powershell script template to rule them all

If you know me, you already know that I'm a huge fan of automation. Therefore, it's natural to assume that I would dabble in Powershell at least once or twice or a few dozen, as a method to implement useful automations. After all, automation is pretty much the whole essence of Powershell in the first place.

As I used Powershell scripts more and more, I learned that there are a few things that are important to have whenever you use such scripts as part of automation (by "automation" I mean any sort of operation done "unattended", i.e. without direct human interaction in real-time).

Here are the main general points that I learned:

Or, if TL;DR and you want to skip to the juicy parts:

Automated scripts must have historical logs

If at any point an automated script fails for some reason, or does not behave as expected, it would be invaluable to have it produce and retain historical logs that could later be investigated for clues as to what it did, and where and why it failed.

Powershell has a few useful cmdlets for this, capable of writing an Output to any sort of destination, such as a log file. For example, Out-File.

However, in my personal experience, nothing beats the level of verbosity offered by a special cmdlet called Start-Transcript.

This cmdlet receives a -Path parameter pointing to where you want to save your log (or "transcript") file, and once you run it, all outputs generated by your script would be saved to that log file. Even if that output came from a system or 3rd-party cmdlet which you have no control over, and even if you did not use Out-File.

It's important to note, though, that it would NOT capture output generated by the Write-Host cmdlet. But its sister cmdlets Write-Output, Write-Verbose, Write-Error, Write-Warning, etc. are all fair game and would be captured by the transcript.

When using system or 3rd-party cmdlets, you should remember to use the -Verbose switch so that those commands would generate useful output. For example Invoke-SqlCmd, Remove-Item, Copy-Item, etc.

Having the output of those cmdlets will help you greatly while investigating historical transcript logs.

Once you're done saving output to your transcript file, you can run the Stop-Transcript cmdlet.

Timestamps are important