Поиск компьютеров с ожидающей перезагрузкой через PowerShell

Установили патч, поменяли системный файл — и Windows говорит «нужна перезагрузка». Когда машин десятки или сотни, обходить каждую вручную нет никакого смысла. Расскажу, как с помощью PowerShell за несколько минут найти все компьютеры, ожидающие перезагрузки, — хоть один хост, хоть весь домен целиком.
Почему компьютер «застревает» в ожидании перезагрузки
Windows фиксирует состояние «pending reboot» сразу в нескольких ветках реестра. Откуда берётся этот флаг? Причин несколько:
- Обновления Windows Update — патч скачан и применён, но ядро или системные DLL физически заменятся только после перезапуска.
- Component-Based Servicing (CBS) — установка ролей и компонентов через DISM или Server Manager всегда проходит через CBS, и он умеет откладывать финальный шаг до рестарта.
- Переименование компьютера или ввод в домен — новое имя появится в сети только после перезагрузки, никак иначе.
- Операции переименования файлов (PendingFileRenameOperations) — установщики MSI сплошь и рядом блокируют файлы в момент инсталляции и регистрируют их замену при следующем старте системы.
- SCCM / Configuration Manager — агент CM выставляет собственный флаг перезагрузки, независимо от всех остальных механизмов.
Машина, которая неделями висит в состоянии «pending reboot», — это головная боль. Новые патчи на неё могут просто не встать, а приложения начинают вести себя странно: частично обновлённые библиотеки дают о себе знать в самый неподходящий момент.
Ключи реестра, отвечающие за ожидание перезагрузки
Прежде чем писать скрипты, полезно понять, что именно мы проверяем. Windows хранит флаги в конкретных ветках реестра:
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending— сам факт существования этого ключа говорит о том, что CBS ждёт перезагрузки.HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired— Windows Update явно требует рестарта.HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\PendingFileRenameOperations— очередь файлов, которые нужно переименовать или удалить прямо при загрузке.HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\PostRebootReporting— дополнительный флаг: система ещё не отправила отчёт о результатах последней перезагрузки.HKLM\SYSTEM\CurrentControlSet\Control\ComputerName\ActiveComputerNamevsComputerName— если значения расходятся, перезагрузка обязательна.
PendingFileRenameOperations не всегда означает критическое ожидание — некоторые приложения оставляют там записи при обычной работе. Анализируйте значение ключа, а не только его существование.Быстрая проверка одного компьютера через реестр
Для разовой диагностики — локальной или на удалённом хосте — хватит буквально нескольких команд:
# Проверка флага Windows Update
Get-Item 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired' `
-ErrorAction SilentlyContinue
# Проверка CBS
Get-Item 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending' `
-ErrorAction SilentlyContinue
# Проверка отложенных переименований файлов
$pfro = Get-ItemProperty 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager' `
-Name PendingFileRenameOperations -ErrorAction SilentlyContinue
if ($pfro) { $pfro.PendingFileRenameOperations }
Получили вывод — машина ждёт перезагрузки. Пусто — флагов нет, всё чисто.
Установка и использование модуля PendingReboot
Для регулярной работы удобнее взять готовый модуль из PowerShell Gallery. Он собирает все проверки в одну команду — не нужно держать в голове пять разных веток реестра:
# Установка модуля (требуется PowerShell 5.0+)
Install-Module -Name PendingReboot -Scope CurrentUser -Force
# Базовая проверка текущего компьютера
Test-PendingReboot
# Детальный вывод с указанием причины
Test-PendingReboot -Detailed
Флаг -Detailed даёт расклад по каждому источнику отдельно — булевые значения, всё наглядно:
ComputerName : WS-FINANCE-01
ComponentBasedServicing: True
WindowsUpdate : False
PendingComputerRename : False
PendingFileRenameOps : False
IsRebootPending : True
Import-Module.Удалённая проверка через Invoke-Command
Модуль PendingReboot умеет работать с удалёнными машинами через PowerShell Remoting (WinRM). Сначала убедитесь, что WinRM поднят на целевых хостах:
# Включить WinRM на удалённой машине через GPO или вручную
Enable-PSRemoting -Force
# Проверить один удалённый хост
Invoke-Command -ComputerName SRV-APP01 -ScriptBlock {
Import-Module PendingReboot
Test-PendingReboot -Detailed
}
# Проверить список хостов
$servers = 'SRV-DC01','SRV-DC02','SRV-FS01','SRV-APP01'
Invoke-Command -ComputerName $servers -ScriptBlock {
Import-Module PendingReboot
Test-PendingReboot
} | Select-Object PSComputerName, IsRebootPending | Sort-Object IsRebootPending -Descending
-Credential.Скрипт для массового аудита всего домена
Скрипт ниже сам забирает список компьютеров из Active Directory и проверяет каждый через удалённый реестр. Никаких модулей на целевых машинах устанавливать не нужно:
# Получаем все активные компьютеры Windows из AD
Import-Module ActiveDirectory
$computers = Get-ADComputer -Filter {
OperatingSystem -like '*Windows*' -and Enabled -eq $true
} -Properties Name | Select-Object -ExpandProperty Name
$results = foreach ($pc in $computers) {
$reboot = $false
$reason = @()
try {
$reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey(
'LocalMachine', $pc)
# Windows Update
$wu = $reg.OpenSubKey(
'SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired')
if ($wu) { $reboot = $true; $reason += 'WindowsUpdate' }
# CBS
$cbs = $reg.OpenSubKey(
'SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending')
if ($cbs) { $reboot = $true; $reason += 'CBS' }
# PendingFileRenameOperations
$sm = $reg.OpenSubKey('SYSTEM\CurrentControlSet\Control\Session Manager')
if ($sm) {
$pfro = $sm.GetValue('PendingFileRenameOperations')
if ($pfro) { $reboot = $true; $reason += 'PendingFileRename' }
}
$reg.Close()
} catch {
$reason += "ERROR: $($_.Exception.Message)"
}
[PSCustomObject]@{
ComputerName = $pc
RebootPending = $reboot
Reason = ($reason -join ', ')
}
}
# Вывод только тех, кто ожидает перезагрузки
$results | Where-Object { $_.RebootPending } |
Format-Table -AutoSize
# Экспорт полного отчёта в CSV
$results | Export-Csv -Path 'C:\Reports\PendingReboot.csv' -Encoding UTF8 -NoTypeInformation
Write-Host "Отчёт сохранён: C:\Reports\PendingReboot.csv"
Принудительная перезагрузка «зависших» машин
Список готов. Теперь можно либо запланировать перезагрузку на ночное окно, либо дать команду немедленно:
# Перезагрузить один компьютер с задержкой 60 секунд
Restart-Computer -ComputerName SRV-APP01 -Wait -Delay 60 -Force
# Перезагрузить список компьютеров
$pendingList = @('SRV-FS01','WS-FINANCE-01','WS-HR-05')
Restart-Computer -ComputerName $pendingList -Force -Wait
# Запланировать перезагрузку через shutdown.exe (поддерживается без WinRM)
foreach ($pc in $pendingList) {
shutdown.exe /m "\\$pc" /r /t 3600 /c "Плановая перезагрузка после обновлений" /f
}
Ключ /t 3600 даёт пользователям час до рестарта — успеют сохраниться. Ключ /f закрывает приложения принудительно. Передумали? Отменить запланированную перезагрузку можно командой shutdown.exe /m \\имя-пк /a.
Мониторинг через Task Scheduler и отчёты на почту
Если нужен регулярный аудит, проще всего поставить скрипт в планировщик и получать отчёт на почту. Вот пример отправки через встроенный SMTP:
# Сохраните скрипт аудита как C:\Scripts\Get-PendingReboot.ps1
# Затем добавьте блок отправки письма в конец:
$html = $results |
Where-Object { $_.RebootPending } |
ConvertTo-Html -Property ComputerName,Reason `
-Title 'Компьютеры, ожидающие перезагрузки' |
Out-String
$mailParams = @{
SmtpServer = 'mail.company.ru'
From = 'monitoring@company.ru'
To = 'admin@company.ru'
Subject = "[$(Get-Date -Format 'dd.MM.yyyy')] Pending Reboot Report"
Body = $html
BodyAsHtml = $true
}
Send-MailMessage @mailParams
# Создать задачу планировщика — запуск каждый понедельник в 08:00
$action = New-ScheduledTaskAction -Execute 'powershell.exe' `
-Argument '-NonInteractive -File C:\Scripts\Get-PendingReboot.ps1'
$trigger = New-ScheduledTaskTrigger -Weekly -DaysOfWeek Monday -At '08:00'
Register-ScheduledTask -TaskName 'PendingRebootAudit' `
-Action $action -Trigger $trigger -RunLevel Highest `
-Description 'Еженедельный аудит компьютеров, ожидающих перезагрузки'
Альтернатива: проверка через SCCM / ConfigMgr
Если в инфраструктуре есть System Center Configuration Manager, статус перезагрузки можно вытащить прямо из консоли или через WMI-запрос к базе ConfigMgr:
# WMI-запрос к локальному агенту SCCM
$ccm = Get-WmiObject -Namespace 'root\CCM\ClientSDK' `
-Class 'CCM_ClientUtilities' -List
$ccm.DetermineIfRebootPending()
# Запрос через CIM (современный вариант)
$pending = Invoke-CimMethod -Namespace 'root\CCM\ClientSDK' `
-ClassName 'CCM_ClientUtilities' `
-MethodName 'DetermineIfRebootPending'
$pending.RebootPending
$pending.IsHardRebootPending
Метод IsHardRebootPending вернёт True, когда ConfigMgr сам инициировал принудительную перезагрузку — например, после установки обязательного приложения или агента Endpoint Protection.
Итог: выстраиваем процесс Patch Management
Разовая проверка закроет накопившиеся хвосты, но без системного подхода они появятся снова. Из того, что реально работает на практике:
- Запускать аудит pending reboot после каждого Patch Tuesday — то есть через 24–48 часов после деплоя обновлений во второй вторник месяца.
- Настроить Maintenance Windows в WSUS или SCCM — тогда рестарт будет происходить автоматически в разрешённое окно, без участия администратора.
- Через GPO можно жёстко задать расписание перезагрузок: Computer Configuration → Administrative Templates → Windows Components → Windows Update → No auto-restart with logged on users — и тогда машины уходят на рестарт ночью, а не в разгар рабочего дня, когда у пользователя открыто двадцать вкладок и несохранённый отчёт.
- Проверку pending reboot мы давно добавили в чек-лист после любых плановых работ. Поставил роль, обновил драйвер, переименовал машину — сразу смотришь статус. Иначе потом часами ищешь, почему что-то работает не так.
- Ведите CSV-журнал с историей: когда машина висела в pending reboot и сколько дней. На практике именно так вычисляются «хронические» хосты — те, которые неделями стоят с незакрытым рестартом и тихо копят проблемы.
Официальная документация: Microsoft Learn — Windows Server, Microsoft Learn — PowerShell
Часто задаваемые вопросы
Что такое Поиск компьютеров с ожидающей перезагрузкой через PowerShell?
Поиск компьютеров с ожидающей перезагрузкой через PowerShell — это важный аспект системного администрирования, который позволяет настроить и оптимизировать работу IT-инфраструктуры. В данной статье подробно рассматриваются все ключевые моменты.
Как правильно настроить Поиск компьютеров с ожидающей перезагрузкой через PowerShell?
Для корректной настройки Поиск компьютеров с ожидающей перезагрузкой через PowerShell необходимо следовать пошаговой инструкции, представленной в статье выше. Важно учитывать особенности вашей инфраструктуры и требования безопасности.
Какие типичные ошибки возникают при работе с Поиск компьютеров с ожидающей перезагрузкой через PowerShell?
Наиболее частые ошибки при работе с Поиск компьютеров с ожидающей перезагрузкой через PowerShell: некорректная конфигурация, недостаточные права доступа и несовместимость версий. Рекомендуем обратиться к специалистам ITFresh для профессиональной настройки.
ООО «АйТи Фреш» возьмёт это на себя
Не хватает времени или своих специалистов — мы настроим, оптимизируем и возьмём вашу IT-инфраструктуру на постоянное сопровождение. Работаем с юридическими лицами в Москве и регионах. Собственный дата-центр, команда из 8 серверов Dell Xeon Platinum 8280 на базе МТС.
Комментарии