· 14 мин чтения

Pending reboot на Windows-серверах: полный аудит через PowerShell

Я Семёнов Евгений Сергеевич, директор АйТи Фреш. За 15+ лет работы с Windows-парками встречал такое регулярно: приезжаешь к клиенту, а там 40 серверов и 23 из них уже две-три недели ждут перезагрузки после обновлений. Пользователи жалуются на тормоза, антивирус «не может обновиться», GPO не применяются — а причина проста: админ ставит патчи, но забывает их «довести» перезагрузкой. В этой статье — как за минуту проверить весь парк на pending reboot, какие ключи реестра смотреть и как правильно выстроить процесс, чтобы серверы перезагружались по плану, а не по настроению.

Что такое pending reboot

Когда Windows устанавливает обновление, драйвер или компонент, часть файлов заменить на лету невозможно — ими пользуется работающий процесс. Система помечает такие операции как «отложенные» и ставит флаг «pending reboot». После перезагрузки при старте Session Manager выполняет MoveFileEx и завершает установку.

Проблема: этот флаг не светится нигде в интерфейсе обычного сервера. Admin Center показывает у себя, SCCM клиент показывает, но на голом Windows Server Core это только в реестре. И если установили 5 апдейтов за месяц и не ребутнули — сервер накапливает технический долг. Каждый следующий патч может сломаться, потому что предыдущий не завершён.

Где Windows хранит флаги pending reboot

ИсточникЧто проверять
Component Based ServicingHKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending
Component Based ServicingHKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootInProgress
Component Based ServicingHKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\PackagesPending
Windows UpdateHKLM:\SOFTWARE\Microsoft\Windows\WindowsUpdate\Auto Update\RebootRequired
Windows UpdateHKLM:\SOFTWARE\Microsoft\Windows\WindowsUpdate\Auto Update\PostRebootReporting
Session ManagerHKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\PendingFileRenameOperations
Computer RenameСравнение ActiveComputerName и ComputerName
SCCM ClientWMI: root\ccm\ClientSDK → CCM_ClientUtilities.DetermineIfRebootPending()

Рабочий скрипт Test-PendingReboot

