---
title: "Test Pending Reboot on Windows Servers with PowerShell"
description: "Use PowerShell to quickly test pending reboot across Windows servers and consolidate steps into one script."
canonical: "https://adamtheautomator.com/pending-reboot-registry/"
---

# Test Pending Reboot on Windows Servers with PowerShell

> Use PowerShell to quickly test pending reboot across Windows servers and consolidate steps into one script.

Source: https://adamtheautomator.com/pending-reboot-registry/

---

ATA Learning

Tap to hide

[

ATA Learning

](/)

*   [Home](/)
*   [Tutorials](/tutorials/)
*   [Instructors](/author/)
*   [Advertising](/advertising/)
*   [Recommended Resources](/resources/)
*   [About Adam](/about-adam/)

Search for:  

*   [](https://twitter.com/adbertram)
*   [](https://github.com/Adam-the-Automator)
*   [](https://www.linkedin.com/company/adam-the-automator-llc)
*   [](/feed/)

![Test Pending Reboot on Windows Servers with PowerShell](https://adamtheautomator.com/wp-content/uploads/2019/07/1-Pending-Restart-GUI-1-1.png)

# Test Pending Reboot on Windows Servers with PowerShell

[![](https://secure.gravatar.com/avatar/d0b9d42e21e5622713f8b693aa5c0f9244d5f7dd200ed29b8398f52dee5de337?s=192&d=mm&r=g)Adam Bertram](https://adamtheautomator.com/author/adam-bertram/)28 July 20197 min. read

Categories: [IT Ops](/category/it-ops/)

Tags:[Microsoft Windows Server](/tag/microsoft-windows-server/)[PowerShell](/tag/powershell/)

Table of Contents

*   [Windows Needs Rebooted](#windows-needs-rebooted)
*   [Pending Reboot Flags are in the Registry](#pending-reboot-flags-are-in-the-registry)
*   [Testing for a a Pending Reboot (The Easy Way)](#testing-for-a-a-pending-reboot-the-easy-way-)
*   [Building a Pending Reboot PowerShell Tool](#building-a-pending-reboot-powershell-tool)
*   [Summary](#summary)

Whenever you install software, updates or make configuration changes, it’s common for Windows to need a reboot. Many OS tasks sometimes force Windows to require a reboot. When a reboot is pending, Windows add some registry values to show that. In this blog post, you’re going to learn how to check for a pending reboot and how to build a [PowerShell script to automate the task](https://adamtheautomator.com/powershell-scheduled-task/).

## Windows Needs Rebooted

When you’re in on the console, you can notice a reboot is pending by some popup box or notification as shown below.

From that notification, you can restart Windows and be done with it. But, what if you can’t immediately reboot a machine when it needs to? What if you’ve just installed updates on a production server and that server can’t be rebooted right now?

![Pending Windows reboot message](https://adamtheautomator.com/content/images/2019/07/1--Pending-Restart-GUI.png)

Pending Windows reboot message

The reboot must wait.

Time goes by and by then the reboot may be forgotten about altogether! By the time you realize, many servers or workstations need to be rebooted but which ones?

## Pending Reboot Flags are in the Registry

A pending reboot is defined in many places. Scroll right to see the values and conditions. A Windows computer is pending a reboot if any of the conditions in this table are true.

<table><tbody><tr><td>Key</td><td>Value</td><td>Condition</td></tr><tr><td>HKLM:\SOFTWARE\Microsoft\Updates</td><td>UpdateExeVolatile</td><td>Value is anything other than 0</td></tr><tr><td>HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager</td><td>PendingFileRenameOperations</td><td>value exists</td></tr><tr><td>HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager</td><td>PendingFileRenameOperations2</td><td>value exists</td></tr><tr><td>HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired</td><td>NA</td><td>key exists</td></tr><tr><td>HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Services\Pending</td><td>NA</td><td>Any GUID subkeys exist</td></tr><tr><td>HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\PostRebootReporting</td><td>NA</td><td>key exists</td></tr><tr><td>HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce</td><td>DVDRebootSignal</td><td>value exists</td></tr><tr><td>HKLM:\Software\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending</td><td>NA</td><td>key exists</td></tr><tr><td>HKLM:\Software\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootInProgress</td><td>NA</td><td>key exists</td></tr><tr><td>HKLM:\Software\Microsoft\Windows\CurrentVersion\Component Based Servicing\PackagesPending</td><td>NA</td><td>key exists</td></tr><tr><td>HKLM:\SOFTWARE\Microsoft\ServerManager\CurrentRebootAttempts</td><td>NA</td><td>key exists</td></tr><tr><td>HKLM:\SYSTEM\CurrentControlSet\Services\Netlogon</td><td>JoinDomain</td><td>value exists</td></tr><tr><td>HKLM:\SYSTEM\CurrentControlSet\Services\Netlogon</td><td>AvoidSpnSet</td><td>value exists</td></tr><tr><td>HKLM:\SYSTEM\CurrentControlSet\Control\ComputerName\ActiveComputerName</td><td>ComputerName</td><td>Value ComputerName in HKLM:\SYSTEM\CurrentControlSet\Control\ComputerName\ComputerName is different</td></tr></tbody></table>

If you have the Microsoft System Center Configuration Manager (SCCM) client installed, you may also see these methods in WMI.

<table><tbody><tr><td>Namespace</td><td>Class</td><td>Property</td><td>Value</td><td>Product</td><td>Notes</td></tr><tr><td>ROOT\ccm\ClientSDK</td><td>CCM_ClientUtilities</td><td>DetermineifRebootPending</td><td>RebootPending</td><td>SCCM</td><td>ReturnValue needs to be 0 and this value is not null</td></tr><tr><td>ROOT\ccm\ClientSDK</td><td>CCM_ClientUtilities</td><td>DetermineifRebootPending</td><td>IsHardRebootPending</td><td>SCCM</td><td>ReturnValue needs to be 0 and this value is not null</td></tr></tbody></table>

Once you know each method to check for a pending reboot, there are many different ways to check registry values. You could open up _regedit.exe_ and manually mouse through each registry key.

![Checking regedit manually](/wp-content/uploads/2019/07/pending-reboot-registry.gif)

Checking regedit manually

Manually checking via the registry works but we’re human. What if you forget to check one registry path or just forget which ones to check? There’s a much better way to do this. You can create a script or function to do this for you. In my case, I prefer PowerShell so that’s what I’ll use.

By using a PowerShell script, you can query one or all computers in our domain or manually provide the server names to see if they are pending a reboot. You can then make a decision to whether to reboot them then or make a list to reboot later. The choice is yours.

To use my PowerShell method, you’ll need to ensure [PowerShell Remoting](https://adamtheautomator.com/psremoting/ "PowerShell Remoting") is set up and available on your servers.

## Testing for a a Pending Reboot (The Easy Way)

If you don’t want to learn how to check these registry keys and build a tool like this in PowerShell, I’ve made it easy for you. Simply open up your PowerShell console and type `Install-Script Test-PendingReboot`. `Install-Script` will download my PowerShell script from the PowerShell Gallery to _C:\\Program Files\\WindowsPowerShell\\Scripts_. Then run the script as shown below.

```powershell
PS51> Test-PendingReboot.ps1 -ComputerName localhost

ComputerName IsPendingReboot
------------ ---------------
localhost              False
```

You can provide as many servers as you want via the `ComputerName` parameter. The script will return _True_ or _False_ along with the server name.

This tool checks all of the registry keys in the above table for you.

> _If you’d like to add conditions I’ve missed or correct any mistakes I’ve made, feel free to issue a [pull request on GitHub](https://github.com/adbertram/Random-PowerShell-Work/blob/master/Random%20Stuff/Test-PendingReboot.ps1) to fix it._

If you want to learn how to build a tool like this, read on!

## Building a Pending Reboot PowerShell Tool

First, you’ll need to define all of the computers you’d like to test a reboot on. There are many different ways to do this but for this demonstration, I’ll define them manually via an array.

```powershell
$servers = 'SRV1','SRV2','SRV3'
```

Now create a _[foreach](https://adamtheautomator.com/powershell-foreach/ "foreach")_ loop to iterate over each of them.

```powershell
foreach ($computer in $ComputerName)

}
```

Next, I recommend using PowerShell Remoting and checking each registry key and value condition inside of a single PSSession. Create a PSSession for every server.

```powershell
foreach ($computer in $ComputerName)
    $session = New-PSSession
}
```

Once you have a PSSession created, you’ll then need to run the checks.

Since you’ll be running many different checks using the same code such as:

*   Testing if a registry key exists
*   Testing if a registry value exists
*   Testing if a registry value is not null

I recommend creating simple functions for each of these checks. This allows you to call a function instead of duplicating code. The `Test-PendingReboot` script builds all of these helper functions into a single scriptblock as shown below.

```powershell
function Test-RegistryKey {
        [OutputType('bool')]
        [CmdletBinding()]
        param
        (
            [Parameter(Mandatory)]
            [ValidateNotNullOrEmpty()]
            [string]$Key
        )
    
        $ErrorActionPreference = 'Stop'

        if (Get-Item -Path $Key -ErrorAction Ignore) {
            $true
        }
    }

    function Test-RegistryValue {
        [OutputType('bool')]
        [CmdletBinding()]
        param
        (
            [Parameter(Mandatory)]
            [ValidateNotNullOrEmpty()]
            [string]$Key,

            [Parameter(Mandatory)]
            [ValidateNotNullOrEmpty()]
            [string]$Value
        )
    
        $ErrorActionPreference = 'Stop'

        if (Get-ItemProperty -Path $Key -Name $Value -ErrorAction Ignore) {
            $true
        }
    }

    function Test-RegistryValueNotNull {
        [OutputType('bool')]
        [CmdletBinding()]
        param
        (
            [Parameter(Mandatory)]
            [ValidateNotNullOrEmpty()]
            [string]$Key,

            [Parameter(Mandatory)]
            [ValidateNotNullOrEmpty()]
            [string]$Value
        )
    
        $ErrorActionPreference = 'Stop'

        if (($regVal = Get-ItemProperty -Path $Key -Name $Value -ErrorAction Ignore) -and $regVal.($Value)) {
            $true
        }
    }
```

Inside of that same scriptblock, define each condition referencing the helper functions you just created.

```powershell
$tests = @(
        { Test-RegistryKey -Key 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending' }
        { Test-RegistryKey -Key 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootInProgress' }
        { Test-RegistryKey -Key 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired' }
        { Test-RegistryKey -Key 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Component Based Servicing\PackagesPending' }
        { Test-RegistryKey -Key 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\PostRebootReporting' }
        { Test-RegistryValueNotNull -Key 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager' -Value 'PendingFileRenameOperations' }
        { Test-RegistryValueNotNull -Key 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager' -Value 'PendingFileRenameOperations2' }
        { 
            # Added test to check first if key exists, using "ErrorAction ignore" will incorrectly return $true
            'HKLM:\SOFTWARE\Microsoft\Updates' | Where-Object { test-path $_ -PathType Container } | ForEach-Object {            
                (Get-ItemProperty -Path $_ -Name 'UpdateExeVolatile' -ErrorAction Ignore | Select-Object -ExpandProperty UpdateExeVolatile) -ne 0 
            }
        }
        { Test-RegistryValue -Key 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce' -Value 'DVDRebootSignal' }
        { Test-RegistryKey -Key 'HKLM:\SOFTWARE\Microsoft\ServerManager\CurrentRebootAttemps' }
        { Test-RegistryValue -Key 'HKLM:\SYSTEM\CurrentControlSet\Services\Netlogon' -Value 'JoinDomain' }
        { Test-RegistryValue -Key 'HKLM:\SYSTEM\CurrentControlSet\Services\Netlogon' -Value 'AvoidSpnSet' }
        {
            # Added test to check first if keys exists, if not each group will return $Null
            # May need to evaluate what it means if one or both of these keys do not exist
            ( 'HKLM:\SYSTEM\CurrentControlSet\Control\ComputerName\ActiveComputerName' | Where-Object { test-path $_ } | %{ (Get-ItemProperty -Path $_ ).ComputerName } ) -ne 
            ( 'HKLM:\SYSTEM\CurrentControlSet\Control\ComputerName\ComputerName' | Where-Object { Test-Path $_ } | %{ (Get-ItemProperty -Path $_ ).ComputerName } )
        }
        {
            # Added test to check first if key exists
            'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Services\Pending' | Where-Object { 
                (Test-Path $_) -and (Get-ChildItem -Path $_) } | ForEach-Object { $true }
        }
    )
```

You can now create a _foreach_ loop inside of your `$servers` _foreach_ loop that reads each test executes each test.

```powershell
foreach ($test in $tests) {
	if (& $test) {
		$true
		break
	}
}
```

When you run the code, the script returns an output like this:

```powershell
ComputerName IsPendingReboot
------------ ---------------
Server1              False
Server2              True
```

You can create this output by ensuring the _foreach_ loop returns a single object per server. You should know that if _any_ of the registry values exist, then the server is pending a reboot. Knowing this, you then need to return _True_ if any of the values exist and _False_ if none of them exist.

Wrap all of this up into a script and it should look like this (with some minor additions like `Credential`).

```powershell
[CmdletBinding()]
param(
    [Parameter(Mandatory)]
    [ValidateNotNullOrEmpty()]
    [string[]]$ComputerName,
	
    [Parameter()]
    [ValidateNotNullOrEmpty()]
    [pscredential]$Credential
)

$ErrorActionPreference = 'Stop'

$scriptBlock = {

    $VerbosePreference = $using:VerbosePreference
    function Test-RegistryKey {
        [OutputType('bool')]
        [CmdletBinding()]
        param
        (
            [Parameter(Mandatory)]
            [ValidateNotNullOrEmpty()]
            [string]$Key
        )
    
        $ErrorActionPreference = 'Stop'

        if (Get-Item -Path $Key -ErrorAction Ignore) {
            $true
        }
    }

    function Test-RegistryValue {
        [OutputType('bool')]
        [CmdletBinding()]
        param
        (
            [Parameter(Mandatory)]
            [ValidateNotNullOrEmpty()]
            [string]$Key,

            [Parameter(Mandatory)]
            [ValidateNotNullOrEmpty()]
            [string]$Value
        )
    
        $ErrorActionPreference = 'Stop'

        if (Get-ItemProperty -Path $Key -Name $Value -ErrorAction Ignore) {
            $true
        }
    }

    function Test-RegistryValueNotNull {
        [OutputType('bool')]
        [CmdletBinding()]
        param
        (
            [Parameter(Mandatory)]
            [ValidateNotNullOrEmpty()]
            [string]$Key,

            [Parameter(Mandatory)]
            [ValidateNotNullOrEmpty()]
            [string]$Value
        )
    
        $ErrorActionPreference = 'Stop'

        if (($regVal = Get-ItemProperty -Path $Key -Name $Value -ErrorAction Ignore) -and $regVal.($Value)) {
            $true
        }
    }

    # Added "test-path" to each test that did not leverage a custom function from above since
    # an exception is thrown when Get-ItemProperty or Get-ChildItem are passed a nonexistant key path
    $tests = @(
        { Test-RegistryKey -Key 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending' }
        { Test-RegistryKey -Key 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootInProgress' }
        { Test-RegistryKey -Key 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired' }
        { Test-RegistryKey -Key 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Component Based Servicing\PackagesPending' }
        { Test-RegistryKey -Key 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\PostRebootReporting' }
        { Test-RegistryValueNotNull -Key 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager' -Value 'PendingFileRenameOperations' }
        { Test-RegistryValueNotNull -Key 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager' -Value 'PendingFileRenameOperations2' }
        { 
            # Added test to check first if key exists, using "ErrorAction ignore" will incorrectly return $true
            'HKLM:\SOFTWARE\Microsoft\Updates' | Where-Object { test-path $_ -PathType Container } | ForEach-Object {            
                (Get-ItemProperty -Path $_ -Name 'UpdateExeVolatile' | Select-Object -ExpandProperty UpdateExeVolatile) -ne 0 
            }
        }
        { Test-RegistryValue -Key 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce' -Value 'DVDRebootSignal' }
        { Test-RegistryKey -Key 'HKLM:\SOFTWARE\Microsoft\ServerManager\CurrentRebootAttemps' }
        { Test-RegistryValue -Key 'HKLM:\SYSTEM\CurrentControlSet\Services\Netlogon' -Value 'JoinDomain' }
        { Test-RegistryValue -Key 'HKLM:\SYSTEM\CurrentControlSet\Services\Netlogon' -Value 'AvoidSpnSet' }
        {
            # Added test to check first if keys exists, if not each group will return $Null
            # May need to evaluate what it means if one or both of these keys do not exist
            ( 'HKLM:\SYSTEM\CurrentControlSet\Control\ComputerName\ActiveComputerName' | Where-Object { test-path $_ } | %{ (Get-ItemProperty -Path $_ ).ComputerName } ) -ne 
            ( 'HKLM:\SYSTEM\CurrentControlSet\Control\ComputerName\ComputerName' | Where-Object { Test-Path $_ } | %{ (Get-ItemProperty -Path $_ ).ComputerName } )
        }
        {
            # Added test to check first if key exists
            'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Services\Pending' | Where-Object { 
                (Test-Path $_) -and (Get-ChildItem -Path $_) } | ForEach-Object { $true }
        }
    )

    foreach ($test in $tests) {
        Write-Verbose "Running scriptblock: [$($test.ToString())]"
        if (& $test) {
            $true
            break
        }
    }
}

foreach ($computer in $ComputerName) {
    try {
        $connParams = @{
            'ComputerName' = $computer
        }
        if ($PSBoundParameters.ContainsKey('Credential')) {
            $connParams.Credential = $Credential
        }

        $output = @{
            ComputerName    = $computer
            IsPendingReboot = $false
        }

        $psRemotingSession = New-PSSession @connParams
        
        if (-not ($output.IsPendingReboot = Invoke-Command -Session $psRemotingSession -ScriptBlock $scriptBlock)) {
            $output.IsPendingReboot = $false
        }
        [pscustomobject]$output
    } catch {
        Write-Error -Message $_.Exception.Message
    } finally {
        if (Get-Variable -Name 'psRemotingSession' -ErrorAction Ignore) {
            $psRemotingSession | Remove-PSSession
        }
    }
}
```

You can now execute it like this:

```powershell
PS51> .\Test-PendingReboot.ps1 -Server SRV1,SRV2,SRV3,etc
```

## Summary

You should now have a quick way to test pending reboot across Windows servers. You can see that by using PowerShell, you can consolidate down many tedious steps into one script. This script allows you to quickly test for a pending reboot across many servers at once.

If you know of any other indications to check for a pending reboot, please let me know.

Share this article

[Share on X](https://twitter.com/intent/tweet?url=https%3A%2F%2Fadamtheautomator.com%2Fpending-reboot-registry%2F&text=Test%20Pending%20Reboot%20on%20Windows%20Servers%20with%20PowerShell)[Share on Facebook](https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Fadamtheautomator.com%2Fpending-reboot-registry%2F)[Share on LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fadamtheautomator.com%2Fpending-reboot-registry%2F)

## Related Posts

![](https://adamtheautomator.com/wp-content/uploads/2019/08/computer-161501_1280.png)

### [Windows 10 Boot Time and Uptime: PowerShell Insights](/windows-uptime/)

Check boot time in Windows 10 and monitor Windows uptime with this PowerShell script.

![](https://adamtheautomator.com/wp-content/uploads/2026/06/26995-troubleshoot-dns-issues-powershell-codex.webp)

### [Troubleshoot DNS Issues with PowerShell](/troubleshoot-dns-issues-powershell/)

Troubleshoot DNS issues with PowerShell by testing name resolution, DNS client settings, cache entries, and network connectivity in a repeatable workflow.

![](https://adamtheautomator.com/wp-content/uploads/2025/10/image_2025-10-24_095322075.png)

### [Migrating from PowerShell 6 to 7.5: Breaking Changes/New Features](/migrating-powershell-6-to-7-5/)

Migrate from PowerShell Core 6 to 7.5: breaking changes, features, and testing tips.

## Categories

*   [IT Ops](/category/it-ops/)
*   [Cloud](/category/cloud/)
*   [DevOps](/category/devops/)
*   [Home Ops](/category/home-ops/)
*   [Information Security](/category/infosec/)
*   [Software Development](/category/software-development/)

## Site

*   [Home](/)
*   [Tutorials](/tutorials/)
*   [Instructors](/author/)
*   [Advertising](/advertising/)
*   [Recommended Resources](/resources/)
*   [About Adam](/about-adam/)

Copyright 2026© ATA Learning | [Privacy Policy](/privacy/)
