How to Easily Search Windows Event Logs Across Hundreds of Servers with PowerShell

When troubleshooting problems or investigating potential security breaches, the Windows event log is a great place to start. Windows provides an extensive list of various event logs grouped by a provider with a sometimes staggering number of events recorded within. With all of these events being recorded, it’s hard to figure out what’s going on. One way to search event logs across not one but hundreds of servers at once is with PowerShell.

PowerShell has two main commands that allow you to query event logs called Get-EventLog and Get-WinEvent. In this article, we’re going to be focusing on Get-WinEvent because it supports all types of event logs and has better filtering capabilities.

Querying events from servers is easy with Get-WinEvent. The Get-WinEvent cmdlet has a parameter called ComputerName that allows you to specify a remote server. We’ll also need to provide the name of the event log to query using the LogName parameter. You can see below that the output is grouped by the provider.

We typically don’t want to find all events in a particular log, so we have options to limit that output down. First, we can use the MaxEvents parameter. This does not filter the results but merely limits the number of events returned.

PS> Get-WinEvent -ComputerName SRV1 -LogName System -MaxEvents 1

To narrow down what I’m looking for, one way to filter events with Get-WinEvent is to use the FilterHashTable parameter. This parameter allows you to provide a hashtable as input specifying different attributes to filter events on.

For example, we could filter events by criticality using the Level key inside of the FilterHashTable parameter. In the case below, this query would only return critical and errors only from my SRV2 server.

Get-WinEvent -ComputerName SRV1 -FilterHashtable @{
    LogName = 'System'
    Level = 1,2 # 1 Critical, 2 Error, 3 Warning, 4 Information
}

I can also perform some other common event log queries by finding account lockouts which I know generates an event ID of 4740 in the Security log. Or I could filter on the provider. There are a lot of different ways you can filter event logs.

Get-WinEvent -FilterHashtable @{
    LogName = 'Security'
    ID = 4740
}

Get-WinEvent -FilterHashtable @{
    LogName = 'System'
    ProviderName = 'Microsoft-Windows-GroupPolicy'
}

Now that I have a good idea of how to query events and filter them, let’s expand out to performing queries on multiple computers. To do this, you’ll need to execute the Get-WinEvent command for each remote computer name. We’ll have to create a for each loop to query all of our servers.

Let’s say I have a list of servers in a text file, and I’d like to search for events logs across all of them. To do that, I can use Get-Content to read the text file which will return each server name where I can then pass that name to the ComputerName parameter on Get-WinEvent. The below example will query the System event log returning the first five events on every server that’s defined in the C:\servers.txt text file.

$servers = Get-Content -Path C:\servers.txt
foreach ($server in $servers) {
    Get-WinEvent -ComputerName $server -MaxEvents 5 -FilterHashtable @{
        LogName = 'System'
    }
}

This returns the expected events, but you can’t tell which server the event is coming from. To remedy this, I can ensure that the MachineName property is returned with only the properties I care about. Perhaps I want to see the event ID and the server name. I can limit the output by those properties by using Select-Object.

$servers = Get-Content -Path C:\servers.txt
foreach ($server in $servers) {
    Get-WinEvent -ComputerName $server -MaxEvents 5 -FilterHashtable @{
        LogName = 'System'
    } | Select-Object -Property ID, MachineName
}

   Id   MachineName
   --   -----------
 7036   SRV1.techsnips.local
10016   SRV2.techsnips.local
 7036   SRV3.techsnips.local

You can see that once you’re able to come up with the appropriate filter for a single computer, expanding that to multiple servers is easy with a foreach loop. Once you do this, the only issue you’ll need to address is output and using Select-Object; you can craft any specific property you’d like to see in your final report.

Related Posts

Get Started with WhatsUp Gold

Subscribe to our mailing listGet our latest blog posts delivered in a weekly email.

Leave a Comment

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