Windows OS Hub
  • Windows Server
    • Windows Server 2022
    • Windows Server 2019
    • Windows Server 2016
    • Windows Server 2012 R2
    • Windows Server 2008 R2
    • SCCM
  • Active Directory
    • Active Directory Domain Services (AD DS)
    • Group Policies
  • Windows Clients
    • Windows 11
    • Windows 10
    • Windows 8
    • Windows 7
    • Windows XP
    • MS Office
    • Outlook
  • Virtualization
    • VMWare
    • Hyper-V
    • KVM
  • PowerShell
  • Exchange
  • Cloud
    • Azure
    • Microsoft 365
    • Office 365
  • Linux
    • CentOS
    • RHEL
    • Ubuntu
  • Home
  • About

Windows OS Hub

  • Windows Server
    • Windows Server 2022
    • Windows Server 2019
    • Windows Server 2016
    • Windows Server 2012 R2
    • Windows Server 2008 R2
    • SCCM
  • Active Directory
    • Active Directory Domain Services (AD DS)
    • Group Policies
  • Windows Clients
    • Windows 11
    • Windows 10
    • Windows 8
    • Windows 7
    • Windows XP
    • MS Office
    • Outlook
  • Virtualization
    • VMWare
    • Hyper-V
    • KVM
  • PowerShell
  • Exchange
  • Cloud
    • Azure
    • Microsoft 365
    • Office 365
  • Linux
    • CentOS
    • RHEL
    • Ubuntu

 Windows OS Hub / PowerShell / Querying Windows Event Logs with PowerShell

May 2, 2023 PowerShellWindows 10Windows 11Windows Server 2019

Querying Windows Event Logs with PowerShell

The Windows Event Log is an important tool for administrators to track errors, warnings, and other information reports that are logged by the operating system, its components, or programs. You can use the Event Viewer graphical MMC snap-in (eventvwr.msc) to view the Windows event log. In some cases, it is much more convenient to use PowerShell to parse and analyze information from the Event Logs. In this article, you’ll learn how to use the Get-WinEvent cmdlet to get information from the Windows event logs.

Contents:
  • Get-WinEvent: Search the Event Logs Using PowerShell
  • Fast Event Search with the FilterHashtable Option
  • Advanced Get-WinEvent Filtering with FilterXml
  • Get Event Logs from Remote Computers

Two cmdlets for accessing event log entries are currently available in Windows: Get-EventLog and Get-WinEvent. We recommend that you use Get-WinEvent in most cases, as it is more productive, especially in scenarios where you need to process a large number of events from remote computers. The Get-EventLog cmdlet is deprecated and was used to get logs in earlier versions of Windows. Also, Get-EventLog is not supported in the latest versions of PowerShell Core 7.x.

Get-WinEvent: Search the Event Logs Using PowerShell

To use the Get-WinEvent command, you must run PowerShell as an administrator. If you try to run Get-WinEvent as a non-admin user, you will not be able to access certain logs, including the Security logs.

To get a list of events from a specific log, you must specify its name. For example, the following command lists the last 20 events from the System log:

Get-WinEvent -LogName Application -MaxEvents 20

System, Application, Security, or Setup logs are the most common logs to query. You can also specify other log names. You can get a full list of event logs in Windows with the command:

Get-WinEvent -ListLog *

Search the event log with Get-WinEvent

For example, to view the RDP connection history on a computer, you must specify the Microsoft-Windows-TerminalServices-RemoteConnectionManager/Operational log:

Get-WinEvent -LogName Microsoft-Windows-TerminalServices-RemoteConnectionManager/Operational

Or you can get the SSH connection logs in Windows from the OpenSSH/Operational log:

Get-WinEvent -LogName OpenSSH/Operational

You can also select events from multiple logs at once. For example, if you want to get information about errors and warnings from System and Application logs for the last 24 hours, use the following code:

$StartDate = (Get-Date) - (New-TimeSpan -Day 1)
Get-WinEvent Application,System | Where-Object {($_.LevelDisplayName -eq "Error" -or $_.LevelDisplayName -eq "Warning") -and ($_.TimeCreated -ge $StartDate )}

filtering event logs with specific date range

You can use the Select-Object or Format-Table cmdlets to display only specific event fields:

Get-WinEvent -LogName System | Format-Table Machinename, TimeCreated, Id, UserID
get-winevent format-table

You can further process data obtained from the event log. In this example, we will immediately convert the username to SID:

Get-WinEvent -filterhash @{Logname = 'system'} |
Select-Object @{Name="Computername";Expression = {$_.machinename}},@{Name="UserName";Expression = {$_.UserId.translate([System.Security.Principal.NTAccount]).value}}, TimeCreated

Fast Event Search with the FilterHashtable Option

The above method of filtering specific events from the Event Viewer logs with Where-Object may be easy to understand, but it is extremely slow, especially if you want to search through a large number of events. In most cases, it’s better to use Event Viewer server-side filtering using the FilterHashtable option.

Now, let’s try to generate a list of errors and warnings over a 30-day period using Where-Object and FilterHashtable. We will then use Measure-Command to compare the execution time of these two PowerShell commands:

$StartDate = (Get-Date).AddDays(-30)

First, we check the execution time of the command with the Where-Object filter:

(Measure-Command {Get-WinEvent Application,System | Where-Object {($_.LevelDisplayName -eq "Error" -or $_.LevelDisplayName -eq "Warning") -and ($_.TimeCreated -ge $StartDate )}}).TotalMilliseconds

The same command with FilterHashtable:

(Measure-Command {Get-WinEvent -FilterHashtable @{LogName = 'System','Application'; Level =2,3; StartTime=$StartDate }}).TotalMilliseconds

This example shows that the FilterHashtable event filtering command is 30 times faster than the usual Where-Object filter ( 2.5 secs vs 76 secs).

Fast event log search in PowerShell with FilterHashtable

If you need to find events by EventID, use the following command with the FilterHashtable parameter:

Get-WinEvent -FilterHashtable @{logname='System';id=1074}|ft TimeCreated,Id,Message

In this example, we have received the latest Windows reboot and shutdown events, allowing us to determine who rebooted or shut down the Windows machine.

The FilterHashtable argument allows you to filter by the following event attributes:

  • LogName
  • ProviderName
  • Path
  • Keywords (use 9007199254740992 to search for successful events and 4503599627370496 for failed ones)
  • ID
  • Level (1=FATAL, 2=ERROR, 3=Warning, 4=Information, 5=DEBUG, 6=TRACE, 0=Info)
  • StartTime
  • EndTime
  • UserID (user’s SID)
  • Data

Here’s an example of searching for an event over a certain period of time:

Get-WinEvent -FilterHashTable @{LogName='System'; StartTime=(get-date).AddDays(-7); EndTime=(get-date).AddHours(-1); ID=1234}

The command below can be used if you want to find specific text in the event description:

Get-WinEvent -FilterHashtable @{logname='System'}|Where {$_.Message -like "*USB*"}

 Get-WinEvent queries with FilterHashtable

Advanced Get-WinEvent Filtering with FilterXml

The Get-WinEvent filters with the FilterHashtable option have some limitations. If you need to use complex queries with many criteria to select events by, you need to use the FilterXml flag, which allows you to make the selection using an XML query. Similar to FilterHashtable, FilterXml filters are server-side. This means you get the result pretty quickly.

For example, here’s another way to get the most recent errors from the System log for the last 30 days:

$xmlQuery = @'
<QueryList>
<Query Id="0" Path="System">
<Select Path="System">*[System[(Level=2 or Level=3) and TimeCreated[timediff(@SystemTime) &lt;= 2592000000]]]</Select>
</Query>
</QueryList>
'@
Get-WinEvent -FilterXML $xmlQuery

Using FilterXml option with Get-WinEvent

To generate a complex XML query code, you can use the Event Viewer graphical console:

  1. Run the command eventvwr.msc ;
  2. Find the log you want to create a query for and click Filter Current Log; Filter current log in Event Viewer
  3. Select the required query parameters in the filter form. In this example, I want to find events with specific EventIDs for the last 7 days for a specific user; Filter event log by event id and username
  4. To get the XML query code, go to the XML tab, and copy the XPath code (CTRL+A, CTRL+C);Copy XPath for event search query
  5. You can edit this query manually if necessary.

