<img height="1" width="1" style="display:none" src="https://www.facebook.com/tr?id=1678611822423757&amp;ev=PageView&amp;noscript=1">
Defrag This

| Read. Reflect. Reboot.

Use PowerShell to Automate Log Reviews

Adam Bertram| September 30 2016

| monitoring

Computer data code screen with magnifying glass icon

When an operating system crashes, a server stops responding to ping, or a simple PowerShell DSC configuration needs to be debugged, where's the first place a sysadmin goes? The event log. The Windows event log records a wealth of information. Let's see how we can automate log reviews.

On a typical Windows server, you'll find dozens of event logs recording events of all shapes and sizes. Having this kind of information is valuable, but it's only as useful as the ability to parse through it and find actionable information. We have the tried-and-true event viewer that's been around for a long time that allows you to sift through all of these events. It even has an excellent filtering option for each log.

event log

This is fine if you're working on a single machine, but many sysadmins don't have that luxury. Also, a sysadmin might simply need all events from a particular timeframe from all event logs. At this point, the usefulness of the event viewer starts to erode. You need to build some kind of automation tool around this. In this article, we'll cover how to use PowerShell to create such a tool.

For this tool, I'd like to build something that I can point at one or more servers and that either finds all events in all event logs matching a particular event ID or all events in all event logs in a specific time window. Both of these requirements are great use-cases for troubleshooting purposes.

Let's first build a tool to automate log reviews of the event logs on multiple servers. We'll then build upon this and add more functionality as we go along.

function Find-TroubleshootingEvent
{
[OutputType()]
[CmdletBinding()]
param
(
[Parameter()]
[ValidateNotNullOrEmpty()]
[string[]]$ComputerName = (hostname)
)
try
{
@($ComputerName).foreach({
$getEventParams = @{
ComputerName = $_
}
$logNames = @(Get-WinEvent @getEventParams -ListLog *).where({ $_.RecordCount }).LogName
Write-Verbose -Message "Found log names: [$($logNames -join ',')]"
})
}
catch
{
$PSCmdlet.ThrowTerminatingError($_)
}

}

PS> Find-TroubleshootingEvent

powershell

You can see the output is ugly, but it is, in fact, reading all of the event logs on my local machine. Let's now add the ability to find specific event IDs by adding this criterion to Get-WinEvent's FilterHashTable parameter. This requires adding another parameter called EventId so we can optionally limit results by event ID and including the logic in the function to add this criterion to the FilterHashTable if necessary.

We will add this parameter:

[Parameter()]
[ValidateNotNullOrEmpty()]
[int]$EventId

…and add the logic to check for the parameter EventId:

if ($PSBoundParameters.ContainsKey('EventId'))
{
$filterHashTable.Id = $EventId
}

Now when Get-WinEvent runs, it's going to also include the event ID as criteria and limit results to that. Below you can see that I can specify the event ID and only get events from all event logs that contain that specific ID.

PS> Find-TroubleshootingEvent –EventId 7040

powershell

This is a great start but what if we have multiple servers that we need to scour? Let's add a few of them in the query. To do that is easy. Simply use the ComputerName parameter and specify multiple comma-separated names.

PS> Find-TroubleshootingEvent –EventId 7040 –ComputerName 'MEMBERSRV1','LABSQL'

This works fine, but now we can't tell what server the result came from. Let's change that and add a ServerName property to the output. I'll do this by using calculated properties with Select-Object.

$selectProperties = @('*',@{Name = 'ServerName'; Expression = {$computer}})
Get-WinEvent @getEventParams -FilterHashTable $filterHashTable | Select-Object -Property $selectProperties

PS> Find-TroubleshootingEvent –EventId 7040 –ComputerName 'MEMBERSRV1','LABSQL' | Format-Table –Property ServerName,Id,Message -AutoSize

powershell

I had to pass the results to Format-Table this time in order to get a decent-looking output. This is because PowerShell understands the default output of Get-WinEvent and applies its own formatting, but since this is a new object, we had to add our own rudimentary formatting.

If you liked this approach, you can download this script from Github. To learn more about PowerShell and building a tool like we have here, check out Understanding PowerShell Toolmaking.

 

Related Articles

WUG Ninja: Why Disable an Interface Active Monitor?

Free Network Monitoring Tools

How Web Automation Helped Zgrum Medical Free Up Time

Topics: monitoring

Leave a Reply

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

THIS POST WAS WRITTEN BY Adam Bertram

Adam Bertram is a 20-year veteran of IT. He’s currently an automation engineer, blogger, independent consultant, freelance writer, author, and trainer. Adam focuses on DevOps, system management, and automation technologies as well as various cloud platforms. He is a Microsoft Cloud and Datacenter Management MVP and efficiency nerd that enjoys teaching others a better way to leverage automation.

Free Trials

Getting started has never been easier. Download a trial today.

Download Free Trials

Contact Us

Let us know how we can help you. Focus on what matters. 

Send us a note

Subscribe to our Blog

Let’s stay in touch! Register to receive our blog updates.