function Test-PendingReboot {
    [CmdletBinding()]
    param([string]$ComputerName = $env:COMPUTERNAME)

    $sb = {
        $flags = [ordered]@{
            ComputerName = $env:COMPUTERNAME
            CBSRebootPending = $false
            WUARebootRequired = $false
            PendingFileRename = $false
            ComputerRenamePending = $false
            CcmPending = $false
            Summary = $false
        }
        $cbsKey = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending'
        if (Test-Path $cbsKey) { $flags.CBSRebootPending = $true }
        $wuaKey = 'HKLM:\SOFTWARE\Microsoft\Windows\WindowsUpdate\Auto Update\RebootRequired'
        if (Test-Path $wuaKey) { $flags.WUARebootRequired = $true }
        $sm = 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager'
        $pend = Get-ItemProperty -Path $sm -Name PendingFileRenameOperations -ErrorAction SilentlyContinue
        if ($pend.PendingFileRenameOperations) { $flags.PendingFileRename = $true }
        $active = (Get-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\ComputerName\ActiveComputerName').ComputerName
        $current = (Get-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\ComputerName\ComputerName').ComputerName
        if ($active -ne $current) { $flags.ComputerRenamePending = $true }
        try {
            $ccm = Invoke-CimMethod -Namespace 'root/ccm/ClientSDK' `
                -ClassName 'CCM_ClientUtilities' -MethodName 'DetermineIfRebootPending' `
                -ErrorAction Stop
            if ($ccm.RebootPending -or $ccm.IsHardRebootPending) { $flags.CcmPending = $true }
        } catch { }
        $flags.Summary = ($flags.CBSRebootPending -or $flags.WUARebootRequired -or
                          $flags.PendingFileRename -or $flags.ComputerRenamePending -or
                          $flags.CcmPending)
        [pscustomobject]$flags
    }

    if ($ComputerName -eq $env:COMPUTERNAME) {
        & $sb
    } else {
        Invoke-Command -ComputerName $ComputerName -ScriptBlock $sb -ErrorAction Stop
    }
}

# Одиночная проверка
Test-PendingReboot -ComputerName srv-db01

Аудит всего парка за одну команду

$servers = Get-ADComputer -Filter { OperatingSystem -like '*Server*' -and Enabled -eq $true } |
    Select-Object -ExpandProperty DNSHostName

$report = $servers | ForEach-Object -Parallel {
    try { Test-PendingReboot -ComputerName $_ }
    catch { [pscustomobject]@{ ComputerName = $_; Summary = 'Unreachable' } }
} -ThrottleLimit 15 -AsJob | Wait-Job | Receive-Job

$report | Where-Object Summary -eq $true | Sort-Object ComputerName |
    Export-Excel -Path "C:\Scripts\Reports\pending-reboot-$(Get-Date -f yyyyMMdd).xlsx" `
        -AutoSize -TableName Pending -ConditionalText @(
        New-ConditionalText -Text 'True' -ConditionalTextColor 'White' -BackgroundColor '#d97000')

На 50 серверах скрипт отрабатывает за 40–80 секунд благодаря ForEach-Object -Parallel (PowerShell 7+). Для PS 5.1 используйте Start-ThreadJob или модуль PoshRSJob.

Мини-кейс: производство на 180 серверов

В октябре 2025 клиент — металлургический комбинат, инфраструктура из 180 Windows Server разных поколений. WSUS катит обновления автоматом, но перезагрузки не автоматизированы — делают руками по заявкам. В какой-то момент безопасники попросили «показать, где у нас уязвимости не запатчены». Запустили мой скрипт — из 180 машин 52 с pending reboot, 14 из них больше месяца. Четыре сервера — контроллеры домена, которые никто не перезагружал с мая.

Собрали Excel-отчёт, посчитали среднее время с момента первого pending reboot — 11 дней. Согласовали матрицу окон обслуживания (суб-сутки для DC, воскресенье 2:00–4:00 для файловых серверов, отдельные окна для 1С) и написали PowerShell-пайплайн, который по расписанию в окне обслуживания ребутит конкретный набор серверов, дожидается, проверяет сервисы и отправляет отчёт. Серверная плечо автоматизации — виртуалка на Dell с Xeon Platinum 8280 в дата-центре МТС, 40G Mellanox до кластера. За первый месяц работы пайплайна количество серверов с pending reboot упало с 52 до 3. Стоимость проекта 95 тыс. руб.

Автоматическая перезагрузка с проверками

Если решаете автоматизировать перезагрузки — ни в коем случае не просто Restart-Computer. Минимум: проверить сервисы до, поставить ping-мониторинг, проверить сервисы после, отправить отчёт, имейть механизм отката.

function Invoke-SafeReboot {
    param([string]$Server, [string[]]$CriticalServices, [int]$TimeoutMinutes = 15)

    Write-PSFMessage "Reboot $Server started"
    $servicesBefore = Get-Service -ComputerName $Server -Name $CriticalServices |
        Select-Object Name,Status

    Restart-Computer -ComputerName $Server -Force -Wait -For PowerShell `
        -Timeout ($TimeoutMinutes * 60) -Delay 5

    Start-Sleep -Seconds 60   # подождать полной инициализации
    $servicesAfter = Get-Service -ComputerName $Server -Name $CriticalServices |
        Select-Object Name,Status

    $broken = $servicesAfter | Where-Object Status -ne 'Running'
    if ($broken) {
        Write-PSFMessage -Level Warning "After reboot broken on $($Server): $($broken.Name -join ',')"
        return $false
    }
    Write-PSFMessage "Reboot $Server OK, $(($servicesAfter | Where-Object Status -eq 'Running').Count) services up"
    return $true
}

Интеграция с мониторингом

Аудит pending reboot должен быть не разовой командой, а постоянной метрикой. У меня на клиентах обычно это:

# Простой JSON для exporter
$now = Get-Date
$report | ForEach-Object {
    [pscustomobject]@{
        host = $_.ComputerName
        pending = [int]$_.Summary
        age_days = if ($_.Summary) { (New-TimeSpan -Start $_.FirstSeen -End $now).Days } else { 0 }
    }
} | ConvertTo-Json | Out-File C:\metrics\pending_reboot.json -Encoding UTF8

Лучшие практики по перезагрузкам

Наведём порядок с перезагрузками на ваших серверах

Проведу аудит всего парка, покажу, сколько у вас серверов с pending reboot, помогу настроить окна обслуживания и автоматизировать процесс ребутов с проверками и откатом. 15+ лет опыта с Windows-парками до 800 рабочих мест, серверное плечо на Dell Xeon Platinum 8280 в дата-центре МТС на 40G Mellanox.

Телефон: +7 903 729-62-41
Telegram: @ITfresh_Boss
Семёнов Евгений Сергеевич, директор АйТи Фреш

FAQ — частые вопросы по pending reboot

Почему Windows просит перезагрузку?
Причины: установлены обновления CBS, WUA-апдейты ждут, PendingFileRenameOperations в реестре, смена имени компьютера, SCCM/Intune запросил reboot, драйверы обновлены. Windows помечает флаг, приложения должны его проверять.
Какие ключи реестра проверять?
Component Based Servicing/RebootPending и RebootInProgress, WindowsUpdate/Auto Update/RebootRequired, Session Manager/PendingFileRenameOperations, ComputerName/ActiveComputerName vs ComputerName. Полный список у автора PendingReboot модуля на GitHub.
Как проверить через WMI?
На серверах с установленным SCCM-клиентом — через namespace root\ccm\ClientSDK, метод DetermineIfRebootPending(). Без SCCM этот namespace недоступен, используйте реестр.
Как устанавливать обновления и перезагружать автоматически?
PSWindowsUpdate модуль: Install-WindowsUpdate -AcceptAll -AutoReboot. Но на продакшене никогда без окна обслуживания и нескольких слоёв согласований. Лучше WSUS + запланированная перезагрузка через scheduled task.
Как исключить серверы из аудита?
Через группу AD или список exclusion.txt. В скрипте Where-Object { $_.DNSHostName -notin $excluded }. Полезно для серверов, которые физически нельзя перезагрузить часто — 1С, АСУ ТП.

Подпишитесь на рассылку ITfresh

Раз в неделю — практические гайды для руководителя IT и сисадмина: безопасность, 1С, миграции, резервные копии, лайфхаки из реальных проектов.

Реквизиты оператора персональных данных

ООО «АЙТИ-ФРЕШ», ИНН 7719418495, КПП 771901001. Юридический адрес: 105523, г. Москва, Щёлковское шоссе, д. 92, корп. 7. Контакт: info@itfresh.ru, +7 903 729-62-41. Оператор обрабатывает e-mail подписчика в целях рассылки информационных и рекламных материалов до момента отзыва согласия.