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

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

windows-server-reboot-audit

Сервер перезагрузился ночью — и все молчат. Или совсем плохой вариант: система ушла в ребут посреди рабочего дня, потянув за собой несколько незафиксированных транзакций. Я за 15 лет видел оба сценария десятки раз, и каждый раз первый вопрос одинаковый: кто или что это сделало? Windows хранит ответ в журнале событий — просто большинство администраторов не знают, куда именно смотреть. Разберём все Event ID, которые связаны с перезагрузками, и заодно покажу, как автоматизировать весь этот аудит через PowerShell, чтобы не делать это руками каждый раз.

Таблица Event ID: что означает каждое событие

Журнал System в Windows пишет каждый запуск и каждую остановку ОС. Без исключений. Вот идентификаторы, которые реально нужны:

Event IDИсточникЧто означает
1074User32Плановая перезагрузка или выключение. Содержит имя пользователя и причину.
6005EventLogСлужба журнала событий запущена — система стартовала.
6006EventLogСлужба журнала событий остановлена — корректное выключение.
6008EventLogПредыдущее выключение было неожиданным (BSOD, зависание, обрыв питания).
41Kernel-PowerСистема перезагрузилась без корректного выключения — критическое событие.
1076User32Пользователь указал причину незапланированного завершения работы.

Главное правило, которое я всегда объясняю новым коллегам: если после загрузки сервера в журнале есть 6008 или Kernel-Power 41 — перезагрузка была аварийной. Только 6005/6006 — плановая, всё в порядке. Event 1074 — вообще удобная вещь, там прямо написано имя пользователя.

Быстрая проверка: кто нажал Restart

Чаще всего картина такая: кто-то из администраторов перезагрузил сервер через GUI или командную строку и «забыл» предупредить. Event ID 1074 решает этот вопрос — имя пользователя прямо в тексте события:

Get-WinEvent -FilterHashtable @{LogName='System'; Id=1074} -MaxEvents 10 |
  Select-Object TimeCreated,
    @{N='User';E={$_.Properties[6].Value}},
    @{N='Process';E={$_.Properties[0].Value}},
    @{N='Reason';E={$_.Properties[2].Value}} |
  Format-Table -AutoSize

В выводе увидите время, пользователя в формате домен\логин, процесс (например C:\Windows\System32\shutdown.exe) и причину — если её вообще потрудились указать.

Совет: Поле Properties[6] содержит UPN пользователя в формате DOMAIN\username. Если там NT AUTHORITY\SYSTEM — перезагрузку инициировала служба или автоматическое обновление.

История всех запусков и остановок сервера

Хотите полную картину — все загрузки, выключения и аварийные ребуты за последние 30 дней одним запросом:

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

Get-WinEvent -FilterHashtable @{
    LogName   = 'System'
    Id        = 1074, 6005, 6006, 6008, 41
    StartTime = $startDate
} | Select-Object TimeCreated, Id,
    @{N='Type';E={
        switch($_.Id){
            1074  {'Плановая перезагрузка'}
            6005  {'Запуск системы'}
            6006  {'Корректное выключение'}
            6008  {'Аварийное выключение'}
            41    {'Kernel-Power: аварийный ребут'}
        }
    }},
    Message |
  Sort-Object TimeCreated |
  Format-Table -AutoSize -Wrap

По этому выводу хронология восстанавливается за пару минут: когда стартовала система, сколько проработала, и были ли вообще внеплановые ребуты на прошлой неделе.

Расследование аварийной перезагрузки: Kernel-Power 41

Event ID 41 от источника Kernel-Power — это то, что никогда не хочется видеть. Означает одно: Windows не успела корректно завершить работу. BSOD, жёсткое зависание, отключение питания, аппаратный сбой — всё это сюда. Смотрим детально:

Get-WinEvent -FilterHashtable @{
    LogName      = 'System'
    ProviderName = 'Microsoft-Windows-Kernel-Power'
    Id           = 41
} -MaxEvents 20 | ForEach-Object {
    $xml = [xml]$_.ToXml()
    [PSCustomObject]@{
        Time       = $_.TimeCreated
        BugCheck   = $xml.Event.EventData.Data |
                     Where-Object {$_.Name -eq 'BugcheckCode'} |
                     Select-Object -ExpandProperty '#text'
        PowerFlag  = $xml.Event.EventData.Data |
                     Where-Object {$_.Name -eq 'SleepInProgress'} |
                     Select-Object -ExpandProperty '#text'
    }
} | Format-Table -AutoSize

