Get-WinEvent: повний посібник для сисадміна — IT-Wiki

[IT-FORMAT]
Новий формат бізнесу

» » » Get-WinEvent: читаємо Event Log у PowerShell — правильно і швидко

Get-WinEvent: читаємо Event Log у PowerShell — правильно і швидко

Цикл: IT-Wiki / Атлас команд Windows Переглядів: 2
Перед стартом
  • PowerShell 5.1 або новіший. Get-WinEvent є у Windows Vista/Server 2008 і новіше.
  • Для читання Security-логу потрібні права адміна. Для System/Application — звичайних прав зазвичай досить.
  • Для віддаленої перевірки — -ComputerName + відкриті WMI/WinRM порти.

Get-WinEvent vs Get-EventLog vs wevtutil

  • Get-WinEvent — сучасний, швидкий, бачить усі Application-and-Services Logs (саме там цікаве — GroupPolicy/Operational, PrintService, WMI, SChannel). Стандартний вибір.
  • Get-EventLog — легасі, бачить тільки класичні логи (System/Application/Security). Deprecated у PowerShell 7+.
  • wevtutil qe — cmd-утиліта, працює без PowerShell, швидка, XML-вивід. Корисна для крос-платформених скриптів і коли PowerShell недоступний.

Синтаксис FilterHashtable — ключ до швидкості

Найчастіший anti-pattern початківців:

Get-WinEvent -LogName System | Where-Object {$_.Id -eq 41}

Це читає весь System-лог у пам'ять, потім фільтрує. На сервері з великим логом — 30-60 секунд і гігабайти RAM. Правильно:

Get-WinEvent -FilterHashtable @{LogName='System'; Id=41}

Тут фільтр передається в ядро Event Log API, результат повертається вже відфільтрований — 1-2 секунди на тому ж сервері.

Ключі FilterHashtable:

  • LogName — назва логу (System, Application, Security, або будь-який з повного шляху).
  • ProviderName — джерело події (наприклад Microsoft-Windows-Kernel-Power).
  • Id — Event ID (одне число або масив).
  • Level — рівень: 1=Critical, 2=Error, 3=Warning, 4=Information, 5=Verbose.
  • StartTime / EndTime — часовий діапазон.
  • UserID — SID користувача (для Security-логу).
  • Data — рядок для повнотекстового пошуку всередині EventData.

Сценарій 1. Чому сервер перезавантажився

Задача: вчора вночі сервер перезавантажився. Треба зрозуміти — планове оновлення, BSOD, чи адмін сам?

Get-WinEvent -FilterHashtable @{LogName='System'; Id=41,1074,6006,6008} -MaxEvents 10 | Select TimeCreated, Id, Message

Що показують ці події:

  • 41 (Kernel-Power) — «система була перезавантажена некоректно». BSOD, power loss, hard reset.
  • 1074 (User32) — «користувач або процес ініціював reboot/shutdown». Видно хто і чому (Windows Update, admin, application).
  • 6006 — Event Log зупинився (нормальне відключення).
  • 6008 — попереднє завершення було некоректним (неплановий reboot).

За цими 4 подіями ви 90% випадків одразу розумієте природу reboot.

Сценарій 2. Account lockout forensics

Задача: користувач скаржиться, що «мене заблокувало». Треба знайти, звідки йшли невдалі логіни.

На PDC (де реєструються всі lockout) у Security-лог:

Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4740} -MaxEvents 20 |
    ForEach-Object {
        [PSCustomObject]@{
            Time = $_.TimeCreated
            User = $_.Properties[0].Value
            CallerComputer = $_.Properties[1].Value
        }
    }

Event 4740 — «A user account was locked out». У Properties[1] — ім'я комп'ютера, з якого прийшов останній невдалий логін (і який спричинив lockout).

Далі на цьому комп'ютері:

Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4625; StartTime=(Get-Date).AddMinutes(-30)} |
    Select TimeCreated, @{n='AccountName';e={$_.Properties[5].Value}}, @{n='Source';e={$_.Properties[19].Value}}

Event 4625 — «Failed logon». Звідси видно причину блокування: збережений пароль у scheduled task, RDP-сесія з застарілим паролем, VPN-клієнт, тощо.

Сценарій 3. Падіння застосунку — шукаємо крашдампи

Задача: Outlook падає у випадкових користувачів. Треба зібрати статистику по падіннях за тиждень.

Get-WinEvent -FilterHashtable @{
    LogName='Application';
    ProviderName='Application Error';
    StartTime=(Get-Date).AddDays(-7)
} | Group-Object {($_.Properties[0].Value)} | Sort Count -Descending | Select Count, Name

