Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Function Write-Log {
- <#
- .SYNOPSIS
- Write messages to a log file in CMTrace.exe compatible format or Legacy text file format.
- .DESCRIPTION
- Write messages to a log file in CMTrace.exe compatible format or Legacy text file format and optionally display in the console.
- .PARAMETER Message
- The message to write to the log file or output to the console.
- .PARAMETER Severity
- Defines message type. When writing to console or CMTrace.exe log format, it allows highlighting of message type.
- Options: 1 = Information (default), 2 = Warning (highlighted in yellow), 3 = Error (highlighted in red)
- .PARAMETER Source
- The source of the message being logged.
- .PARAMETER ScriptSection
- The heading for the portion of the script that is being executed. Default is: $script:installPhase.
- .PARAMETER LogType
- Choose whether to write a CMTrace.exe compatible log file or a Legacy text log file.
- .PARAMETER LogFileDirectory
- Set the directory where the log file will be saved.
- .PARAMETER LogFileName
- Set the name of the log file.
- .PARAMETER MaxLogFileSizeMB
- Maximum file size limit for log file in megabytes (MB). Default is 10 MB.
- .PARAMETER WriteHost
- Write the log message to the console.
- .PARAMETER ContinueOnError
- Suppress writing log message to console on failure to write message to log file. Default is: $true.
- .PARAMETER PassThru
- Return the message that was passed to the function
- .PARAMETER DebugMessage
- Specifies that the message is a debug message. Debug messages only get logged if -LogDebugMessage is set to $true.
- .PARAMETER LogDebugMessage
- Debug messages only get logged if this parameter is set to $true in the config XML file.
- .EXAMPLE
- Write-Log -Message "Installing patch MS15-031" -Source 'Add-Patch' -LogType 'CMTrace'
- .EXAMPLE
- Write-Log -Message "Script is running on Windows 8" -Source 'Test-ValidOS' -LogType 'Legacy'
- .NOTES
- .LINK
- http://psappdeploytoolkit.com
- #>
- [CmdletBinding()]
- Param (
- [Parameter(Mandatory=$true,Position=0,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
- [AllowEmptyCollection()]
- [Alias('Text')]
- [string[]]$Message,
- [Parameter(Mandatory=$false,Position=1)]
- [ValidateRange(1,3)]
- [int16]$Severity = 1,
- [Parameter(Mandatory=$false,Position=2)]
- [ValidateNotNull()]
- [string]$Source = '',
- [Parameter(Mandatory=$false,Position=3)]
- [ValidateNotNullorEmpty()]
- [string]$ScriptSection = $script:installPhase,
- [Parameter(Mandatory=$false,Position=4)]
- [ValidateSet('CMTrace','Legacy')]
- [string]$LogType = $configToolkitLogStyle,
- [Parameter(Mandatory=$false,Position=5)]
- [ValidateNotNullorEmpty()]
- [string]$LogFileDirectory = $(If ($configToolkitCompressLogs) { $logTempFolder } Else { $configToolkitLogDir }),
- [Parameter(Mandatory=$false,Position=6)]
- [ValidateNotNullorEmpty()]
- [string]$LogFileName = $logName,
- [Parameter(Mandatory=$false,Position=7)]
- [ValidateNotNullorEmpty()]
- [decimal]$MaxLogFileSizeMB = $configToolkitLogMaxSize,
- [Parameter(Mandatory=$false,Position=8)]
- [ValidateNotNullorEmpty()]
- [boolean]$WriteHost = $configToolkitLogWriteToHost,
- [Parameter(Mandatory=$false,Position=9)]
- [ValidateNotNullorEmpty()]
- [boolean]$ContinueOnError = $true,
- [Parameter(Mandatory=$false,Position=10)]
- [switch]$PassThru = $false,
- [Parameter(Mandatory=$false,Position=11)]
- [switch]$DebugMessage = $false,
- [Parameter(Mandatory=$false,Position=12)]
- [boolean]$LogDebugMessage = $configToolkitLogDebugMessage
- )
- Begin {
- ## Get the name of this function
- [string]${CmdletName} = $PSCmdlet.MyInvocation.MyCommand.Name
- ## Logging Variables
- # Log file date/time
- [string]$LogTime = (Get-Date -Format 'HH\:mm\:ss.fff').ToString()
- [string]$LogDate = (Get-Date -Format 'MM-dd-yyyy').ToString()
- If (-not (Test-Path -LiteralPath 'variable:LogTimeZoneBias')) { [int32]$script:LogTimeZoneBias = [timezone]::CurrentTimeZone.GetUtcOffset([datetime]::Now).TotalMinutes }
- [string]$LogTimePlusBias = $LogTime + $script:LogTimeZoneBias
- # Initialize variables
- [boolean]$ExitLoggingFunction = $false
- If (-not (Test-Path -LiteralPath 'variable:DisableLogging')) { $DisableLogging = $false }
- # Check if the script section is defined
- [boolean]$ScriptSectionDefined = [boolean](-not [string]::IsNullOrEmpty($ScriptSection))
- # Get the file name of the source script
- Try {
- If ($script:MyInvocation.Value.ScriptName) {
- [string]$ScriptSource = Split-Path -Path $script:MyInvocation.Value.ScriptName -Leaf -ErrorAction 'Stop'
- }
- Else {
- [string]$ScriptSource = Split-Path -Path $script:MyInvocation.MyCommand.Definition -Leaf -ErrorAction 'Stop'
- }
- }
- Catch {
- $ScriptSource = ''
- }
- ## Create script block for generating CMTrace.exe compatible log entry
- [scriptblock]$CMTraceLogString = {
- Param (
- [string]$lMessage,
- [string]$lSource,
- [int16]$lSeverity
- )
- "<![LOG[$lMessage]LOG]!>" + "<time=`"$LogTimePlusBias`" " + "date=`"$LogDate`" " + "component=`"$lSource`" " + "context=`"$([Security.Principal.WindowsIdentity]::GetCurrent().Name)`" " + "type=`"$lSeverity`" " + "thread=`"$PID`" " + "file=`"$ScriptSource`">"
- }
- ## Create script block for writing log entry to the console
- [scriptblock]$WriteLogLineToHost = {
- Param (
- [string]$lTextLogLine,
- [int16]$lSeverity
- )
- If ($WriteHost) {
- # Only output using color options if running in a host which supports colors.
- If ($Host.UI.RawUI.ForegroundColor) {
- Switch ($lSeverity) {
- 3 { Write-Host -Object $lTextLogLine -ForegroundColor 'Red' -BackgroundColor 'Black' }
- 2 { Write-Host -Object $lTextLogLine -ForegroundColor 'Yellow' -BackgroundColor 'Black' }
- 1 { Write-Host -Object $lTextLogLine }
- }
- }
- # If executing "powershell.exe -File <filename>.ps1 > log.txt", then all the Write-Host calls are converted to Write-Output calls so that they are included in the text log.
- Else {
- Write-Output -InputObject $lTextLogLine
- }
- }
- }
- ## Exit function if it is a debug message and logging debug messages is not enabled in the config XML file
- If (($DebugMessage) -and (-not $LogDebugMessage)) { [boolean]$ExitLoggingFunction = $true; Return }
- ## Exit function if logging to file is disabled and logging to console host is disabled
- If (($DisableLogging) -and (-not $WriteHost)) { [boolean]$ExitLoggingFunction = $true; Return }
- ## Exit Begin block if logging is disabled
- If ($DisableLogging) { Return }
- ## Exit function function if it is an [Initialization] message and the toolkit has been relaunched
- If (($AsyncToolkitLaunch) -and ($ScriptSection -eq 'Initialization')) { [boolean]$ExitLoggingFunction = $true; Return }
- ## Create the directory where the log file will be saved
- If (-not (Test-Path -LiteralPath $LogFileDirectory -PathType 'Container')) {
- Try {
- $null = New-Item -Path $LogFileDirectory -Type 'Directory' -Force -ErrorAction 'Stop'
- }
- Catch {
- [boolean]$ExitLoggingFunction = $true
- # If error creating directory, write message to console
- If (-not $ContinueOnError) {
- Write-Host -Object "[$LogDate $LogTime] [${CmdletName}] $ScriptSection :: Failed to create the log directory [$LogFileDirectory]. `n$(Resolve-Error)" -ForegroundColor 'Red'
- }
- Return
- }
- }
- ## Assemble the fully qualified path to the log file
- [string]$LogFilePath = Join-Path -Path $LogFileDirectory -ChildPath $LogFileName
- }
- Process {
- ## Exit function if logging is disabled
- If ($ExitLoggingFunction) { Return }
- ForEach ($Msg in $Message) {
- ## If the message is not $null or empty, create the log entry for the different logging methods
- [string]$CMTraceMsg = ''
- [string]$ConsoleLogLine = ''
- [string]$LegacyTextLogLine = ''
- If ($Msg) {
- # Create the CMTrace log message
- If ($ScriptSectionDefined) { [string]$CMTraceMsg = "[$ScriptSection] :: $Msg" }
- # Create a Console and Legacy "text" log entry
- [string]$LegacyMsg = "[$LogDate $LogTime]"
- If ($ScriptSectionDefined) { [string]$LegacyMsg += " [$ScriptSection]" }
- If ($Source) {
- [string]$ConsoleLogLine = "$LegacyMsg [$Source] :: $Msg"
- Switch ($Severity) {
- 3 { [string]$LegacyTextLogLine = "$LegacyMsg [$Source] [Error] :: $Msg" }
- 2 { [string]$LegacyTextLogLine = "$LegacyMsg [$Source] [Warning] :: $Msg" }
- 1 { [string]$LegacyTextLogLine = "$LegacyMsg [$Source] [Info] :: $Msg" }
- }
- }
- Else {
- [string]$ConsoleLogLine = "$LegacyMsg :: $Msg"
- Switch ($Severity) {
- 3 { [string]$LegacyTextLogLine = "$LegacyMsg [Error] :: $Msg" }
- 2 { [string]$LegacyTextLogLine = "$LegacyMsg [Warning] :: $Msg" }
- 1 { [string]$LegacyTextLogLine = "$LegacyMsg [Info] :: $Msg" }
- }
- }
- }
- ## Execute script block to create the CMTrace.exe compatible log entry
- [string]$CMTraceLogLine = & $CMTraceLogString -lMessage $CMTraceMsg -lSource $Source -lSeverity $Severity
- ## Choose which log type to write to file
- If ($LogType -ieq 'CMTrace') {
- [string]$LogLine = $CMTraceLogLine
- }
- Else {
- [string]$LogLine = $LegacyTextLogLine
- }
- ## Write the log entry to the log file if logging is not currently disabled
- If (-not $DisableLogging) {
- Try {
- $LogLine | Out-File -FilePath $LogFilePath -Append -NoClobber -Force -Encoding 'UTF8' -ErrorAction 'Stop'
- }
- Catch {
- If (-not $ContinueOnError) {
- Write-Host -Object "[$LogDate $LogTime] [$ScriptSection] [${CmdletName}] :: Failed to write message [$Msg] to the log file [$LogFilePath]. `n$(Resolve-Error)" -ForegroundColor 'Red'
- }
- }
- }
- ## Execute script block to write the log entry to the console if $WriteHost is $true
- & $WriteLogLineToHost -lTextLogLine $ConsoleLogLine -lSeverity $Severity
- }
- }
- End {
- ## Archive log file if size is greater than $MaxLogFileSizeMB and $MaxLogFileSizeMB > 0
- Try {
- If ((-not $ExitLoggingFunction) -and (-not $DisableLogging)) {
- [IO.FileInfo]$LogFile = Get-ChildItem -LiteralPath $LogFilePath -ErrorAction 'Stop'
- [decimal]$LogFileSizeMB = $LogFile.Length/1MB
- If (($LogFileSizeMB -gt $MaxLogFileSizeMB) -and ($MaxLogFileSizeMB -gt 0)) {
- ## Change the file extension to "lo_"
- [string]$ArchivedOutLogFile = [IO.Path]::ChangeExtension($LogFilePath, 'lo_')
- [hashtable]$ArchiveLogParams = @{ ScriptSection = $ScriptSection; Source = ${CmdletName}; Severity = 2; LogFileDirectory = $LogFileDirectory; LogFileName = $LogFileName; LogType = $LogType; MaxLogFileSizeMB = 0; WriteHost = $WriteHost; ContinueOnError = $ContinueOnError; PassThru = $false }
- ## Log message about archiving the log file
- $ArchiveLogMessage = "Maximum log file size [$MaxLogFileSizeMB MB] reached. Rename log file to [$ArchivedOutLogFile]."
- Write-Log -Message $ArchiveLogMessage @ArchiveLogParams
- ## Archive existing log file from <filename>.log to <filename>.lo_. Overwrites any existing <filename>.lo_ file. This is the same method SCCM uses for log files.
- Move-Item -LiteralPath $LogFilePath -Destination $ArchivedOutLogFile -Force -ErrorAction 'Stop'
- ## Start new log file and Log message about archiving the old log file
- $NewLogMessage = "Previous log file was renamed to [$ArchivedOutLogFile] because maximum log file size of [$MaxLogFileSizeMB MB] was reached."
- Write-Log -Message $NewLogMessage @ArchiveLogParams
- }
- }
- }
- Catch {
- ## If renaming of file fails, script will continue writing to log file even if size goes over the max file size
- }
- Finally {
- If ($PassThru) { Write-Output -InputObject $Message }
- }
- }
- }
- #endregion
Advertisement
Add Comment
Please, Sign In to add comment