grokgarble.com

Database, Software, and System Engineering

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!

,

3 thoughts on “Using Write-EventLog cmdlet in PowerShell

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>