PSBlogweek: PowerShell logging in the Windows Event log

This post is part of the #PSBlogWeek PowerShell blogging series. #PSBlogWeek is a regular event where anyone interested in writing great content about PowerShell is welcome to volunteer for. The purpose is to pool our collective PowerShell knowledge together over a 5-day period and write about a topic that anyone using PowerShell may benefit from. #PSBlogWeek is a Twitter hashtag so feel free to stay up to date on the topic on Twitter at the #PSBlogWeek hashtag. For more information on #PSBlogWeek or if you’d like to volunteer for future sessions, contact Adam Bertram (@adbertram) on Twitter.

Once you’re done getting schooled on everything this post has to offer head on over to the powershell.org announcement for links to the other four past and upcoming #PSBlogWeek articles this week!


An important part of PowerShell scripting is error handling, one of the main differences between a script and a one-liner for me personally is error handling and dealing with exceptions that might occur. For more information on error handling please refer to the previous PSBlogWeek articles where Boe Prox dives into use Try-Catch in order to catch specific errors.

When moving your scripts from into a production environment logging becomes more important, initially using plain text files for logging might be an appropriate solution. Another option however is writing logging information to the Windows Event Log. This has the benefit of being the centralized location where most logging takes place.

Writing to the event log is relatively simple, the Write-EventLog cmdlet can be used for this purpose:

PSBlogWeek2015-1

By taking a look at the error message we see that the PowerShell event source is not registered with the application log, in order to resolve this, we can write to the Windows PowerShell event log instead:

1
Write-EventLog -LogName 'Windows PowerShell' -Source PowerShell -EventId 12345 -EntryType Information -Message 'Script started'

PSBlogWeek2015-2

Notice how the command now successfully executes without the error message, this is because it is important for the script

Alternatively, it is also possible to specify a custom event provider, and register this to the correct event log as such:

1
2
New-EventLog -Source AwesomeScript -LogName 'Windows PowerShell'
Write-EventLog -LogName 'Windows PowerShell' -Source AwesomeScript -EventId 12345 -EntryType Information -Message 'Script started'

PSBlogWeek2015-3

It is also possible to create an entire separate event log for your script logging, also by using the New-EventLog cmdlet:

1
2
3
4
New-EventLog -LogName 'Scripts' -Source 'Your Script'
Write-EventLog -LogName 'Scripts' -Source 'Your Script' -EventId 12345 -EntryType Information -Message 'Script started'
New-EventLog -LogName 'Scripts' -Source 'Your Script2'
Write-EventLog -LogName 'Scripts' -Source 'Your Script2' -EventId 12345 -EntryType Information -Message 'Script started'

PSBlogWeek2015-4

To build upon this, it would be possible to create a script that logs when the script starts, executes an action, when an error occurs and when the script ends.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
begin {
    $EventHashInformation = @{
        LogName   = 'Scripts'
        Source    = 'Your Script'
        EventId   = 30000
        EntryType = 'Information'
    }
    $EventHashWarning     = @{
        LogName   = 'Scripts'
        Source    = 'Your Script'
        EventId   = 40000
        EntryType = 'Warning'   
    }
    Write-EventLog @EventHashInformation -Message 'Script started'
}
 
process {
    try {
        Get-CimInstance -ClassName Win32_Bios -ErrorAction Stop
        Write-EventLog @EventHashInformation -Message 'Successfully queried Win32_Bios'
    } catch {
        Write-EventLog @EventHashWarning -Message 'Error occurred while  queried Win32_Bios'
    }
}
 
end {
    Write-EventLog @EventHashInformation -Message 'Script finished'
}

PSBlogWeek2015-5

Using this method of logging allows for a dynamic form of logging where information such as the timestamp are automatically added to the information. A nice feature of using the event log is that it also allows for exporting the information directory to xml, for example:

1
2
3
Get-WinEvent -FilterHashtable @{
    LogName = 'Scripts'
} | ForEach-Object {$_.ToXml()}

PSBlogWeek2015-6

Because this type of logging can quickly fill up the event logs it is important to set the limits and the type of logging the event logs can do. In order to verify the current configuration, we can use the Get-EventLog cmdlet:

1
2
Get-EventLog -List | Where-Object {$_.LogDisplayName -eq 'Scripts'} |
Select-Object -Property Log,MaximumKilobytes,MinimumRetentionDays,OverFlowAction

PSBlogWeek2015-7

From this we gather that the Minimum retention of this log should be seven days and that only events older than 7 days will be discarded. If the event log is at the maximum size and there are no events older than 7 days to be discarded the latest event will be discarded and will not be written to the script. For more information on this subject please refer to the following MSDN article:
OverflowAction

Member name                                                                                                             Description 
DoNotOverwrite Indicates that existing entries are retained when the event log is full and new entries are discarded.
OverwriteAsNeeded Indicates that each new entry overwrites the oldest entry when the event log is full.
OverwriteOlder Indicates that new events overwrite events older than specified by the MinimumRetentionDays property value when the event log is full. New events are discarded if the event log is full and there are no events older than specified by the MinimumRetentionDays property value.

Based on the information in the article, we decide to increase the maximum size of log to 20 MB and to allow overwriting as needed, this is also referred to as circular logging:

1
2
3
Limit-EventLog -Maximumsize 20MB -Logname Scripts -OverflowAction OverwriteAsNeeded
Get-EventLog -List | Where-Object {$_.LogDisplayName -eq 'Scripts'} |
Select-Object -Property Log,MaximumKilobytes,MinimumRetentionDays,OverFlowAction

PSBlogWeek2015-8

With the information provided in this article you will be able to:

  • How to write information to the event log
  • How to register an event source to an event log
  • How to create a new event log
  • How to configure an existing event log

I hope this was informative and do not forget to read through the other #PSBlogWeek posts:

Links in this Article
Twitter #PSBlogWeek
#PSBlogWeek Announcement on PowerShell.org
MSDN Article: OverflowAction
Adam Bertram Blog
June Blender Sapien Blog
Jason Wasser Blog
Thom Schumacher Blog
Adam Platt Blog
Matt Johnson Blog

3 thoughts on “PSBlogweek: PowerShell logging in the Windows Event log

  1. Thom Schumacher

    Any thoughts about multi logging. where you log to eventlog also to a log file and then to the screen?

    I’ve attempted to start something along these lines with this code that I posted on Github. be interesting though to add what you speak of here for event log as well.

    github location:
    https://github.com/crshnbrn66/PSLog

    Reply
    1. Jaap Brasser Post author

      That is an interesting approach indeed, I will take a look at your code and see if I can amend it to also include event logging. Thanks for sharing your code Thom!

      Reply
  2. Pingback: The Popular Week of PowerShell Blogging is back! #PSBlogWeek » PowerShell.org

Leave a Reply

Your email address will not be published.