Поле BugcheckCode: если значение не 0 — был BSOD, код можно расшифровать в документации Microsoft. Поле SleepInProgress: false означает, что система не находилась в режиме сна — это реальный аварийный сбой, не выход из hibernate.

Важно: Event 41 появляется при следующем запуске системы, а не в момент сбоя. Поэтому его время — это время загрузки после краша, а не сам момент падения.

Фильтрация по конкретному инциденту

Клиенты часто спрашивают: как разобрать конкретный инцидент? Например, тот самый неплановый ребут в прошлую пятницу в 3 ночи:

$incidentStart = [datetime]'2026-03-20 02:00:00'
$incidentEnd   = [datetime]'2026-03-20 06:00:00'

Get-WinEvent -FilterHashtable @{
    LogName   = 'System'
    Id        = 1074, 6005, 6006, 6008, 41
    StartTime = $incidentStart
    EndTime   = $incidentEnd
} | Select-Object TimeCreated, Id, Message |
  Sort-Object TimeCreated |
  Format-List

Аудит нескольких серверов одной командой

В доменной инфраструктуре нужно прокатиться по нескольким серверам сразу. PowerShell Remoting делает это в несколько строк:

$servers = @('DC01', 'DC02', 'FILE-SRV', 'APP-SRV')
$startDate = (Get-Date).AddDays(-7)

$results = Invoke-Command -ComputerName $servers -ScriptBlock {
    param($start)
    Get-WinEvent -FilterHashtable @{
        LogName   = 'System'
        Id        = 1074, 6008, 41
        StartTime = $start
    } -ErrorAction SilentlyContinue |
    Select-Object TimeCreated, Id, Message
} -ArgumentList $startDate

$results |
  Select-Object PSComputerName, TimeCreated, Id, Message |
  Sort-Object PSComputerName, TimeCreated |
  Format-Table -AutoSize
Совет: Добавьте -ThrottleLimit 10 в Invoke-Command при опросе большого количества серверов, чтобы не перегрузить сеть одновременными подключениями.

Настройка автоматических уведомлений о перезагрузках

Хотите письмо каждый раз, когда сервер поднялся после ребута — настройте задачу в Task Scheduler на Event ID 6005. Работает надёжно, проверено годами:

# Создаём действие — отправка письма через PowerShell
$action = New-ScheduledTaskAction -Execute 'powershell.exe' -Argument @'
-NoProfile -WindowStyle Hidden -Command "
  Send-MailMessage -SmtpServer 'mail.company.ru' `
    -From 'monitor@company.ru' `
    -To 'admin@company.ru' `
    -Subject ('Сервер ' + $env:COMPUTERNAME + ' перезагружен: ' + (Get-Date)) `
    -Body 'Сервер был перезагружен. Проверьте журнал событий.'
"
'@

# Триггер — по событию 6005 в журнале System
$trigger = New-ScheduledTaskTrigger -AtStartup

Register-ScheduledTask -TaskName 'RebootNotify' `
  -Action $action -Trigger $trigger `
  -RunLevel Highest -Force

Более взрослый вариант — подписка на события через wevtutil или Windows Event Forwarding с централизованным сбором со всех серверов на один коллектор. Особенно актуально, если серверов больше десяти.

Экспорт истории перезагрузок в CSV

Нужно отчитаться перед руководством или зафиксировать инцидент документально — экспортируем в CSV одной командой:

Get-WinEvent -FilterHashtable @{
    LogName = 'System'
    Id      = 1074, 6005, 6006, 6008, 41
} -MaxEvents 100 | Select-Object TimeCreated, Id,
    @{N='EventType';E={
        switch($_.Id){
            1074 {'Плановая перезагрузка'}
            6005 {'Запуск'}
            6006 {'Выключение'}
            6008 {'Аварийное выключение'}
            41   {'Kernel-Power 41'}
        }
    }},
    @{N='Details';E={$_.Message -replace '\r\n',' '}} |
