Запрос журналов событий Windows с помощью PowerShell

Журнал событий Windows – это важный инструмент для администраторов, позволяющий отслеживать ошибки, предупреждения и другие информационные сообщения, которые регистрируются операционной системой, ее компонентами или программами. Вы можете использовать графическую оснастку MMC Event Viewer (eventvwr.msc) для просмотра журнала событий Windows. В некоторых случаях гораздо удобнее использовать PowerShell для разбора и анализа информации из журналов событий. В этой статье вы узнаете, как использовать Get-WinEvent Команда для получения информации из журналов событий Windows.

В настоящее время в Windows доступны две команды для доступа к записям журнала событий: Get-EventLog и Get-WinEvent. Мы рекомендуем использовать Get-WinEvent в большинстве случаев, так как она более продуктивна, особенно в сценариях, где необходимо обрабатывать большое количество событий с удаленных компьютеров. Команда Get-EventLog устарела и использовалась для получения журналов в ранних версиях Windows. Кроме того, Get-EventLog не поддерживается в последних версиях PowerShell Core 7.x.

Get-WinEvent: Поиск в журналах событий с помощью PowerShell

Чтобы использовать команду Get-WinEvent, необходимо запустить PowerShell от имени администратора. Если вы попытаетесь запустить Get-WinEvent от имени пользователя, не являющегося администратором, вы не сможете получить доступ к некоторым журналам, включая журналы безопасности.

Чтобы получить список событий из определенного журнала, необходимо указать его имя. Например, следующая команда выводит список последних 20 событий из журнала System:

Get-WinEvent -LogName Application -MaxEvents 20

Наиболее часто запрашиваются журналы System, Application, Security или Setup. Можно указать и другие имена журналов. Полный список журналов событий в Windows можно получить с помощью команды:

Get-WinEvent -ListLog *

Поиск в журнале событий с помощью Get-WinEventПоиск в журнале событий с помощью Get-WinEvent

Например, чтобы просмотреть историю RDP-соединений на компьютере, необходимо указать параметр Microsoft-Windows-TerminalServices-RemoteConnectionManager/Operational log:

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
get-winevent format-tableget-winevent format-table

Данные, полученные из журнала событий, можно обрабатывать и дальше. В этом примере мы сразу преобразуем имя пользователя в SID:

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

Быстрый поиск событий с помощью опции FilterHashtable

Приведенный выше метод фильтрации определенных событий из журналов Event Viewer с помощью Where-Object может быть прост для понимания, но он чрезвычайно медленный, особенно если вы хотите выполнить поиск по большому количеству событий. В большинстве случаев лучше использовать фильтрацию на стороне сервера Event Viewer с помощью опции FilterHashtable вариант.

Теперь попробуем сгенерировать список ошибок и предупреждений за 30-дневный период с помощью Where-Object и FilterHashtable. Для этого мы воспользуемся Measure-Command для сравнения времени выполнения этих двух команд PowerShell:

$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 секунды против 76 сек).

Быстрый поиск в журнале событий в PowerShell с помощью FilterHashtable Быстрый поиск в журнале событий в PowerShell с помощью FilterHashtable

Если вам нужно найти события по EventID, используйте следующую команду с параметром FilterHashtable:

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

В этом примере мы получили последние события перезагрузки и выключения Windows, что позволяет нам определить, кто перезагружал или выключал машину Windows.

Аргумент FilterHashtable позволяет фильтровать по следующим атрибутам событий:

  • LogName
  • ProviderName
  • Путь
  • Ключевые слова (использовать 9007199254740992 для поиска успешных событий и 4503599627370496 для неудачных)
  • ID
  • Уровень (1=FATAL, 2=ERROR, 3=Warning, 4=Information, 5=DEBUG, 6=TRACE, 0=Info)
  • StartTime
  • EndTime
  • UserID (SID пользователя)
  • Данные

Вот пример поиска события за определенный период времени:

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 с помощью FilterHashtable  Get-WinEvent запросы с помощью FilterHashtable

Расширенная фильтрация Get-WinEvent с помощью FilterXml

Фильтры Get-WinEvent с опцией FilterHashtable имеют некоторые ограничения. Если вам нужно использовать сложные запросы с большим количеством критериев для отбора событий, вам нужно использовать опцию FilterXml флаг, который позволяет сделать выборку с помощью XML-запроса. Как и FilterHashtable, фильтры FilterXml работают на стороне сервера. Это означает, что вы получите результат довольно быстро.

Например, вот еще один способ получить последние ошибки из системного журнала за последние 30 дней:

$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

Использование параметра FilterXml с Get-WinEvent Использование опции FilterXml в Get-WinEvent

Чтобы сгенерировать сложный XML-код запроса, можно воспользоваться графической консолью Event Viewer:

  1. Выполните команду eventvwr.msc ;
  2. Найдите журнал, для которого вы хотите создать запрос, и нажмите кнопку Фильтр текущего журнала; Фильтр текущего журнала в средстве просмотра событийФильтр текущего журнала в средстве просмотра событий
  3. Выберите необходимые параметры запроса в форме фильтра. В этом примере я хочу найти события с определенными идентификаторами EventID за последние 7 дней для конкретного пользователя; Фильтр журнала событий по идентификатору события и имени пользователяФильтр журнала событий по идентификатору события и имени пользователя
  4. Чтобы получить код XML-запроса, перейдите на вкладку XML и скопируйте код XPath (CTRL+A, CTRL+C);Копирование XPath для запроса поиска событий Копирование XPath для запроса поиска событий
  5. При необходимости вы можете отредактировать этот запрос вручную.

Чтобы экспортировать список событий в CSV-файл, используйте команду Export-CSV:

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

Получение журналов событий с удаленных компьютеров

Чтобы получить события с удаленного компьютера, просто укажите его имя в поле -ComputerName параметр:

$computer="mun-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.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}
}

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *