BAMCIS.Logging.psm1
#region Logging Function Write-Log { <# .SYNOPSIS Writes to a log file and echoes the message to the console. .DESCRIPTION The cmdlet writes text or a PowerShell ErrorRecord to a log file and displays the log message to the console at the specified logging level. .PARAMETER Message The message to write to the log file. .PARAMETER ErrorRecord Optionally specify a PowerShell ErrorRecord object to include with the message. .PARAMETER Level The level of the log message, this is either INFO, WARNING, ERROR, DEBUG, or VERBOSE. This defaults to INFO. .PARAMETER Path The path to the log file. If this is not specified, the message is only echoed out. .PARAMETER NoInfo Specify to not add the timestamp and log level to the message being written. .INPUTS System.String The log message can be piped to Write-Log .OUTPUTS None .EXAMPLE try { $Err = 10 / 0 } catch [Exception] { Write-Log -Message $_.Exception.Message -ErrorRecord $_ -Level ERROR } Writes an ERROR log about dividing by 0 to the default log path. .EXAMPLE Write-Log -Message "The script is starting" Writes an INFO log to the default log path. .NOTES AUTHOR: Michael Haken LAST UPDATE: 8/24/2016 #> [CmdletBinding()] [OutputType()] Param( [Parameter()] [ValidateSet("INFO", "WARNING", "ERROR", "DEBUG", "VERBOSE", "FATAL", "VERBOSEERROR")] [System.String]$Level = "INFO", [Parameter(Position = 0, ValueFromPipeline = $true, ParameterSetName = "Message", Mandatory = $true)] [ValidateNotNullOrEmpty()] [System.String]$Message, [Parameter(Position = 0, ValueFromPipeline = $true, ParameterSetName = "Error", Mandatory = $true)] [Parameter(Position = 1, ParameterSetName = "Message")] [ValidateNotNull()] [System.Management.Automation.ErrorRecord]$ErrorRecord, [Parameter()] [System.String]$Path, [Parameter()] [Switch]$NoInfo ) Begin { } Process { if ($ErrorRecord -ne $null) { if (-not [System.String]::IsNullOrEmpty($Message)) { $Message += "`r`n" } $Message += ("Exception: `n" + ($ErrorRecord.Exception | Select-Object -Property * | Format-List | Out-String) + "`n") $Message += ("Category: " + ($ErrorRecord.CategoryInfo.Category.ToString()) + "`n") $Message += ("Stack Trace: `n" + ($ErrorRecord.ScriptStackTrace | Format-List | Out-String) + "`n") $Message += ("Invocation Info: `n" + ($ErrorRecord.InvocationInfo | Format-List | Out-String)) } if ($NoInfo) { $Content = $Message } else { $Lvl = $Level if ($Level -eq "VERBOSEERROR") { $Lvl = "ERROR" } $Content = "$(Get-Date) : [$Lvl] $Message" } if ([System.String]::IsNullOrEmpty($Path)) { $Path = [System.Environment]::GetEnvironmentVariable("LogPath", [System.EnvironmentVariableTarget]::Machine) } if (-not [System.String]::IsNullOrEmpty($Path)) { try { Add-Content -Path $Path -Value $Content } catch [Exception] { Write-Warning -Message "Could not write to log file : $($_.Exception.Message)`n$Content" } } switch ($Level) { "INFO" { Write-Host $Content break } "WARNING" { Write-Warning -Message $Content break } "ERROR" { Write-Error -Message $Content break } "DEBUG" { Write-Debug -Message $Content break } "VERBOSE" { Write-Verbose -Message $Content break } "VERBOSEERROR" { Write-Verbose -Message $Content break } "FATAL" { throw (New-Object -TypeName System.Exception($Content)) } default { Write-Warning -Message "Could not determine log level to write." Write-Host $Content break } } } End { } } Function Write-CMTraceLog { <# .SYNOPSIS Writes a log file formatted to be read by the CMTrace tool. .DESCRIPTION The cmdlet takes a message and writes it to a file in the format that can be read by CMTrace. .PARAMETER Message The message to be written to the file. .PARAMETER FilePath The path of the file to write the log information. .PARAMETER LogLevel The log level of the message. 1 is Informational, 2 is Warning, and 3 is Error. This defaults to Informational. .PARAMETER Component The component generating the log file. .PARAMETER Thread The thread ID of the process running the task. This defaults to the current managed thread ID. .PARAMETER ErrorRecord Specify a PowerShell ErrorRecord object to include with the message. The resulting message content will be in JSON format. .EXAMPLE Write-CMTraceLog -Message "Test Warning Message" -FilePath "c:\logpath.log" -LogLevel 2 -Component "PowerShell" This command writes "Test Warning Message" to c:\logpath.log and sets it as a Warning message in the CMTrace log viewer tool. .INPUTS System.String, System.Management.Automation.ErrorRecord .OUTPUTS None .NOTES AUTHOR: Michael Haken LAST UPDATE: 10/25/2017 .FUNCTIONALITY The intended use of this cmdlet is to write CMTrace formatted log files to be used with the viewer tool. #> [CmdletBinding()] [OutputType()] Param( [Parameter(Position = 0, ValueFromPipeline = $true, Mandatory = $true, ParameterSetName = "Message")] [ValidateNotNullOrEmpty()] [System.String]$Message = [System.String]::Empty, [Parameter(Position = 1, Mandatory = $true)] [ValidateNotNullOrEmpty()] [System.String]$FilePath, [Parameter(Position = 2)] [ValidateSet(1,2,3)] [System.Int32]$LogLevel = 1, [Parameter(Position = 3)] [ValidateNotNullOrEmpty()] [System.String]$Component = [System.String]::Empty, [Parameter(Position = 4)] [System.Int32]$Thread = 0, [Parameter(ParameterSetName = "Message")] [Parameter(Position = 0, Mandatory = $true, ParameterSetName = "Error")] [ValidateNotNull()] [System.Management.Automation.ErrorRecord]$ErrorRecord = $null ) Begin { } Process { if ($Thread -eq 0) { $Thread = [System.Threading.Thread]::CurrentThread.ManagedThreadId } $Date = Get-Date $Time = ($Date.ToString("HH:mm:ss.fff") + "+" + ([System.TimeZone]::CurrentTimeZone.GetUtcOffset((Get-Date)).TotalMinutes * -1)) $Day = $Date.ToString("MM-dd-yyyy") if ($ErrorRecord -ne $null) { [System.Collections.Hashtable]$Data = @{Exception = $ErrorRecord.Exception; Category = $ErrorRecord.CategoryInfo.Category.ToString(); StackTrace = $ErrorRecord.ScriptStackTrace; InvocationInfo = $ErrorRecord.InvocationInfo} if (-not [System.String]::IsNullOrEmpty($Message)) { $Data.Add("Message", $Message) } $Message = ConvertTo-Json -InputObject $Data -Compress } $File = $FilePath.Substring($FilePath.LastIndexOf("\") + 1) [System.String]$Log = @" <![LOG[$Message]LOG]!><time="$Time" date="$Day" component="$Component" context="" type="$LogLevel" thread="$Thread" file="$File"> "@ Add-Content -Path $FilePath -Value $Log -Force } End { } } #endregion |