Export-Csv -Path "C:\Logs\reboot-history-$(Get-Date -Format 'yyyyMMdd').csv" `
  -Encoding UTF8 -NoTypeInformation

Write-Host "Экспортировано в C:\Logs\reboot-history-$(Get-Date -Format 'yyyyMMdd').csv"

Что делать, если журнал очищен

Иногда журнал оказывается пустым. Два варианта: кто-то его намеренно почистил, или размер журнала выставлен слишком маленьким и старые записи затёрты новыми. Очистку журнала Windows тоже фиксирует — Event ID 104 в канале System (источник: Microsoft-Windows-Eventlog).

Get-WinEvent -FilterHashtable @{
    LogName      = 'System'
    ProviderName = 'Microsoft-Windows-Eventlog'
    Id           = 104
} | Select-Object TimeCreated,
    @{N='ClearedBy';E={$_.Properties[0].Value}},
    Message | Format-List

Поле ClearedBy покажет имя того, кто это сделал. Если очистка журналов происходит регулярно — это повод насторожиться. Настройте Windows Event Forwarding и храните события на отдельном коллекторе, куда у рядовых администраторов нет доступа.

Увеличение размера журнала событий

По умолчанию журнал System ограничен 20 МБ. На активном сервере это буквально несколько дней истории. Расширяем через PowerShell:

# Увеличить журнал System до 512 МБ
$log = New-Object System.Diagnostics.Eventing.Reader.EventLogConfiguration('System')
$log.MaximumSizeInBytes = 512MB
$log.SaveChanges()

# Проверить текущий размер
Get-WinEvent -ListLog System | Select-Object LogName, MaximumSizeInBytes, RecordCount

На production-серверах мы обычно ставим от 256 МБ до 1 ГБ. При высокой активности этого хватит на несколько недель — и при следующем инциденте вы не будете смотреть на пустой журнал.

Шпаргалка: все команды в одном месте

# 1. Кто перезагрузил (Event 1074)
Get-WinEvent -FilterHashtable @{LogName='System';Id=1074} -MaxEvents 5 |
  Select-Object TimeCreated, @{N='User';E={$_.Properties[6].Value}}

# 2. Последние 10 событий запуска/остановки
Get-WinEvent -FilterHashtable @{LogName='System';Id=1074,6005,6006,6008,41} -MaxEvents 10 |
  Sort-Object TimeCreated | Format-Table TimeCreated, Id -AutoSize

# 3. Аварийные ребуты (Kernel-Power 41) за 30 дней
Get-WinEvent -FilterHashtable @{LogName='System';Id=41;StartTime=(Get-Date).AddDays(-30)} |
  Select-Object TimeCreated, Message

# 4. Проверить несколько серверов
Invoke-Command -ComputerName DC01,DC02 -ScriptBlock {
    Get-WinEvent -FilterHashtable @{LogName='System';Id=6008,41} -MaxEvents 3 -EA SilentlyContinue
} | Select-Object PSComputerName, TimeCreated, Id

# 5. Кто очистил журнал
Get-WinEvent -FilterHashtable @{LogName='System';Id=104} |
  Select-Object TimeCreated, @{N='By';E={$_.Properties[0].Value}}

Заключение

Аудит перезагрузок — не паранойя. Это базовая гигиена при управлении инфраструктурой. Пять минут на настройку мониторинга однажды сэкономят вам несколько часов расследования в два часа ночи. Начните с малого: добавьте в еженедельный регламент запрос Event ID 6008 и 41 — и прошлая неделя перестанет быть загадкой.

Если инфраструктура серьёзная — идите дальше. Windows Event Forwarding, централизованный лог-сервер, автоматические алерты на критические события. Один день работы инженера, зато потом полная видимость происходящего на всех серверах в реальном времени. На практике это окупается при первом же серьёзном инциденте.

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

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

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

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

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

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

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

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

Нужна помощь специалистов?

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

Не хватает времени или своих специалистов — мы настроим, оптимизируем и возьмём вашу IT-инфраструктуру на постоянное сопровождение. Работаем с юридическими лицами в Москве и регионах. Собственный дата-центр, команда из 8 серверов Dell Xeon Platinum 8280 на базе МТС.

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

Комментарии