Are you a lumberJack?
Ever have difficulty implementing logging for long running or large scripts? Did they take up too much space because you either log EVERYTHING, or nothing? Or did you leave the logging you were doing while writing and troubleshooting your script, in the real script, and now you are creating too much noise? I was constantly changing my logging, adding, removing, commenting things out, then back in, etc. It was a mess, not consistent and a pain in the…… Not anymore! I’ve added a new function to the PowerLumber Module ‘Write-LogLevel’ that can increase or decrease the noise based on how the messages are defined in the script/module/function. This is just like Log4j that Java uses, although my implementation is a little different.
The PowerLumber Module is available in the PowerShell Gallery, and the source code is github.
Install-Module -Name PowerLumber
Import-Module -Name PowerLumber
Using the module you define each message with an option from ‘-MsgLevel’. The Options are currently:
TRACE,DEBUG,INFO,WARN,ERROR,FATAL,CONSOLEONLY
At runtime you define ‘-RunLogLevel’, based on the relationship between the options the message will get printed to the console, written to the log file, or both. The Options are currently:
ALL,TRACE,DEBUG,INFO,WARN,ERROR,FATAL,CONSOLEONLY,OFF
You can turn all logging off (‘-RunLogLevel OFF‘), and only output to the console(‘-RunLogLevel CONSOLEONLY‘), which is great for active debugging, without having to edit all of your log commands! If you are using a loop you also have the option of pulling in the -RunLogLevel from a property file so that you can edit the noise level on the fly.
Check out my example script, the console output versus the log output to see what I’m talking about. Sorry, its a bit redundant, but I wanted to make a point. Below we run the internal function 3 times, generating quite a few “messages” and a lot of console noise, but not all message are written to file…..
Write-Warning "Setting the RunLogLevel Variable controls the level of logs written to the logfile."
Write-Warning "All Message will print to the console unless 'OFF' is specified."
$script:RunLogLevel = "ERROR"
$logfile = "c:\temp\testing.log"
$Msg1 = "This is a TRACE Message"
$Msg2 = "This is a DEBUG Message"
$Msg3 = "This is a INFO Message"
$Msg4 = "This is a WARN Message"
$Msg5 = "This is a ERROR Message"
$Msg6 = "This is a FATAL Message"
$Msg7 = "This is a CONSOLEONLY Message"
$Msg8 = "This message has a hardcoded value for -RunLogLevel of ALL"
Write-Warning "You could force a message to appear, by specifying all as the -RunLogLevel"
Write-LogLevel -Message $Msg8 -Logfile $logfile -RunLogLevel ALL -MsgLevel TRACE
function Invoke-DemoLogLevel {
Write-Warning "See which items write to the log file as you change -RunLogLevel"
Write-LogLevel -Message $Msg1 -Logfile $logfile -RunLogLevel $script:RunLogLevel -MsgLevel TRACE
Write-LogLevel -Message $Msg2 -Logfile $logfile -RunLogLevel $script:RunLogLevel -MsgLevel DEBUG
Write-LogLevel -Message $Msg3 -Logfile $logfile -RunLogLevel $script:RunLogLevel -MsgLevel INFO
Write-LogLevel -Message $Msg4 -Logfile $logfile -RunLogLevel $script:RunLogLevel -MsgLevel WARN
Write-LogLevel -Message $Msg5 -Logfile $logfile -RunLogLevel $script:RunLogLevel -MsgLevel ERROR
Write-LogLevel -Message $Msg6 -Logfile $logfile -RunLogLevel $script:RunLogLevel -MsgLevel FATAL
Write-LogLevel -Message $Msg7 -Logfile $logfile -RunLogLevel $script:RunLogLevel -MsgLevel CONSOLEONLY
}
Invoke-DemoLogLevel
$script:RunLogLevel = "WARN"
write-Warning "You could force a message to appear, by specifying all as the -RunLogLevel"
Write-LogLevel -Message $Msg8 -Logfile $logfile -RunLogLevel ALL -MsgLevel TRACE
Invoke-DemoLogLevel
$script:RunLogLevel = "FATAL"
write-Warning "You could force a message to appear, by specifying all as the -RunLogLevel"
Write-LogLevel -Message $Msg8 -Logfile $logfile -RunLogLevel ALL -MsgLevel TRACE
Invoke-DemoLogLevel
So keep in mind this is just a sample to show you what it can do, its kinda messy and a very stupid script. Here is what the console looks like:

BUT WAIT! There’s LESS, YES LESS in the log file! Check out what actually got written to file:
It’s very clear that this function can clean up your logs, when you choose.
I’m open to feedback, I’m not sure I’m sold on the parameter names yet, but I love the functionality!