Here is a function to save time when writing logging or debugging information in scripts. It has grown from a simple “dump stuff to a file” to a handy “Swiss army knife” of logging. The function is not perfect and will no doubt keep growing.
A quick thing to mention is that if the file locations are not passed to the function it will default to the variables $DebugFile and $LogFile. So if you define those at the start of your main script you will save yourself a lot of typing.
<#
.SYNOPSIS
Log to debug log file and/or log file.
.DESCRIPTION
writes a message/or object to a debug file. Can also write to the screen and log file.
Can also pause or exit on an error
message will have the format of
OK message here
fail message here
.PARAMETER message
The message to be displayed in the debug/log file or on screen
.PARAMETER NewDebugFile
the path to the debug file
.PARAMETER NewLogFile
the path to the log file
.PARAMETER ScreenOut
Set to also out put to the screen (Green OK, red Fail)
.PARAMETER ReturnCode
used to get the stats of the last commend $? or $true - success, $false - failed
.PARAMETER IgnoreReturnCode
if the return code is not null, setting this will ignore it.
.PARAMETER ClearDebugFile
will write the time to the debug file with no append, clearing the file.
.PARAMETER ClearLogFile
will write the time to the log file with no append, clearing the file.
.PARAMETER Logit
Will write the same message to the log file as well as the debug file.
.PARAMETER PauseOnError
Will pause execution if the ReturnCode is false, and wait for the user to press enter.
.PARAMETER StopOnError
Will exit execution if the ReturnCode is false.
.EXAMPLE
Send-Debug -Message "the command run" -ReturnCode $? -NewDebugFile ".\debug.log"
"OK the command run" is appended to the file debug.log (if the previous command was successfull)
"Fail the command run" is appended to the file debug.log (if the previous command failed)
.EXAMPLE
Send-Debug -Message "the command run" -NewDebugFile ".\debug.log"
" the command run" is appended to the file debug.log
.EXAMPLE
Send-Debug -Message "the command run" -ReturnCode $? -NewDebugFile ".\debug.log" -ClearDebugFile
"run at date time"
" the command run" is appended to the file debug.log
.EXAMPLE
Send-Debug -Message "the command run" -ReturnCode $? -NewDebugFile ".\debug.log" -NewLogFile ".\Log.log" -Logit
"OK the command run" is appended to the file debug.log and log.log (if the previous command was successful)
"Fail the command run" is appended to the file debug.log and log.log (if the previous command failed)
#>
function Send-Debug
{
[CmdletBinding()]
param
(
[Parameter(Mandatory = $false)] $NewDebugFile = $DebugFile,
[Parameter(Mandatory = $false)] $NewLogFile = $LogFile,
[Parameter(Mandatory = $false,ValueFromPipeline=$true)] $Message = " ",
[Parameter(Mandatory = $false)] [switch]$ScreenOut = $false,
[Parameter(Mandatory = $false)] $ReturnCode = $null,
[Parameter(Mandatory = $false)] [switch]$IgnoreReturnCode = $false,
[Parameter(Mandatory = $false)] [switch]$ClearDebugFile = $false,
[Parameter(Mandatory = $false)] [switch]$ClearLogFile = $false,
[Parameter(Mandatory = $false)] [switch]$Logit = $false,
[Parameter(Mandatory = $false)] [switch]$PauseOnError = $false,
[Parameter(Mandatory = $false)] [switch]$StopOnError = $false
)
if($Message -eq $null){$Message = " "} # $Message should not ever be null but bad things happen if it is.
# look for the $ClearDebugFile or $ClearLogFile settings and dont use the appand setting when writing to files.
if($ClearDebugFile) {("Run at " + (get-date).tostring()) | out-file $NewDebugFile}
if($ClearLogFile) {("Run at " + (get-date).tostring()) | out-file $LogFile}
# if there is no return code or the $IgnoreReturnCode setting is set.
if ($ReturnCode -eq $null -or $IgnoreReturnCode -eq $true)
{
# if $Message is an object, dont put the leading spaces in, just dump the object to file
if ($Message.gettype().name -match "object")
{
$LogMessage = $Message
}else{
$LogMessage = " " + $Message
}
# if the $ScreenOut setting is set we also use write-host to output to the screen
if ($ScreenOut){write-host $LogMessage -ForegroundColor yellow}
# if the $Logit setting is set we also use output to the $NewLogFile
if ($Logit) {$LogMessage | out-file $LogFile -Append}
# now we just dump $LogMessage to the debugFile
$LogMessage | out-file $NewDebugFile -Append
}
# if there is a successful return code AND the $IgnoreReturnCode setting is not set.
if ($ReturnCode -eq $true -and $IgnoreReturnCode -eq $false)
{
if ($Message.gettype().name -match "object")
{
$LogMessage = $Message
}else{
$LogMessage = "OK " + $Message
}
# if the $ScreenOut setting is set we also use write-host to output to the screen, this section outputs green text
if ($ScreenOut){write-host $LogMessage -ForegroundColor Green}
if ($Logit) {$LogMessage | out-file $LogFile -Append}
$LogMessage | out-file $NewDebugFile -Append
}
# if there is a failure return code AND the $IgnoreReturnCode setting is not set.
if ($ReturnCode -eq $false -and $IgnoreReturnCode -eq $false)
{
if ($Message.gettype().name -match "object")
{
$LogMessage = $Message
}else{
$LogMessage = "Fail " + $Message
}
# if the $ScreenOut setting is set we also use write-host to output to the screen, this section outputs red text
if ($ScreenOut){write-host $LogMessage -ForegroundColor red}
if ($Logit) {$LogMessage | out-file $LogFile -Append}
$LogMessage | out-file $NewDebugFile -Append
}
if ($PauseOnError -and ($ReturnCode -eq $false))
{
Write-host "An error has occured, Press Enter to continue" -ForegroundColor Red
$bob = read-host "Press Enter to continue"
}
if ($StopOnError -and ($ReturnCode -eq $false))
{
Write-host "An error has occured, unable to continue" -ForegroundColor Red
exit
}
}
So here is how it works:
set-something -SomethingTo 5
Send-Debug -Message "set something to 5" -ReturnCode $? -NewDebugFile ".\Debug.log"
The Send-Debug function will append the line “set something to 5” to the log file if the set-something was successful. If not it will append “Fail set something to 5”.
To much text? we can shorten that up a bit.
$DebugFile = ".\Debug.log"
set-something -SomethingTo 5
Send-Debug -ReturnCode $? -Message "set something to 5"
And then expand on that…
$DebugFile = ".\Debug.log"
set-something -SomethingTo 5
Send-Debug -ReturnCode $? -Message "set something to 5" -ScreenOut -ClearDebugFile
The above will also write the output to the screen in green if successful or red if not. Will also clear the Debug file, best to use this at the first call so you create/clear the debug file.
$DebugFile = ".\Debug.log"
$LogFile = ".\LogFile.log"
set-something -SomethingTo 5
Send-Debug -ReturnCode $? -Message "set something to 5" -ScreenOut -Logit -PauseOnError
Now this will output to the screen in the same way as the last example. But will also log to a log file. This is handy for a log file slowing a higher level summery then a full debug log. Finally the function will pause if the set-something command failed.
Or if you need to log the contents of unknown objects…
$DebugFile = ".\Debug.log"
$LogFile = ".\LogFile.log"
set-something -SomethingTo 5 | Send-Debug -ReturnCode $? -ScreenOut -Logit
The result of the command set-something -SomethingTo 5 will be piped in to Send-Debug as the message. If that input is an object it will be written to the debug file and printed to the screen.