Logging in Powershell

Logging is really, really important for powershell (or any scripts IMO). Yes, your scripts should be self-documenting and clear, but you just never know when or how things will go wrong. Especially if you’re using the scripts for important functions, investing in logging is really a must. You or whoever is maintaining the systems in 5-years will be thankful.

In Powershell v3 you can redirect all output except write-host.

This makes a BAT file I usually wrap powershell files in for logging purposes a lot easier.

Powershell v3

  • All you need to do is name the BAT file the same name as the ps1 file.
  • Set $verbosePreference and $debugPreference in your ps1 file
I usually like to write a quick function like this:
But, hold on. We can make this better. Especially if you re-use a lot of code and import other .ps1 files via dot-sourcing — figuring out errors can be a bit maddening. I generally use a logging function like the following to write more robust logs. This accepts any object type and also will show you the call stack — e.g.  [main.ps1][functions.ps1][Get-ToTheChopper]

Powershell v2

You can get a similar effect in v2, but honestly it’s a lot more pain than its worth.

Caveats:

And to the ps1 file:
Don’t forget: Since you’re essentially got just “stdout” you have to be extremely careful what you return through the pipe / write-output. Scripts end up having a lot of “cached” logging and it makes logging within functions very kludgey.

You can use similar “logging” functions like shown for v3 above, but you have to basically buffer output when “logging” from inside a function that returns any objects and remember to write the buffer out when it’s safe. It’s a giant pain, honestly.

 

Leave a Reply

Your email address will not be published. Required fields are marked *