<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.

How to Search Windows Event Logs Across Hundreds of Servers

Adam Bertram| April 25 2019

| security

how-to-search-windows-event-logs-across-hundreds-of-servers

The Windows event logs are a great place to start when troubleshooting problems or investigating potential security breaches.

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.

PS> Get-WinEvent -ComputerName SRV1 -LogName System

   ProviderName: Microsoft-Windows-NDIS

TimeCreated                     Id LevelDisplayName Message
-----------                     -- ---------------- -------
3/14/2019 9:20:50 AM         10400 Warning          The network interface "Intel(R) PRO/1000 MT Network Connection" has begun resetting.  There will ...
3/14/2019 9:12:16 AM         10400 Warning          The network interface "Intel(R) PRO/1000 MT Network Connection" has begun resetting.  There will ...


   ProviderName: Service Control Manager

TimeCreated                     Id LevelDisplayName Message
-----------                     -- ---------------- -------
3/14/2019 8:08:46 AM          7040 Information      The start type of the Background Intelligent Transfer Service service was changed from auto start...
<SNIP>

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 SRV1 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 foreach 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.

Topics: security

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.