The best place to start when troubleshooting is the Windows event log. The Event Viewer is a great tool for reading event logs, but what if you've got dozens or hundreds of servers you need to check out? In this case, it's time for PowerShell!

By using the Get-WinEvent command in PowerShell, we're able to create a script that queries event logs based on different criteria at once. But let's take some baby steps and first figure out how to query the event log of a single server. To do that, we just run Get-WinEvent and specify the LogName parameter.

Notice in the example below I'm querying the System event log, and I'm optionally using the MaxEvents parameter to return only five entries at the most.

Using the MaxEvents parameter

Using the MaxEvents parameter

This works fine, but I'm querying the local computer I'm running the command on. I need to query a remote computer. To do that, I simply use the ComputerName parameter to specify the name of the remote server I'd like to query. Notice below that I receive the same output, although this time it's coming from the remote computer.

Get-WinEvent -ComputerName SRV2 -LogName System -MaxEvents 5

   ProviderName: Service Control Manager

TimeCreated                     Id LevelDisplayName Message                                                                                
-----------                     -- ---------------- -------                                                                                
7/28/2018 4:47:34 PM          7036 Information      The Windows Biometric Service service entered the stopped state.                       
7/28/2018 4:47:33 PM          7036 Information      The Software Protection service entered the stopped state.                             
7/28/2018 4:47:24 PM          7036 Information      The Windows Azure Guest Agent service entered the running state.                       
7/28/2018 4:47:23 PM          7045 Information      A service was installed in the system....                                              
7/28/2018 4:47:21 PM          7036 Information      The Portable Device Enumerator Service service entered the stopped state.

Usually though, we're looking for events that match specific criteria. I sure wouldn't want all of the events from all of my servers at once! The Get-WinEvent command has a few ways to filter specific events. One of the most common ways is by using the FilterHashTable parameter. This parameter allows you to provide a hash table as input specifying different attributes to filter events on.

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

Get-WinEvent -ComputerName SRV2 -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 provider. You can filter event logs a lot of different ways.

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 cmdlet for each remote computer name. Unfortunately, unlike its cousin Get-EventLog, the Get-WinEvent doesn't have an option to query multiple computers at once. We'll have to create a foreach loop to query all of our servers.

I first need to gather up all of my server names in an array somehow. I could store these server names in a CSV, a simple text file, a database, an Excel spreadsheet, wherever. PowerShell can read them all, but for this demonstration, I'll take the easy route and assume that I have a text file with a single column full of server names.

Get-Content -Path C:\servers.txt

localhost
SRV2

I'm cheating a little bit by throwing localhost in the list, but the names don't matter. Put as many server names as you'd like in there.

Once you have the text file, you'll then read it using Get-Content as I did above and then pass each server name as the value for the parameter ComputerName as shown below.

$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 it returns the MachineName property with only the properties I care about. Perhaps I just want to see the event ID and the server name. I can limit the output to those properties by using Select-Object.

Subscribe to 4sysops newsletter!

$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 MOVEITTRANSFER.techsnips.local
10016 MOVEITTRANSFER.techsnips.local
 7036 MOVEITTRANSFER.techsnips.local
 7036 MOVEITTRANSFER.techsnips.local
10016 MOVEITTRANSFER.techsnips.local
 7036 MOVEITAUTO.techsnips.local    
 7036 MOVEITAUTO.techsnips.local    
 7036 MOVEITAUTO.techsnips.local    
 7036 MOVEITAUTO.techsnips.local    
 7036 MOVEITAUTO.techsnips.local

Using the Get-WinEvent command is a great way to query and filter events on one or multiple Windows servers.

+4
avatar
5 Comments
  1. Just discovered through your article that the Level key accepts multiple values.
    However, sadly it works only on remote computers.

    Thanks for sharing Adam!

    0

  2. Jay 3 years ago

    Hi,

    How can I create a Powershell I can run, that shows which computers both locally and remotely querys userprofile events issue due to files unable to sync? I love to have a script that techs can use.

    Thanks

    0

  3. Darren Turrell 2 years ago

    Thanks Adam, its surprising how often your articles come up when I am looking for answers to tech questions. Thanks for taking the time.

    0

  4. Kevin 1 year ago

    Can someone help me understand how to output the resulting table to a csv or txt? 

    0

    • Marty 2 weeks ago

      Add " | Out-File -FilePath C:\temp\myfilename.csv" to the end of the command

      0

Leave a reply

Please enclose code in pre tags

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

*

© 4sysops 2006 - 2021

CONTACT US

Please ask IT administration questions in the forums. Any other messages are welcome.

Sending

Log in with your credentials

or    

Forgot your details?

Create Account