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

Сервер перезагрузился ночью — и все молчат. Или совсем плохой вариант: система ушла в ребут посреди рабочего дня, потянув за собой несколько незафиксированных транзакций. Я за 15 лет видел оба сценария десятки раз, и каждый раз первый вопрос одинаковый: кто или что это сделало? Windows хранит ответ в журнале событий — просто большинство администраторов не знают, куда именно смотреть. Разберём все Event ID, которые связаны с перезагрузками, и заодно покажу, как автоматизировать весь этот аудит через PowerShell, чтобы не делать это руками каждый раз.
Таблица Event ID: что означает каждое событие
Журнал System в Windows пишет каждый запуск и каждую остановку ОС. Без исключений. Вот идентификаторы, которые реально нужны:
| Event ID | Источник | Что означает |
|---|---|---|
| 1074 | User32 | Плановая перезагрузка или выключение. Содержит имя пользователя и причину. |
| 6005 | EventLog | Служба журнала событий запущена — система стартовала. |
| 6006 | EventLog | Служба журнала событий остановлена — корректное выключение. |
| 6008 | EventLog | Предыдущее выключение было неожиданным (BSOD, зависание, обрыв питания). |
| 41 | Kernel-Power | Система перезагрузилась без корректного выключения — критическое событие. |
| 1076 | User32 | Пользователь указал причину незапланированного завершения работы. |
Главное правило, которое я всегда объясняю новым коллегам: если после загрузки сервера в журнале есть 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) и причину — если её вообще потрудились указать.
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.
Фильтрация по конкретному инциденту
Клиенты часто спрашивают: как разобрать конкретный инцидент? Например, тот самый неплановый ребут в прошлую пятницу в 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 на базе МТС.
Комментарии