Using the Event Log with PowerShell

PowerShellPowerShell can be used in a diverse set of circumstances. Sometimes PowerShell is used to establish an ongoing process, such as managing users. In such a circumstance, logging becomes rather crucial, both in terms of identifying errors but also in terms of capturing what was successful to provide reports. The Windows Event Log is a great existing tool for such a task and PowerShell is capable of working with it in many different ways.

Establishing an Application Log

Let’s imagine that we have a system that we want to provision users and it requires numerous scripts to manage the overall process. We’ll call the overall capability set “Provisioning” and we’ll call the three sub-processes “User Provisioning,” “Policy Assignment,” and “Licensing.” We’ll be using a Windows Server system as a host to execute the related scripts and we want to create a custom Application in the event log:


New-EventLog -LogName "Provisioning" `
-Source "User Provisioning"
New-EventLog -LogName "Provisioning" `
-Source "Policy Assignment"
New-EventLog -LogName "Provisioning" `
-Source "Licensing"

view raw

New-EventLog

hosted with ❤ by GitHub


New-EventLog -LogName "Provisioning" `
-Source "User Provisioning"
New-EventLog -LogName "Provisioning" `
-Source "Policy Assignment"
New-EventLog -LogName "Provisioning" `
-Source "Licensing"

Writing Event Log Entries

Within our scripts, we can use various means to identify items that we would like to capture in the event log. We could use Try/Catch blocks. If we’re provisioning a user, we could run the following at the end of the Try block to denote the successful provisioning of a user:


Write-EventLog -LogName "Provisioning" `
-Source "User Provisioning" `
-EntryType Information -EventId 1000 `
-Message "User provisioned: ${UserPrincipalName}"

view raw

Write-EventLog

hosted with ❤ by GitHub


Write-EventLog -LogName “Provisioning” `
-Source “User Provisioning” `
-EntryType Information -EventId 1000 `
-Message “User provisioned: ${UserPrincipalName}”

If we attempted to license a user and it failed, we could run the following in the Catch block:


Write-EventLog -LogName "Provisioning" `
-Source "Licensing" `
-EntryType Error -EventId 3300 `
-Message "No licenses available for user: ${UserPrincipalName}"

view raw

Write-EventLog2

hosted with ❤ by GitHub


Write-EventLog -LogName “Provisioning” `
-Source “Licensing” `
-EntryType Error -EventId 3300 `
-Message “No licenses available for user: ${UserPrincipalName}”

Taking Action

In some instances we may simply choose to report on items daily, weekly, or monthly. This would work well for getting a summary of the number of users provisioned. We could write a script for a scheduled task to execute on the desired interval and pull the requisite information like so:


Get-EventLog -LogName "Provisioning" `
-Source "User Provisioning" `
-EntryType Information `
-After (Get-DateTime -format %m/%d/%Y)

view raw

Get-EventLog

hosted with ❤ by GitHub


Get-EventLog -LogName “Provisioning” `
-Source “User Provisioning” `
-EntryType Information `
-After (Get-DateTime -format %m/%d/%Y)

We could store this in a variable, pass it through Select-Object to grab the specific attributes that are interesting, and through Where-Object to filter the results, then make a report with ConvertTo-Html.

That is great for situations where things are working and we just want a report. However, when things go wrong, we likely want to be notified in a more timely manner.

Establishing Triggers

A scheduled task need not only be based on a time of day, it can also be triggered by the instance of an event. Since this is specifically what we are looking to do, this comes in handy. In order to grab the proper information, we could just grab the last instance of an event from the event log with Get-EventLog, or we could use some of the capabilities of the trigger to kick off our script and pass the specific event log entry to it. There are many ways to do this, but I find that the most extensible way is to pass the LogName and Index to the script. With these pieces of information we can grab the exact event log entry and take away all of the guess work.

The problem that we will encounter here is that with the GUI for Scheduled Tasks we cannot do this. So, the way that I handle this is to create the scheduled task and then execute the following script that will export the task to an XML file, delete the original task, modify the XML file, and then re-create the task with the XML file.

Update-ScheduledTask -Name <ScheduledTask>

This will execute the supplied script and pass whatever event log entries that we are watching for to it. Then we can add parameters to that script to accept the LogName and Index parameters and run the follow to grab the full event log entry and parse the interesting information from it and take an action:


Get-EventLog – LogName ${LogName} -Index ${Index}

view raw

Get-EventLog

hosted with ❤ by GitHub


Get-EventLog -LogName ${LogName} -Index ${Index}

After which, we could send an email.

Alternatively, one could create a monitoring pack in SCOM or other solutions that monitor for such events and define actions within.

While this is a fairly simple set of tasks, together they can be used to create quite sophisticated solutions that make our processes more robust.

SPONSOR: Do you want a simple domain name registration solution without constant up-selling and keeping your data private by not selling it and giving you free WHOIS privacy?  Sign up with Hover and and get $2 off of your first order.  You’ll get a great a great experience and be supporting this site.

Advertisement

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s