Windows Server / AD 24 марта 2026 9 мин чтения ...
ЕС
Евгений Семёнов
Генеральный директор ООО АйТи Фреш · 15+ лет в IT

Анализ журналов событий Windows: поиск ошибок и аудит через PowerShell

windows-event-log-analysis-powershell

Журнал событий Windows — это чёрный ящик. Он пишет всё подряд: входы пользователей, падения служб, перезагрузки, изменения политик, сбои драйверов. Event Viewer справляется, когда нужно глянуть пару записей — открыл, нашёл, закрыл. Но когда перед тобой 80 000 событий за месяц и надо найти конкретную ошибку или собрать аудит — без PowerShell это превращается в пытку. В этой статье разберём, как работать с журналами через Get-WinEvent и Get-EventLog: фильтрация по Event ID, экспорт результатов и построение нормальной системы мониторинга.

Архитектура журналов событий Windows

Windows ведёт сотни журналов одновременно — на типичной Windows 10/11 их больше 1000, на Windows Server ещё больше. Все они лежат в формате .evtx в папке C:\Windows\System32\winevt\Logs, и большинство администраторов никогда не заглядывают дальше трёх-четырёх из них.

На практике администратор работает с несколькими основными журналами:

Совет: чтобы узнать точное количество журналов в вашей системе, выполните Get-WinEvent -ListLog * -Force | Measure-Object. Результат может удивить — в Windows Server 2022 их бывает свыше 1200.

Get-WinEvent vs Get-EventLog: что выбрать

В PowerShell для работы с журналами есть два командлета. Выглядят похоже, но разница между ними принципиальная:

Get-EventLog — старый командлет, работает только с классической тройкой: System, Application, Security. Прост, да, но крепко ограничен. В PowerShell 7+ его уже нет вовсе.

Get-WinEvent — современный инструмент. Читает все журналы без исключения, включая операционные и аналитические, поддерживает FilterHashtable и FilterXPath, умеет работать с .evtx-файлами напрямую. Microsoft рекомендует его для всех новых скриптов — и это не просто слова.

# Get-EventLog — только классические журналы
Get-EventLog -LogName System -Newest 20

# Get-WinEvent — любой журнал, включая операционные
Get-WinEvent -LogName 'Microsoft-Windows-GroupPolicy/Operational' -MaxEvents 20
Внимание: Get-EventLog отсутствует в PowerShell 7 (Core). Если вы переходите на новую версию PowerShell, заменяйте все скрипты на Get-WinEvent.

FilterHashtable: быстрая фильтрация событий

Главная фишка Get-WinEvent — параметр -FilterHashtable. Фильтрация происходит на уровне провайдера, а не в пайплайне, и на больших журналах это даёт кратный прирост скорости. Мы проверяли на журналах по 2–3 гигабайта — разница ощутимая.

# Ошибки в системном журнале за последние 24 часа
Get-WinEvent -FilterHashtable @{
    LogName   = 'System'
    Level     = 2          # 2 = Error
    StartTime = (Get-Date).AddDays(-1)
} | Select-Object TimeCreated, Id, Message | Format-Table -AutoSize

Доступные ключи FilterHashtable:

# Критические ошибки и ошибки из нескольких журналов
Get-WinEvent -FilterHashtable @{
    LogName   = 'System','Application'
    Level     = 1,2
    StartTime = (Get-Date).AddHours(-6)
} | Sort-Object TimeCreated -Descending

Аудит входов: Event ID 4624 и 4625

Журнал Security — главный источник правды об аутентификации. Два Event ID, которые я смотрю в первую очередь при любом инциденте:

# Успешные RDP-входы за последние 7 дней
Get-WinEvent -FilterHashtable @{
    LogName   = 'Security'
    Id        = 4624
    StartTime = (Get-Date).AddDays(-7)
} | ForEach-Object {
    $xml = [xml]$_.ToXml()
    [PSCustomObject]@{
        Time    = $_.TimeCreated
        User    = ($xml.Event.EventData.Data |
                   Where-Object {$_.Name -eq 'TargetUserName'}).'#text'
        IP      = ($xml.Event.EventData.Data |
                   Where-Object {$_.Name -eq 'IpAddress'}).'#text'
        LogonType = ($xml.Event.EventData.Data |
                   Where-Object {$_.Name -eq 'LogonType'}).'#text'
    }
} | Where-Object { $_.LogonType -eq '10' -and $_.User -ne 'ANONYMOUS LOGON' } |
    Sort-Object Time -Descending | Format-Table -AutoSize

Типы входа (LogonType) — без понимания этого поля картина будет неполной:

Совет: для быстрого мониторинга неудачных входов замените Id = 4624 на Id = 4625. Массовые события 4625 с одного IP — признак brute-force атаки.

Мониторинг ошибок служб и драйверов

Журнал System — это где ищешь, когда что-то рухнуло. Службы, драйверы, неожиданные перезагрузки. Вот Event ID, которые реально встречаются в работе:

