Using Write-EventLog cmdlet in PowerShell
I set out to create a standard method of interacting with the Write-EventLog cmdlet. Simply put it will fail and I think it shouldn’t. It could be a little more robust, so I created my own function that is. The big thing that most people will benefit from is the ability to create a new source within a log. When they execute Write-EventLog they’re met with an error telling them that a source doesn’t exist within their log they specified:
Write-EventLog : The source name "MyScript" does not exist on computer "localhost".
Here’s a simple way to get around that do that:
PS C:> New-Eventlog -LogName "Application" -Source "MyScript"
Change “MyScript” to whatever you want the source element to reflect in your event log.
A more robust way of doing check, create if needed, then write and event can be seen here:
$ErrorActionPreference = "SilentlyContinue" if(!(Get-Eventlog -LogName $LogName -Source $Source)){ New-Eventlog -LogName "Application" -Source "MyScript" | Out-Null } $ErrorActionPreference = "Continue" Write-EventLog -LogName "Application" -Source "MyScript" -EntryType "Information" -EventId 0 -Message "Script Started."
First, I need to explain the “SilentlyContinue”. At least in 2.0, the Get-EventLog cmdlet has problems throwing exceptions. It doesn’t throw the exceptions correctly to be in a proper try/catch as discussed here. It appears to throw a PowerShell error that can’t be properly try/catched. After troubleshooting for a few hours, tracing the exception all over, I settled on a workaround. I set the $ErrorActionPreference variable to “SilentlyContinue” and test for a NULL return from Get-EventLog. If it’s return is NULL I create the log/source pair for logging and continue on my way. Any following Write-EventLog executions using the same LogName/Source pairing will log without the source error since you’ve created it on the machine from now to the end of time.
If you want to expand to include some permissions catching I suggest this approach:
$ErrorActionPreference = "SilentlyContinue" if(!(Get-Eventlog -LogName $LogName -Source $Source)){ $ErrorActionPreference = "Continue" try { New-Eventlog -LogName "Application" -Source "MyScript" | Out-Null Write-EventLog -LogName "Application" -Source MyScript" -EntryType "Information" -EventId 0 -Message "Script Started." } catch [System.Security.SecurityException] { Write-Error "Error: Run as elevated user. Unable to write or read to event logs." } } $ErrorActionPreference = "Continue"
I wanted to try and parameterize all of the options that the Write-Event cmdlet could do a little differently so the invocation of it within a script could be more standardized and much cleaner. So, I extended my working through integrating my own Write-EventLog cmdlet further to exposes all of the power around the cmdlet without getting hung up on errors and unknowns. Completed function script can be downloaded from here as well as viewed below:
Function Write-Event { <# .SYNOPSIS Write-Event function writes messages to the event log. .DESCRIPTION Write-Event function writes messages to the event log after creating the logname and source if not already defined. .PARAMETER $Message The message you want displayed in the event log body. Required. .PARAMETER $EventId The entryid number you wanted displayed in the event log. Default is 0. .PARAMETER $Source The source of the event log you wanted displayed in the event log. Default is the PowerShell script name the function was invoked from. .PARAMETER $LogName The log that you want the event loged in. Default is the Application log. If the Log and source pair do not exist on the machine this scirpt is invoked on the pair will be created. .EXAMPLE PS C:\> Write-Event -Message "Process Started." -EntryId 0 -Information .EXAMPLE PS C:\> Write-Event "Process Started." -Information .EXAMPLE PS C:\> Write-Event "Process Failed." -EntryId 161 -Error .EXAMPLE PS C:\> Write-Event "Process Started." .INPUTS System.String,System.Int32,System.String,System.String,System.Switch,System.Switch .OUTPUTS None .NOTES Additional information about the function go here. .LINK http://jeffmurr.com/blog #> [CmdletBinding()] param( [Parameter(Position=0, Mandatory=$true)] [ValidateNotNullOrEmpty()] [System.String] $Message, [Parameter(Position=1, Mandatory=$false)] [ValidateNotNullOrEmpty()] [System.Int32] $EventId = 0, [Parameter(Position=2, Mandatory=$false)] [System.String] $Source = "PowerShellScript", [Parameter(Position=3, Mandatory=$false)] [ValidateNotNullOrEmpty()] [System.String] $LogName = "Application", [Switch] $Information, [Switch] $Warning, [Switch] $Error ) $ErrorActionPreference = "SilentlyContinue" if(!(Get-Eventlog -LogName $LogName -Source $Source)){ $ErrorActionPreference = "Continue" try {New-Eventlog -LogName $LogName -Source $Source | Out-Null} catch [System.Security.SecurityException] { Write-Error "Error: Run as elevated user. Unable to write or read to event logs." } } If ($Warning.IsPresent){ try { Write-EventLog -LogName $LogName -Source $Source -EntryType "Warning" -EventId $EventId -Message $Message | Out-Null} catch [System.Security.SecurityException] { Write-Error "Error: Run as elevated user. Unable to write or read to event logs." } } ElseIf ($Error.IsPresent) { try { Write-EventLog -LogName $LogName -Source $Source -EntryType "Error" -EventId $EventId -Message $Message | Out-Null} catch [System.Security.SecurityException] { Write-Error "Error: Run as elevated user. Unable to write or read to event logs." } } Else { try { Write-EventLog -LogName $LogName -Source $Source -EntryType "Information" -EventId $EventId -Message $Message | Out-Null} catch [System.Security.SecurityException] { Write-Error "Error: Run as elevated user. Unable to write or read to event logs." } } }
Get to writing to the event log!
Asymmetric Encryption of Text using x.509 Certificates in PowerShell Network File Share in .NET C#
Your examples show a parameter called “EntryID,” which isn’t defined in the script. I assume you meant EventID?
Oops, nevermind, I see write-eventlog, doesn’t support messages from the pipe-line.
EntryID is like whether it’s a warning, error or informational. Comes from the wriite-event log cmdlet itself.