Групуємо за назвою exe — побачите, яка програма крашиться найчастіше. Якщо Outlook у топі — далі дивимось конкретні повідомлення:

Get-WinEvent -FilterHashtable @{
    LogName='Application';
    ProviderName='Application Error';
    StartTime=(Get-Date).AddDays(-1)
} | Where-Object {$_.Properties[0].Value -eq 'OUTLOOK.EXE'} | Format-List TimeCreated, Message

Сценарій 4. Події конкретної служби — Group Policy, PrintService

Application-and-Services Logs — це сотні окремих логів для кожного компонента. Їхні повні імена містять слеш (Microsoft-Windows-GroupPolicy/Operational).

Get-WinEvent -LogName 'Microsoft-Windows-GroupPolicy/Operational' -MaxEvents 20 | Select TimeCreated, Id, Message

Для пошуку імен логів за ключовим словом:

Get-WinEvent -ListLog '*GroupPolicy*' | Select LogName, RecordCount

Список усіх логів з подіями за останню добу:

Get-WinEvent -ListLog * | Where-Object {$_.RecordCount -gt 0 -and $_.LastWriteTime -gt (Get-Date).AddDays(-1)} | Sort LastWriteTime -Descending

Сценарій 5. Віддалений сервер

Get-WinEvent -FilterHashtable @{LogName='System'; Level=1,2; StartTime=(Get-Date).AddHours(-24)} -ComputerName DC01.corp.local -MaxEvents 30

Рівні 1 і 2 — Critical і Error. Масово за усіма DCs:

$dcs = Get-ADDomainController -Filter * | Select -Expand HostName
foreach ($dc in $dcs) {
    $events = Get-WinEvent -FilterHashtable @{LogName='System'; Level=1,2; StartTime=(Get-Date).AddHours(-24)} -ComputerName $dc -ErrorAction SilentlyContinue
    [PSCustomObject]@{
        DC = $dc
        CritErrorCount = $events.Count
    }
}

Сценарій 6. XPath-фільтр для складних запитів

Коли FilterHashtable замалий (наприклад, шукати подію, де EventData містить конкретний SID), використовуйте XPath через -FilterXPath:

Get-WinEvent -LogName Security -FilterXPath "*[EventData[Data[@Name='SubjectUserName']='ivanov']]" -MaxEvents 50

XPath працює з уподобаною серверу XML-структурою події — дозволяє фільтрувати по будь-якому полю всередині EventData.

Типові пастки

Пастка 1: -FilterHashtable strict про типи

Id=41 — працює. Id='41' (у лапках) — не працює. FilterHashtable пропускає значення в низькорівневе API, типи важливі. Якщо помилка «Parameter set cannot be resolved» — перевіряйте типи всіх значень.

Пастка 2: -MaxEvents на великому часовому діапазоні

Без -MaxEvents команда поверне ВСІ відповідні події. На сервері з мільйонами подій — десятки секунд і гігабайти RAM. Завжди ставте -MaxEvents N, починайте з 100 і збільшуйте за потребою.

Пастка 3: Time zone

TimeCreated повертається у локальному часі сервера. При агрегації з кількох DC у різних timezone — приводьте до UTC: $_.TimeCreated.ToUniversalTime().

Пастка 4: Security-лог тільки для адміна

Без прав адміна на цільовій машині Security-лог читається як «Access denied». Якщо запускаєтесь з непривілейованого облікового запису — отримуєте нічого, навіть не зрозумівши причини.

Коротка пам'ятка

Найчастіше
  • Останні 20 критичних/помилок System за день: Get-WinEvent -FilterHashtable @{LogName='System'; Level=1,2; StartTime=(Get-Date).AddHours(-24)} -MaxEvents 20
  • Reboot-related: -Id 41,1074,6006,6008
  • Account lockout: -Id 4740 у Security на PDC
  • Failed logon: -Id 4625
  • Application crash: -ProviderName 'Application Error'
  • Знайти лог за ключовим словом: Get-WinEvent -ListLog *keyword*
  • Віддалено: додати -ComputerName HOST

Пов'язане

  • ← Назад до Атласу команд Windows.
  • Перевірка служб (попередня спиця) — разом з Get-WinEvent знаходять причину, чому служба впала.
  • Active Directory: розслідування (майбутній цикл) — account lockout, replication errors, DNS-логи для AD.

Event Viewer — для обзору. Get-WinEvent — для роботи. Різниця особливо гостро відчувається, коли логи великі.

  • Коментарі


Привіт, незнайомець
Опитування

Якою програмою обліку ви користуєтесь?