To export the list of events to a CSV file, use the Export-CSV cmdlet:

$Events= Get-WinEvent -FilterXML $xmlQuery
$events| Export-CSV "C:\ps\FilterSYSEvents.csv" -NoTypeInformation -Encoding UTF8

Get Event Logs from Remote Computers

To get events from a remote computer, simply specify its name in the -ComputerName parameter:

$computer='mun-dc01'
Get-WinEvent -ComputerName $computer -FilterHashtable @{LogName="System"; StartTime=(get-date).AddHours(-24)} |   select Message,Id,TimeCreated

You can query multiple remote hosts at once to search for specific events. You can get the list of remote computers from a text file:

$servers = Get-Content -Path C:\ps\servers.txt

Or from Active Directory:

$servers = (Get-ADComputer -Filter 'operatingsystem -like "*Windows Server*" -and enabled -eq "true"').Name
foreach ($server in $servers) {
Get-WinEvent -ComputerName $server -MaxEvents 5 -FilterHashtable @{
LogName = 'System'; ID= 1234
} | Select-Object -Property ID, MachineName
}

Here is another example of searching for user account lockout events on all domain controllers:

$Username = 'a.muller'
Get-ADDomainController -fi * | select -exp hostname | % {
$GweParams = @{
'Computername' = $_
'LogName' = 'Security'
'FilterXPath' = "*[System[EventID=4740] and EventData[Data[@Name='TargetUserName']='$Username']]"
}
$Events = Get-WinEvent @GweParams
$Events | foreach {$_.Computer + " " +$_.Properties[1].value + ' ' + $_.TimeCreated}
}

0 comment
0
Facebook Twitter Google + Pinterest
previous post
Configure Windows LAPS (Local Administrator Passwords Solution) in AD
next post
Fix: “Something Went Wrong” Error When Installing Teams

Related Reading

How to Connect VPN Before Windows Logon

November 14, 2023

Using WPAD (Web Proxy Auto-Discovery Protocol) on Windows

November 7, 2023

Send Emails with Microsoft Graph API and PowerShell

November 6, 2023

Zabbix: How to Get Data from PowerShell Scripts

October 27, 2023

Tracking Printer Usage with Windows Event Viewer Logs

October 19, 2023

Leave a Comment Cancel Reply

Categories

  • Active Directory
  • Group Policies
  • Exchange Server
  • Microsoft 365
  • Azure
  • Windows 11
  • Windows 10
  • Windows Server 2022
  • Windows Server 2019
  • Windows Server 2016
  • PowerShell
  • VMWare
  • Hyper-V
  • Linux
  • MS Office

Recent Posts

  • How to Connect VPN Before Windows Logon

    November 14, 2023
  • Removing Azure Arc Setup Feature on Windows Server 2022

    November 9, 2023
  • Using WPAD (Web Proxy Auto-Discovery Protocol) on Windows

    November 7, 2023
  • Send Emails with Microsoft Graph API and PowerShell

    November 6, 2023
  • Zabbix: How to Get Data from PowerShell Scripts

    October 27, 2023
  • Tracking Printer Usage with Windows Event Viewer Logs

    October 19, 2023
  • PowerShell: Configure Certificate-Based Authentication for Exchange Online (Azure)

    October 15, 2023
  • Reset Root Password in VMware ESXi

    October 12, 2023
  • How to Query and Change Teams User Presence Status with PowerShell

    October 8, 2023
  • How to Increase Size of Disk Partition in Ubuntu

    October 5, 2023

Follow us

  • Facebook
  • Twitter
  • Telegram
Popular Posts
  • Fix: Remote Desktop Licensing Mode is not Configured
  • Configuring Port Forwarding in Windows
  • Manage Windows Updates with PSWindowsUpdate PowerShell Module
  • Start Menu or Taskbar Search Not Working in Windows 10/11
  • How to Install Remote Server Administration Tools (RSAT) on Windows
  • How to Delete Old User Profiles in Windows
  • Adding Drivers into VMWare ESXi Installation Image
Footer Logo

@2014 - 2023 - Windows OS Hub. All about operating systems for sysadmins


Back To Top