Журнал событий Windows (Event Log) — это важный инструмент, который позволяет администратору отслеживать ошибки, предупреждения и другие информационные сообщения, которые регистрируются операционной системой, ее компонентами и различными программами. Для просмотра журнала событий Windows можно использовать графическую MMC оснастку Event Viewer (
eventvwr.msc
). В некоторых случаях для поиска информации в журналах событий и их анализа гораздо удобнее использовать PowerShell. В этой статье мы покажем, как получать информацию из журналов событий Windows с помощью командлета Get-WinEvent.
Содержание:
- Получение логов Windows с помощью Get-WinEvent
- Get-WinEvent: быстрый поиск в событиях Event Viewer с помощью FilterHashtable
- Расширенный фильтры событий Get-WinEvent с помощью FilterXml
- Получить логи Event Viewer с удаленных компьютеров
На данный момент в Windows доступны два командлета для доступа к событиям в Event Log: Get-EventLog и Get-WinEvent. В подавляющем большинстве случаев рекомендуем использовать именно Get-WinEvent, т.к. он более производителен, особенно в сценариях обработки большого количества событий с удаленных компьютеров. Командлет Get-EventLog является устаревшим и использовался для получения логов в более ранних версиях Windows. Кроме того, Get-EventLog не поддерживается в современных версиях PowerShell Core 7.x.
Получение логов Windows с помощью Get-WinEvent
Для использования команды Get-WinEvent нужно запустить PowerShell с правами администратора (при запуске Get-WinEvent от имени пользователя вы не сможете получить доступ к некоторым логам, например, к Security).
Для получения списка событий из определенного журнала, нужно указать его имя. В данном примере мы выведем последние 20 событий из журнала System:
Get-WinEvent -LogName Application -MaxEvents 20
Чаще всего вам нужно будет получать информацию из журналов System, Application, Security или Setup. Но вы можете указать и другие журналы. Полный список журналов событий в Windows можно получить с помощью команды:
Get-WinEvent -ListLog *
Например, чтобы вывести события RDP подключений к компьютеру, нужно указать лог Microsoft-Windows-TerminalServices-RemoteConnectionManager/Operational:
Get-WinEvent -LogName Microsoft-Windows-TerminalServices-RemoteConnectionManager/Operational
Или получить логи SSH подключений к Windows из журнала OpenSSH/Operational:
Get-WinEvent -LogName OpenSSH/Operational
Можно выбрать события сразу из нескольких журналов. Например, чтобы получить информацию о ошибках и предупреждениях из журналов System и Application за последние 24 часа (сутки), можно использовать такой код:
$StartDate = (Get-Date) - (New-TimeSpan -Day 1)
Get-WinEvent Application,System | Where-Object {($_.LevelDisplayName -eq "Error" -or $_.LevelDisplayName -eq "Warning") -and ($_.TimeCreated -ge $StartDate )}
Чтобы вывести только определенные поля событий, можно использовать Select-Object или Format-Table:
Get-WinEvent -LogName System | Format-Table Machinename, TimeCreated, Id, UserID
Можно выполнить дополнительные преобразования с полученными данными. Например, в этом примере мы сразу преобразуем имя пользователя в SID:
Get-WinEvent -filterhash @{Logname = 'system'} |
Select-Object @{Name="Computername";Expression = {$_.machinename}},@{Name="UserName";Expression = {$_.UserId.translate([System.Security.Principal.NTAccount]).value}}, TimeCreated
Get-WinEvent: быстрый поиск в событиях Event Viewer с помощью FilterHashtable
Рассмотренный выше способ выбора определенных событий из журналов Event Viewer с помощью Select-Object прост для понимая, но выполняется крайне медленно. Это особенно заметно при выборке большого количества событий. В большинстве случаев для выборки событий нужно использовать фильтрацию на стороне службы Event Viewer с помощью параметра FilterHashtable.
Попробуем сформировать список ошибок и предупреждений за 30 дней с помощью Where-Object и FilterHashtable. Сравнима скорость выполнения этих двух команд PowerShell с помощью Measure-Command:
$StartDate = (Get-Date).AddDays(-30)
Проверим скорость выполнения команды с Where-Object:
(Measure-Command {Get-WinEvent Application,System | Where-Object {($_.LevelDisplayName -eq "Error" -or $_.LevelDisplayName -eq "Warning") -and ($_.TimeCreated -ge $StartDate )}}).TotalMilliseconds
Аналогичная команда с FilterHashtable:
(Measure-Command {Get-WinEvent -FilterHashtable @{LogName = 'System','Application'; Level =2,3; StartTime=$StartDate }})..TotalMilliseconds
В данном примере видно, что команда выборки событий через FilterHashtable выполняется в 30 раз быстрее, чем если бы обычный Where-Object (
2.5
сек vs
76
секунд).
Если вам нужно найти события по EventID, используйте следующую команду с FilterHashtable:
Get-WinEvent -FilterHashtable @{logname='System';id=1074}|ft TimeCreated,Id,Message
В параметре FilterHashtable можно использовать фильтры по следующим атрибутам событий:
- LogName
- ProviderName
- Path
- Keywords (для поиска успешных событий нужно использовать значение 9007199254740992 или для неуспешных попыток 4503599627370496)
- ID
- Level (1=FATAL, 2=ERROR, 3=Warning, 4=Information, 5=DEBUG, 6=TRACE, 0=Info)
- StartTime
- EndTime
- UserID (SID пользователя)
- Data
Пример поиска события за определенный промежуток времени:
Get-WinEvent -FilterHashTable @{LogName='System'; StartTime=(get-date).AddDays(-7); EndTime=(get-date).AddHours(-1); ID=1234}
Если нужно найти определенный текст в описании события, можно использовать такую команду:
Get-WinEvent -FilterHashtable @{logname='System'}|Where {$_.Message -like "*USB*"}
Расширенный фильтры событий Get-WinEvent с помощью FilterXml
Фильтры Get-WinEvent с параметром FilterHashtable являются несколько ограниченными. Если вам нужно использовать для выборки событий сложные запросы с множеством условий, нужно использовать параметр FilterXml, который позволяет сформировать запрос на выбор событий в Event Viewer с помощью XML запроса. Как и FilterHashtable, фильтры FilterXml выполняется на стороне сервера, поэтому результат вы получите довольно быстро.
Например, аналогичный запрос для получения последних ошибок из журнала System за последние 30 дней может выглядеть так:
$xmlQuery = @'
<QueryList>
<Query Id="0" Path="System">
<Select Path="System">*[System[(Level=2 or Level=3) and TimeCreated[timediff(@SystemTime) <= 2592000000]]]</Select>
</Query>
</QueryList>
'@
Get-WinEvent -FilterXML $xmlQuery
Для построения кода сложных XML запросов можно использовать графическую консоль Event Viewer:
- Запустите
eventvwr.msc
; - Найдите журнал для которого вы хотите создать и выберите Filter Current Log;
- Выберите необходимые параметры запроса в форме. В этом примере я хочу найти события с определенными EventID за последние 7 дней от определенного пользователя;
- Чтобы получить код XML запроса для параметра FilterXML, перейдите на вкладку XML и скопируйте полученный код (CTRL+A, CTRL+C);
- Если нужно, вы можете вручную отредактировать данный запрос.
Для экспорта списка событий в CSV файл нужно использовать командлет Export-CSV:
$Events= Get-WinEvent -FilterXML $xmlQuery
$events| Export-CSV "C:\ps\FilterSYSEvents.csv" -NoTypeInformation -Encoding UTF8
Получить логи Event Viewer с удаленных компьютеров
Для получения события с удаленного компьютер достаточно указать его имя в параметре -ComputerName:
$computer='msk-dc01'
Get-WinEvent -ComputerName $computer -FilterHashtable @{LogName="System"; StartTime=(get-date).AddHours(-24)} | select Message,Id,TimeCreated
Можно опросить сразу несколько серверов/компьютеров и поискать на них определенные события. Список серверов можно получить из текстового файла:
$servers = Get-Content -Path C:\ps\servers.txt
Или из 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
}
Здесь есть другой пример для поиска событий блокировки учетной записи пользователя на всех контроллерах домена:
$Username = 'a.ivanov'
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}
}
Post Date:
– Last Modified:
In this post, we will explore how to use PowerShell to view event logs. We will use the Get-EventLog
command to accomplish this, listing event types available and then show recent events.
1. List Available Event Log Types
To display all event log types on a system, run Get-EventLog -List
as shown below:
# Get event types PowerShell Get-EventLog -List
This command returns event categories such as System, Security, and Application. You can then specify a particular log type using the -LogName
parameter in subsequent commands.
2. Get Most Recent Events
To retrieve the 100 most recent events from the System log, run the following:
# Get most recent Windows events PowerShell Get-EventLog -LogName System -Newest 100
For a high-level view of frequent errors, group and count the newest 1000 error events from the Application log:
# Get most recent application events by count Get-EventLog -LogName Application -Newest 1000 -EntryType Error | Group-Object -Property Source -NoElement | Sort-Object -Property Count -Descending
This reveals recurring error sources, helping identify persistent issues.
3. Get Events Between Specific Dates
To retrieve critical and error events within a date range, use the Get-WinEvent
cmdlet in a PowerShell script:
param( [DateTime]$StartDate, [DateTime]$EndDate ) # Get all critical and error events from the Windows event logs Get-WinEvent -FilterHashtable @{ LogName = 'System, Application'; Level = 1, 2; StartTime = $StartDate; EndTime = $EndDate }
Replace START_DATE
and END_DATE
with your desired date range:
.\Get-CriticalAndErrorEvents.ps1 -StartDate '2021-01-01' -EndDate '2021-12-31'
This script filters events by:
– Date Range: Defined by your start and end dates
– Log Name: System and Application logs
– Level: Critical (1) and Error (2) events
Using PowerShell to explore and filter event logs offers a powerful way to troubleshoot and monitor system health. These commands and scripts will help you pinpoint issues and understand system behavior more effectively. Hope all this helps!
Every Windows system administrator is probably familiar with the Windows Event Log. Using this cmdlet in PowerShell allows sysadmins to parse lots of events at once across many computers at once. It frees sysadmins up from clicking around in the Event Viewer trying to figure out just the right filter to use and to determine where precisely that critical event is stored. However, Get-EventLog
does have its downfalls which you’ll see.
Not a reader? Watch this related video tutorial!
Not seeing the video? Make sure your ad blocker is disabled.
Listing Event Logs with Get-EventLog
The Get-EventLog
cmdlet is available on all modern versions of Windows PowerShell. At it’s most straightforward use, this cmdlet needs an event log to query which it will then display all events in that event log.
But what if you don’t know the event log name in the first place? In that case, we need to figure out all of the event logs that are available on our local computer. We do that by using the command Get-EventLog -List
.
You can see I’ve got a few event logs on my local system now, but you might be wondering where are the others? There are dozens of other event logs showing up under Applications and Services logs in the Event Viewer. Why aren’t they here?
If you need those events, unfortunately, Get-EventLog
isn’t going to work. Instead, you’ll need to check out Get-WinEvent. The Get-EventLog
cmdlet could be considered a legacy cmdlet at this point, but it’s one I still use frequently simply because it’s just so easy to use.
Querying Events with Get-EventLog
Now that we know all of the events logs available, we can now read events within that event log. Maybe I want to see all events in the Application event log. To get those events, I need to specify the LogName
parameter with Get-EventLog
and the cmdlet will oblige by returning all events in that event log.
By default, you’ll only see six properties in the output:
Index
Time
EntryType
Source
InstanceId
Message
In actuality, Get-EventLog
returns 16 of them. The reason you only see six is due to PowerShell formatting rules which define the output. Below is an example of the actual output found by piping Get-EventLog
to Select-Object
and selecting all of the properties.
Filtering with Get-EventLog
Chances are when looking for events, we don’t need all events. Instead, we only need a few. In that case, we need to filter for particular events. Get-EventLog
has a few different ways to do this. The Get-EventLog
cmdlet can filter based on timestamp, entry type, event ID, message, source, and username. This takes care of the majority of ways to find events.
To demonstrate filtering, perhaps I’m querying for events every so often, and I want to find the ten newest events. In that case, I can use the Newest
parameter and specify how many events I’d like to see. Get-EventLog -LogName Application -Newest 10
will return only the latest ten events.
Perhaps I want to find all events after a particular point in time. For that, we have the After
parameter. The After
parameter takes a date/time, so if I’d like to find only the events within the Application log that happened after 1/26/19 10:17 AM, I could do this Get-EventLog -LogName Application -After '1/26/19 10:17'
. We could also perform the same process but select events that happened before a certain date with, you might have guessed it, the Before
parameter.
The Get-EventLog
has a lot of different ways to filter not including based on a timestamp. We can also filter events based on other attributes like event ID (Instance ID) and message which tend to be common attributes to search on. Maybe I know I’m looking for an event with an ID of 916; we’d pass 916 to the InstanceId
parameter.
PS> Get-EventLog -LogName Application -InstanceId 916
We can combine filters too. Maybe I get a lot of events returned with an ID of 916, but I want those events with the string svchost in the message. In that case, we can add the Message
parameter to Get-EventLog
and specify a wildcard like svchost.
PS> Get-EventLog -LogName Application -InstanceId 916 -Message '*svchost*'
Bonus Script!
Do you need a great example of using Get-EventLog in a real-world script? If so, you’re in luck! Below is an advanced use case of Get-EventLog
you can download and use today!
<#
.SYNOPSIS
This script searches a Windows computer for all event log or text log entries
between a specified start and end time.
.DESCRIPTION
This script enumerates all event logs within a specified timeframe and all text logs
that have a last write time in the timeframe or contains a line that has a date/time
reference within the timeframe. It records this information to a set of files and copies
any interesting log file off for further analysis.
.EXAMPLE
PS> .\Get-EventsFromTimeframe.ps1 -StartTimestamp '01-29-2014 13:25:00' -EndTimeStamp '01-29-2014 13:28:00' -ComputerName COMPUTERNAME
This example finds all event log entries between StartTimestamp and EndTimestamp and any file
with an extension inside the $FileExtension param that either was last written within the timeframe
or contains a line with a date/time reference within the timeframe.
.PARAMETER StartTimestamp
The earliest date/time you'd like to begin searching for events.
.PARAMETER EndTimestamp
The latest date/time you'd like to begin searching for events.
.PARAMETER Computername
The name of the remote (or local) computer you'd like to search on.
.PARAMETER OutputFolderPath
The path of the folder that will contain the text files that will contain the events.
.PARAMETER LogAuditFilPath
The path to the text file that will document the log file, line number and match type
to the logs that were matched.
.PARAMETER EventLogsOnly
Use this switch parameter if you only want to search in the event logs.
.PARAMETER LogFilesOnly
Use this parameter if you only want to search for logs on the file system.
.PARAMETER ExcludeDirectory
If searching on the file system, specify any folder paths you'd like to skip.
.PARAMETER FileExtension
Specify one or more comma-delimited set of file extensions you'd like to search for on the file system.
This defaults to 'log,txt,wer' extensions.
#>
[CmdletBinding(DefaultParameterSetName = 'Neither')]
param (
[Parameter(Mandatory)]
[datetime]$StartTimestamp,
[Parameter(Mandatory)]
[datetime]$EndTimestamp,
[Parameter(ValueFromPipeline,
ValueFromPipelineByPropertyName)]
[string]$ComputerName = 'localhost',
[Parameter()]
[string]$OutputFolderPath = ".\$Computername",
[Parameter(ParameterSetName = 'LogFiles')]
[string]$LogAuditFilePath = "$OutputFolderPath\LogActivity.csv",
[Parameter(ParameterSetName = 'EventLogs')]
[switch]$EventLogsOnly,
[Parameter(ParameterSetName = 'LogFiles')]
[switch]$LogFilesOnly,
[Parameter(ParameterSetName = 'LogFiles')]
[string[]]$ExcludeDirectory,
[Parameter(ParameterSetName = 'LogFiles')]
[string[]]$FileExtension = @('log', 'txt', 'wer')
)
begin {
if (!$EventLogsOnly.IsPresent) {
## Create the local directory where to store any log files that matched the criteria
$LogsFolderPath = "$OutputFolderPath\logs"
if (!(Test-Path $LogsFolderPath)) {
mkdir $LogsFolderPath | Out-Null
}
}
function Add-ToLog($FilePath,$LineText,$LineNumber,$MatchType) {
$Audit = @{
'FilePath' = $FilePath;
'LineText' = $LineText
'LineNumber' = $LineNumber
'MatchType' = $MatchType
}
[pscustomobject]$Audit | Export-Csv -Path $LogAuditFilePath -Append -NoTypeInformation
}
}
process {
## Run only if the user wants to find event log entries
if (!$LogFilesOnly.IsPresent) {
## Find all of the event log names that contain at least 1 event
$Logs = (Get-WinEvent -ListLog * -ComputerName $ComputerName | where { $_.RecordCount }).LogName
$FilterTable = @{
'StartTime' = $StartTimestamp
'EndTime' = $EndTimestamp
'LogName' = $Logs
}
## Find all of the events in all of the event logs that are between the start and ending timestamps
$Events = Get-WinEvent -ComputerName $ComputerName -FilterHashtable $FilterTable -ea 'SilentlyContinue'
Write-Verbose "Found $($Events.Count) total events"
## Convert the properties to something friendlier and append each event into the event log text file
$LogProps = @{ }
[System.Collections.ArrayList]$MyEvents = @()
foreach ($Event in $Events) {
$LogProps.Time = $Event.TimeCreated
$LogProps.Source = $Event.ProviderName
$LogProps.EventId = $Event.Id
if ($Event.Message) {
$LogProps.Message = $Event.Message.Replace("<code>n", '|').Replace("</code>r", '|')
}
$LogProps.EventLog = $Event.LogName
$MyEvents.Add([pscustomobject]$LogProps) | Out-Null
}
$MyEvents | sort Time | Export-Csv -Path "$OutputFolderPath\eventlogs.txt" -Append -NoTypeInformation
}
## Run only if the user wants to find log files
if (!$EventLogsOnly.IsPresent) {
## Enumerate all remote admin shares on the remote computer. I do this instead of enumerating all phyiscal drives because
## the drive may be there and the share may not which means I can't get to the drive anyway.
$Shares = Get-WmiObject -ComputerName $ComputerName -Class Win32_Share | where { $_.Path -match '^\w{1}:\\$' }
[System.Collections.ArrayList]$AccessibleShares = @()
## Ensure I can get to all of the remote admin shares
foreach ($Share in $Shares) {
$Share = "\\$ComputerName\$($Share.Name)"
if (!(Test-Path $Share)) {
Write-Warning "Unable to access the '$Share' share on '$Computername'"
} else {
$AccessibleShares.Add($Share) | Out-Null
}
}
$AllFilesQueryParams = @{
Path = $AccessibleShares
Recurse = $true
Force = $true
ErrorAction = 'SilentlyContinue'
File = $true
}
## Add any directories specified in $ExcludeDirectory param to not search for log files in
if ($ExcludeDirectory) {
$AllFilesQueryParams.ExcludeDirectory = $ExcludeDirectory
}
## Create the crazy regex string that I use to search for a number of different date/time formats.
## This is used in an attempt to search for date/time strings in each text file found
##TODO: Add capability to match on Jan,Feb,Mar,etc
$DateTimeRegex = "($($StartTimestamp.Month)[\\.\-/]?$($StartTimestamp.Day)[\\.\-/]?[\\.\-/]$($StartTimestamp.Year))|($($StartTimestamp.Year)[\\.\-/]?$($StartTimestamp.Month)[\\.\-/]?[\\.\-/]?$($StartTimestamp.Day))"
## Enumerate all files matching the query params that have content
Get-ChildItem @AllFilesQueryParams | where { $_.Length -ne 0 } | foreach {
try {
Write-Verbose "Processing file '$($_.Name)'"
## Record the file if the last write time is within the timeframe. This finds log files that may not record a
## date/time timestamp but may still be involved in whatever event the user is trying to find.
if (($_.LastWriteTime -ge $StartTimestamp) -and ($_.LastWriteTime -le $EndTimestamp)) {
Write-Verbose "Last write time within timeframe for file '$($_.Name)'"
Add-ToLog -FilePath $_.FullName -MatchType 'LastWriteTime'
}
## If the file found matches the set of extensions I'm trying to find and it's actually a plain text file.
## I use the Get-Content to just double-check it's plain text before parsing through it.
if ($FileExtension -contains $_.Extension.Replace('.','') -and !((Get-Content $_.FullName -Encoding Byte -TotalCount 1024) -contains 0)) {
## Check the contents of text file to references to dates in the timeframe
Write-Verbose "Checking log file '$($_.Name)' for date/time match in contents"
$LineMatches = Select-String -Path $_.FullName -Pattern $DateTimeRegex
if ($LineMatches) {
Write-Verbose "Date/time match found in file '$($_.FullName)'"
## Record all of the matching lines to the audit file.
foreach ($Match in $LineMatches) {
Add-ToLog -FilePath $_.FullName -LineNumber $Match.LineNumber -LineText $Match.Line -MatchType 'Contents'
}
## Create the same path to the log file on the remote computer inside the output log directory and
## copy the log file with an event inside the timeframe to that path.
## This will not work if an file path above 255 characters is met.
$Trim = $_.FullName.Replace("\\$Computername\", '')
$Destination = "$OutputFolderPath\$Trim"
if (!(Test-Path $Destination)) {
##TODO: Remove the error action when long path support is implemented
mkdir $Destination -ErrorAction SilentlyContinue | Out-Null
}
Copy-Item -Path $_.FullName -Destination $Destination -ErrorAction SilentlyContinue -Recurse
}
}
} catch {
Write-Warning $_.Exception.Message
}
}
}
}
Summary
The Get-EventLog
cmdlet is a great command to use if you ever find yourself needing to query one of the common event logs quickly. It’s easy to use and provides some basic filtering ability. However, if you need to do any in-depth event log sleuthing, the Get-WinEvent
command will probably work better, but it’s a little harder to use and sometimes requiring knowing syntax like XPath.
The Windows OS is designed to create a record of various system events by writing entries into event logs. Administrators normally access the event logs through the Windows Event Viewer. However, it’s also possible to view logging data through Windows PowerShell.
How does event logging work?
The Windows OS writes errors and other types of events to a collection of log files. Many applications are also designed to write data to the Windows event logs. Windows provides a variety of individual logs, each of which has a dedicated purpose. The core Windows logs include:
- Application. Initially, Windows applications were designed to write application-related logging data to the Application log. Today, this log exists for backward compatibility purposes. Most application specific logging data is now written to the Applications and Services log, which enables individual logs to be created for each application.
- Security. The Security log stores security related events.
- Setup. The Setup log provides information about the OS and patch installation.
- System. The System log contains events related to the OS’s health and functionality.
- Forwarded Events. The Forwarded Events log acts as a repository for events that occurred on a remote computer.
Event Viewer
As previously noted, the Event Viewer is the native graphical tool used to access the Windows event logs, although many third-party tools are also available. The Event Viewer is divided into three main panes. The pane on the left lists the individual event logs and enables you to select the log you want to view. With a log selected, the pane in the upper right portion of the screen lists the events within that log. These events are listed in chronological order but can be sorted based on severity (level), source, event ID or category.
The pane in the lower right portion of the window displays the details of the log entry that is currently selected. For each event, Windows displays the log name, source, event ID, level, user, OpCode, date and time when the event was logged, task category, keyword and user.
Get-WinEvent vs Get-EventLog
PowerShell provides two main cmdlets for accessing the Windows event logs. These cmdlets are Get-WinEvent and Get-EventLog. Both cmdlets can retrieve event log entries from the local computer and remote computers. The most important difference between the two cmdlets is that the Get-WinEvent cmdlet works with the classic event logs that were first introduced in Windows Vista, while the Get-EventLog cmdlet doesn’t.
The Get-WinEvents cmdlet uses the concept of list providers. A list provider is a component that is configured to write logging data to a specific event log. For example, logging data related to the Trusted Platform Module is handled by the TPM list provider, which sends TPM-related logging data to the System log.
You can view the list providers by entering the following command:
Get-WinEvents -ListProvider *
The asterisk functions as a wildcard character, indicating that all list providers should be shown. However, there are dozens of list providers, so it’s usually more practical to specify the name of a list provider — in this case, TPM — or even a partial name. T*, for instance, would list the list providers starting with the letter T. To see the events related to the TPM list provider, use this command:
(Get-WinEvent -ListProvider TPM).Events
Retrieving logging data from a classic log using the Get-WinEvent cmdlet is usually a simpler matter. Just append the name of the log file to the Get-EventLog cmdlet. If you want to see the system events in the System log, for example, you can do so with this command:
Get-EventLog -LogName System
Checking logs on remote machines
If you need to retrieve logging data from a remote computer rather than from the local host, you must incorporate the ComputerName parameter in your command. If, for example, you want to retrieve the contents of the System logs from a remote computer named Server1, you can use this command:
Get-EventLog -LogName System -ComputerName Server1
Similarly, you can use the Get-WinEvent cmdlet to retrieve TPM-related log entries from a remote computer named Server1 by using this command:
(Get-WinEvent -ListProvider TPM -ComputerName Server1).Events
Keep in mind that both commands assume you are able to perform DNS name resolution for the remote computer and that you have permission to access the remote computer’s event logs.
Finding problems on multiple computers
PowerShell makes it relatively easy to retrieve logging data from multiple computers. In fact, the process is nearly identical to that of retrieving logging data from a remote computer. If you’re using the Get-EventLog cmdlet, then you must include the LogName parameter and the ComputerName parameter. If, for example, you want to retrieve the System logs from Server1, Server2 and Server3, use this command:
Get-EventLog -LogName System -ComputerName Server1, Server2, Server3
The Get-WinEvent cmdlet also makes use of the -ComputerName parameter. If you want to retrieve TPM-related log entries from Server1, Server2 and Server3, you can use this command:
(Get-WinEvent -ListProvider TPM -ComputerName Server1, Server2, Server3).Events
Example commands
Regardless of whether you’re retrieving log entries using the Get-EventLog cmdlet or the Get-WinEvent cmdlet, the log files are likely going to contain too much data to look through. You can use PowerShell to filter the event logging data so that only the most relevant events are shown.
You can filter log entries based on a time range, property values — such as event IDs — or even a specific word, such as Active Directory or Group Policy. There are many different ways to filter logging data, but the most common method involves using either the Get-EventLog or the Get-WinEvent cmdlet to retrieve the logging data, and to then treat that data as pipeline input for the Where-Object cmdlet.
The Where-Object cmdlet uses an operator such as equals (-eq), not equal (-ne), greater than (-gt) or less than (-lt) to compare a source parameter against a property parameter.
Suppose you want to find all occurrences of a distributed COM error with an Event ID of 10010 in the system log. The first thing you must do is use the Get-EventLog cmdlet to retrieve the system log. Then use the pipeline to join the Get-Eventlog command to the Where-Object command. You can examine the log entries to find any log entries where the Event ID is equal to 10010. The command for doing so is:
Get-EventLog -LogName System | Where-Object {$_.InstanceID -eq '10010'}
Keep in mind that you can filter based on any available parameter and that wildcard characters are supported.
As an IT professional or a system administrator, I often need to check the event logs for debugging purposes. I used PowerShell to do this. In this tutorial, I will explain how to use PowerShell to query Windows Event Logs effectively.
What are Windows Event Logs?
Windows Event Logs are useful for diagnosing and troubleshooting system and application issues. They record significant occurrences on your computer, such as system errors, security events, and application logs. IT administrators can access and analyze these logs, which can help you identify and resolve issues promptly.
PowerShell provides different ways to interact with Windows Event Logs. It allows you to automate tasks, filter specific events, and generate reports. Unlike the Event Viewer, which is a graphical interface, PowerShell offers command-line access to Windows event logs.
Note: You need administrative privileges depending on the logs you want to access.
Using Get-EventLog
The Get-EventLog
cmdlet is the primary command used to retrieve event logs in PowerShell. Here’s a simple example to get you started:
Get-EventLog -LogName Application -Newest 10
This command retrieves the ten most recent entries from the Application log.
Here is the exact output in the screenshot below after I executed the above PowerShell script.
Check out Retrieve Your Windows Product Key Using PowerShell
Query Specific Event Logs using PowerShell
Now, let me show you how to query specific event logs using PowerShell.
Filtering by Event ID
Event IDs are unique identifiers for specific types of events. You can filter logs by event ID to find particular events. For example, to find events with ID 1000 in the Application log, you can use the cmdlet below.
Get-EventLog -LogName Application -InstanceId 1000
Filtering by Date Range
You can also filter Windows event logs by date range using powerShell. This is particularly useful when you need to investigate events that occurred within a specific timeframe. For example, to find events from the last 24 hours:
Get-EventLog -LogName System -After (Get-Date).AddDays(-1)
Here is the exact output in the screenshot below:
Read Enable WinRM (Windows Remote Management) Using PowerShell
Combine Filters
You can combine multiple filters to narrow down your search. For instance, to find events with ID 4624 (successful logon) in the Security log from the last week, here is the complete cmdlet.
Get-EventLog -LogName Security -InstanceId 4624 -After (Get-Date).AddDays(-7)
Exporting Event Logs
Exporting Windows event logs to a file can be useful for further analysis or archiving. You can export logs to various formats, such as CSV or XML. Here’s how to export logs to a CSV file using the below PowerShell script.
Get-EventLog -LogName Application -Newest 100 | Export-Csv -Path "C:\Logs\ApplicationLogs.csv" -NoTypeInformation
Parsing Event Logs
Sometimes, you need to extract specific information from event logs. PowerShell allows you to parse logs and extract relevant data. For example, to get the message and timestamp of recent errors in the System log:
Get-EventLog -LogName System -EntryType Error -Newest 50 | Select-Object TimeGenerated, Message
Read Get Windows Services Using PowerShell
Monitoring Event Logs in Real-Time
Real-time monitoring of event logs can help you detect and respond to issues as they occur. You can use the -Wait
parameter with the Get-WinEvent
cmdlet to achieve this:
Get-WinEvent -LogName Application -MaxEvents 1 -Wait
This command waits for new events in the Application log and displays them as they occur.
Read Get Windows Activation Status Using PowerShell
Windows Event Logs: Practical Use Cases
Now, let me show you some practical use cases where I have used PowerShell to work with Windows event logs.
Troubleshooting Application Crashes
Suppose you are an IT administrator in New York City, and users report that a critical application is crashing frequently. You can use PowerShell to find relevant events in the Application log:
Get-EventLog -LogName Application -EntryType Error -Newest 100 | Where-Object { $_.Source -eq "YourApplicationName" }
This command filters the 100 most recent error events related to the specified application.
Security Auditing
As a system administrator in Los Angeles, you might need to audit successful and failed logons for security purposes. You can use the following command to retrieve logon events from the Security log:
Get-EventLog -LogName Security -InstanceId 4624, 4625 -After (Get-Date).AddDays(-7)
Event ID 4624 represents successful logons, and 4625 represents failed logons.
Check out Get the Windows Version Using PowerShell
System Health Monitoring
For system health monitoring in a data center in San Francisco, you can use PowerShell to check for critical system events:
Get-EventLog -LogName System -EntryType Error, Warning -Newest 200
This command retrieves the 200 most recent error and warning events from the System log.
Conclusion
You can use PowerShell to query Windows Event Logs to manage and analyze log data. By using cmdlets like Get-EventLog
and Get-WinEvent
, you can get Windows event logs, filter specific events, and generate detailed reports.
In this tutorial, I explained how to get Windows event logs using PowerShell.
You may also like the following tutorials:
- Find Logged In User Using PowerShell
- Enable Remote Desktop Using PowerShell
- Find Installed Software Using PowerShell
- Create a Self-Signed Certificate Using PowerShell
- Create Desktop Shortcuts with Custom Icons Using PowerShell
Bijay Kumar is an esteemed author and the mind behind PowerShellFAQs.com, where he shares his extensive knowledge and expertise in PowerShell, with a particular focus on SharePoint projects. Recognized for his contributions to the tech community, Bijay has been honored with the prestigious Microsoft MVP award. With over 15 years of experience in the software industry, he has a rich professional background, having worked with industry giants such as HP and TCS. His insights and guidance have made him a respected figure in the world of software development and administration. Read more.