# Падения служб за последний месяц
Get-WinEvent -FilterHashtable @{
    LogName      = 'System'
    ProviderName = 'Service Control Manager'
    Id           = 7034
    StartTime    = (Get-Date).AddDays(-30)
} | Select-Object TimeCreated, @{
    Name='Service'; Expression={$_.Properties[0].Value}
}, @{
    Name='Crashes'; Expression={$_.Properties[1].Value}
} | Format-Table -AutoSize
# Все неожиданные перезагрузки (Kernel-Power 41)
Get-WinEvent -FilterHashtable @{
    LogName      = 'System'
    ProviderName = 'Microsoft-Windows-Kernel-Power'
    Id           = 41
} | Select-Object TimeCreated, Message

FilterXPath: продвинутая фильтрация

Бывают ситуации, когда FilterHashtable просто не хватает — например, нужно фильтровать по вложенным полям EventData. Вот тут в ход идут XPath-запросы. Синтаксис поначалу выглядит страшно, но зато позволяет добраться до любого поля события.

# Неудачные входы конкретного пользователя
Get-WinEvent -LogName Security -FilterXPath @"
*[System[(EventID=4625)]]
 and
*[EventData[Data[@Name='TargetUserName']='admin']]
"@ -MaxEvents 50 | Select-Object TimeCreated, Message
# Ошибки определённого источника с уровнем Error
Get-WinEvent -LogName Application -FilterXPath @"
*[System[Provider[@Name='MSSQLSERVER'] and (Level=2)]]
"@ -MaxEvents 100
Совет: XPath-фильтры можно тестировать прямо в Event Viewer: вкладка XML в окне фильтра. Скопируйте работающий запрос оттуда в PowerShell.

Работа с архивными .evtx файлами

Get-WinEvent умеет читать архивные файлы .evtx напрямую — и это реально спасает. Когда к нам попадает машина после инцидента или нужно поднять резервную копию логов двухнедельной давности, именно эта возможность позволяет восстановить картину произошедшего без доступа к живой системе.

# Чтение из архивного файла
Get-WinEvent -Path "C:\Backup\System-2026-03.evtx" -FilterHashtable @{
    Id    = 41, 1074, 6008
    Level = 1, 2
} | Select-Object TimeCreated, Id, Message

# Чтение с удалённого компьютера
Get-WinEvent -ComputerName 'SRV-DC01' -FilterHashtable @{
    LogName   = 'Security'
    Id        = 4625
    StartTime = (Get-Date).AddDays(-1)
}

Экспорт и автоматизация: CSV, HTML, Email

Найденные события экспортируем в CSV или XML — и руководство получает читаемый отчёт, а не скриншоты консоли.

# Экспорт ошибок в CSV
Get-WinEvent -FilterHashtable @{
    LogName   = 'System'
    Level     = 1,2
    StartTime = (Get-Date).AddDays(-7)
} | Select-Object TimeCreated, Id, ProviderName, Message |
    Export-Csv -Path "C:\Reports\errors_weekly.csv" -NoTypeInformation -Encoding UTF8
# HTML-отчёт с форматированием
$events = Get-WinEvent -FilterHashtable @{
    LogName   = 'System'
    Level     = 2
    StartTime = (Get-Date).AddDays(-1)
} | Select-Object TimeCreated, Id, ProviderName,
    @{Name='Short'; Expression={$_.Message.Substring(0, [Math]::Min(200, $_.Message.Length))}}

$events | ConvertTo-Html -Title "System Errors Report" -CssUri "style.css" |
    Out-File "C:\Reports\daily_errors.html"
Внимание: при экспорте больших объёмов данных добавляйте -MaxEvents или сужайте временной диапазон. Запрос без ограничений к журналу Security на контроллере домена может занять десятки минут и потребить гигабайты памяти.

Очистка журналов: wevtutil и Clear-EventLog

Бывает, что лог надо просто почистить. Классика: какая-то служба словила ошибку и за ночь нагенерила 40 000 одинаковых записей — журнал разросся до неприличных размеров, а найти в нём что-то полезное уже нереально. После устранения причины чистим и работаем дальше.

# Очистить конкретный журнал
Clear-EventLog -LogName Application

# Очистить все классические журналы
Get-EventLog -LogName * | ForEach-Object { Clear-EventLog $_.Log }

# Через wevtutil — с резервным копированием
wevtutil cl System /bu:C:\Backup\System_backup.evtx

# Очистить ВСЕ журналы (включая операционные)
Get-WinEvent -ListLog * -Force | ForEach-Object {
    wevtutil cl $_.LogName
}
Внимание: очистка журнала Security требует привилегий SeSecurityPrivilege. На контроллерах домена выполняйте только с одобрения ИБ-службы, т.к. очистка сама по себе создаёт событие аудита (Event ID 1102).

Диагностика групповых политик через журналы

