# encoding: utf-8
# api: powershell
# title: Write-Log
# description: Logging function for Powershell v2. Needed to address current Powershell logging limitations. See a discussion about said limitations here: http://jdhitsolutions.com/blog/2011/03/powershell-automatic-logging/#comment-2899 .
# version: 0.1
# type: function
# author: Will Steele
# license: CC0
# function: Write-Log
# x-poshcode-id: 5308
# x-archived: 2015-04-29T14:30:14
# x-published: 2015-07-15T18:24:00
#
# Logs to file and prints messages to the console and optionally logs to the system event logs. Note – admin rights are required when specifying the EventLogName parameter because the SourceExists method requires admin rights because it checks rights on the Security log. This limitation seems silly to me and if you think so as well get Microsoft to fix it by voting here: https://connect.microsoft.com/VisualStudio/feedback/details/293617/eventlog-sourceexists-always-fails-for-non-administrators#tabs .
# Feel free to add features as necessary.
# Will Steele: I suggest adding the Encoding switch to the Out-File calls (lines 58 and 60) to ensure the file didn’t clog up the output file. I also added a parameter, $LogEncoding, (lines 37-38) to allow for Encoding selection. The default is ASCII.
# It might be worth adding a few lines that allow for folder creation using the input file parameter. For instance, if the folder path referenced in the -Path parameter is invalid it doesn’t handle this. Example:
# dir | Write-Log -Path C:\test\test\test.txt
# Contacts
# Failed to create log entry in: ‘C:\test\test\test.txt’. The error was: ‘Could not find a part of the path ‘C:\test\test\test.txt’.’.
# At line:86 char:9
# + throw <<<< “Failed to create log entry in: ‘$Path’. The error was: ‘$_’.”
# + CategoryInfo : OperationStopped: (Failed to creat…st\test.txt’.’.:String) [], RuntimeException
# + FullyQualifiedErrorId : Failed to create log entry in: ‘C:\test\test\test.txt’. The error was: ‘Could not find a part of the path ‘C:\test\test\test.txt’.’.
#
function Write-Log {
#region Parameters
[cmdletbinding()]
Param(
[Parameter(ValueFromPipeline=$true,Mandatory=$true)] [ValidateNotNullOrEmpty()]
[string] $Message,
[Parameter()] [ValidateSet(“Error”, “Warn”, “Info”)]
[string] $Level = “Info”,
[Parameter()]
[Switch] $NoConsoleOut,
[Parameter()]
[String] $ConsoleForeground = 'White',
[Parameter()] [ValidateRange(1,30)]
[Int16] $Indent = 0,
[Parameter()]
[IO.FileInfo] $Path = ”$env:temp\PowerShellLog.txt”,
[Parameter()]
[Switch] $Clobber,
[Parameter()]
[String] $EventLogName,
[Parameter()]
[String] $EventSource,
[Parameter()]
[Int32] $EventID = 1
[Parameter()]
[String] $LogEncoding = "ASCII"
)
#endregion
Begin {}
Process {
try {
$msg = '{0}{1} : {2} : {3}' -f (" " * $Indent), (Get-Date -Format “yyyy-MM-dd HH:mm:ss”), $Level.ToUpper(), $Message
if ($NoConsoleOut -eq $false) {
switch ($Level) {
'Error' { Write-Error $Message }
'Warn' { Write-Warning $Message }
'Info' { Write-Host ('{0}{1}' -f (" " * $Indent), $Message) -ForegroundColor $ConsoleForeground}
}
}
if ($Clobber) {
$msg | Out-File -FilePath $Path -Encoding $LogEncoding -Force
} else {
$msg | Out-File -FilePath $Path -Encoding $LogEncoding -Append
}
if ($EventLogName) {
if (-not $EventSource) {
$EventSource = ([IO.FileInfo] $MyInvocation.ScriptName).Name
}
if(-not [Diagnostics.EventLog]::SourceExists($EventSource)) {
[Diagnostics.EventLog]::CreateEventSource($EventSource, $EventLogName)
}
$log = New-Object System.Diagnostics.EventLog
$log.set_log($EventLogName)
$log.set_source($EventSource)
switch ($Level) {
“Error” { $log.WriteEntry($Message, 'Error', $EventID) }
“Warn” { $log.WriteEntry($Message, 'Warning', $EventID) }
“Info” { $log.WriteEntry($Message, 'Information', $EventID) }
}
}
} catch {
throw “Failed to create log entry in: ‘$Path’. The error was: ‘$_’.”
}
}
End {}
<#
.SYNOPSIS
Writes logging information to screen and log file simultaneously.
.DESCRIPTION
Writes logging information to screen and log file simultaneously. Supports multiple log levels.
.PARAMETER Message
The message to be logged.
.PARAMETER Level
The type of message to be logged.
.PARAMETER NoConsoleOut
Specifies to not display the message to the console.
.PARAMETER ConsoleForeground
Specifies what color the text should be be displayed on the console. Ignored when switch 'NoConsoleOut' is specified.
.PARAMETER Indent
The number of spaces to indent the line in the log file.
.PARAMETER Path
The log file path.
.PARAMETER Clobber
Existing log file is deleted when this is specified.
.PARAMETER EventLogName
The name of the system event log, e.g. 'Application'.
.PARAMETER EventSource
The name to appear as the source attribute for the system event log entry. This is ignored unless 'EventLogName' is specified.
.PARAMETER EventID
The ID to appear as the event ID attribute for the system event log entry. This is ignored unless 'EventLogName' is specified.
.EXAMPLE
PS C:\> Write-Log -Message "It's all good!" -Path C:\MyLog.log -Clobber -EventLogName 'Application'
.EXAMPLE
PS C:\> Write-Log -Message "Oops, not so good!" -Level Error -EventID 3 -Indent 2 -EventLogName 'Application' -EventSource "My Script"
.INPUTS
System.String
.OUTPUTS
No output.
.NOTES
Revision History:
2011-03-10 : Andy Arismendi - Created.
2011-07-23 : Will Steele - Updated.
#>
}