«Почему так долго грузится рабочий стол?» — этот вопрос в доменных средах слышишь регулярно. Операционный журнал GroupPolicy отвечает на него конкретно: видно, какая именно политика обрабатывается дольше всего и сколько секунд она съедает при входе.

# Время обработки групповых политик
Get-WinEvent -FilterHashtable @{
    LogName = 'Microsoft-Windows-GroupPolicy/Operational'
    Id      = 5312
} | Select-Object TimeCreated, Message | Format-List

# Профиль пользователя — диагностика загрузки
Get-WinEvent -LogName 'Microsoft-Windows-User Profile Service/Operational' |
    Select-Object TimeCreated, Id, Message -First 20

# События Winlogon
Get-WinEvent -LogName 'Microsoft-Windows-Winlogon/Operational' |
    Select-Object TimeCreated, Id, Message -First 20

Готовый скрипт: ежедневный аудит сервера

Теперь собираем всё вместе. Один скрипт — ключевые события, сводка на выходе:

# Daily-Audit.ps1 — ежедневный сбор критических событий
$since = (Get-Date).AddDays(-1)
$report = @()

# Критические ошибки системы
$report += Get-WinEvent -FilterHashtable @{
    LogName='System'; Level=1,2; StartTime=$since
} -ErrorAction SilentlyContinue | Select-Object @{N='Source';E={'System'}},
    TimeCreated, Id, @{N='Info';E={$_.Message.Substring(0,
    [Math]::Min(150,$_.Message.Length))}}

# Неудачные входы
$report += Get-WinEvent -FilterHashtable @{
    LogName='Security'; Id=4625; StartTime=$since
} -ErrorAction SilentlyContinue | Select-Object @{N='Source';E={'Login-Fail'}},
    TimeCreated, Id, @{N='Info';E={$_.Message.Substring(0,
    [Math]::Min(150,$_.Message.Length))}}

# Падения служб
$report += Get-WinEvent -FilterHashtable @{
    LogName='System'; Id=7034; StartTime=$since
} -ErrorAction SilentlyContinue | Select-Object @{N='Source';E={'SvcCrash'}},
    TimeCreated, Id, @{N='Info';E={$_.Properties[0].Value}}

# Результат
$report | Sort-Object TimeCreated -Descending |
    Export-Csv "C:\Reports\daily_audit_$(Get-Date -f 'yyyyMMdd').csv" -NoTypeInformation -Encoding UTF8

Write-Host "Найдено событий: $($report.Count)" -ForegroundColor Cyan
Совет: запустите этот скрипт через Task Scheduler каждое утро в 07:00 и отправляйте CSV на почту администраторам. Так вы узнаете о проблемах раньше, чем позвонят пользователи.

Заключение: от хаоса к контролю

Журналы событий Windows — это, по сути, чёрный ящик вашей инфраструктуры. Почти на любой вопрос «что вообще произошло?» там есть ответ — надо только уметь его достать. Вот что мы вынесли из многолетней практики:

Попробуйте с малого: запустите скрипт ежедневного аудита на одном сервере. Уже через неделю начнёте замечать паттерны, которые раньше просто не видели. А через месяц — ловить себя на том, что проблему удалось закрыть до того, как её заметили пользователи. Это и есть нормальная администраторская работа.

Если инфраструктура большая — смотрите в сторону Windows Event Forwarding (WEF): централизованный сбор журналов с сотен машин на один коллектор. Но это отдельная история, разберём в другой раз.

Официальная документация: Microsoft Learn — Windows Server, Microsoft Learn — PowerShell

Часто задаваемые вопросы

Что такое Анализ журналов событий Windows: поиск ошибок и аудит через PowerShell?

Анализ журналов событий Windows: поиск ошибок и аудит через PowerShell — это важный аспект системного администрирования, который позволяет настроить и оптимизировать работу IT-инфраструктуры. В данной статье подробно рассматриваются все ключевые моменты.

Как правильно настроить Анализ журналов событий Windows: поиск ошибок и аудит через PowerShell?

Для корректной настройки Анализ журналов событий Windows: поиск ошибок и аудит через PowerShell необходимо следовать пошаговой инструкции, представленной в статье выше. Важно учитывать особенности вашей инфраструктуры и требования безопасности.

Какие типичные ошибки возникают при работе с Анализ журналов событий Windows: поиск ошибок и аудит через PowerShell?

Наиболее частые ошибки при работе с Анализ журналов событий Windows: поиск ошибок и аудит через PowerShell: некорректная конфигурация, недостаточные права доступа и несовместимость версий. Рекомендуем обратиться к специалистам ITFresh для профессиональной настройки.

Нужен аудит инфраструктуры?

ООО «Айти Фреш» возьмёт мониторинг на себя

Мы настроим сбор и анализ журналов событий, аудит безопасности, мониторинг критических служб и автоматическое оповещение об инцидентах. Работаем с инфраструктурой любого масштаба — от 5 рабочих станций до кластеров на 500+ серверов.

15+лет опыта
25+клиентов
40Gнаша сеть
24/7поддержка

Комментарии