17

I am trying to get to know where reboot is required or not for a Windows machine. However, my script is throwing and error.

powershell "$key = Get-Item "HKLM:SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired" -ErrorAction SilentlyContinue"

Error :
Get-Item : A positional parameter cannot be found that accepts argument
'Update\RebootRequired'.
At line:1 char:8
+ $key = Get-Item
HKLM:SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Aut ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~
    + CategoryInfo          : InvalidArgument: (:) [Get-Item], ParameterBindin
   gException
    + FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell
   .Commands.GetItemCommand

I am running this command in "command prompt". Not sure what it means !

weir
  • 4,521
  • 2
  • 29
  • 42
Pradeep Shanbhag
  • 437
  • 5
  • 8
  • 19
  • 1
    Hey got the answer powershell "(Invoke-WmiMethod -Namespace root\ccm\clientsdk -Class CCM_ClientUtilities -Name DetermineIfRebootPending).RebootPending" – Pradeep Shanbhag Dec 18 '17 at 11:59
  • 1
    It is perfectly acceptable to answer your own question and to even accept it ... consider adding your comment as a proper answer - it may help others in the future. – David Dec 18 '17 at 12:06
  • Possible duplicate of [C#: How can a required reboot be detected for windows 7](https://stackoverflow.com/questions/15482174/c-how-can-a-required-reboot-be-detected-for-windows-7) – Maximilian Burszley Dec 18 '17 at 13:53

5 Answers5

21

Pending reboot can be caused by variety of reasons, not just the ones that are detailed in other answers. Try PendingReboot module, which incorporates various tests into a single cmdlet:

# Install
Install-Module -Name PendingReboot

# Run
Test-PendingReboot -Detailed
George Chakhidze
  • 1,269
  • 12
  • 15
  • 1
    This gave me enough information to know the reason for the reboot request as well, which is what I was looking for. – HackSlash Jun 24 '19 at 21:42
  • 5
    This is not working on latest powershell (Core) because it is still using the now fully deprecated WMI, and not CIM instances. Repo is abandoned. – not2qubit Nov 29 '22 at 00:54
16

You need to check 2 paths, one key and you need to query the configuration manager via WMI in order to check all possible locations.

#Adapted from https://gist.github.com/altrive/5329377
#Based on <http://gallery.technet.microsoft.com/scriptcenter/Get-PendingReboot-Query-bdb79542>
function Test-PendingReboot {
    if (Get-ChildItem "HKLM:\Software\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending" -EA Ignore) { return $true }
    if (Get-Item "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired" -EA Ignore) { return $true }
    if (Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager" -Name PendingFileRenameOperations -EA Ignore) { return $true }
    try { 
        $util = [wmiclass]"\\.\root\ccm\clientsdk:CCM_ClientUtilities"
        $status = $util.DetermineIfRebootPending()
        if (($status -ne $null) -and $status.RebootPending) {
            return $true
        }
    }
    catch { }

    return $false
}

Test-PendingReboot
Zam
  • 1,121
  • 10
  • 27
Mathis Michel
  • 277
  • 2
  • 7
4

Your syntax wasn't correct, if you want to run the PowerShell command from cmd, it has to look like this:

powershell.exe "Get-Item 'HKLM:SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired'"

But like Mathis mentioned, this key only exists if a reboot is pending.

Paxz
  • 2,959
  • 1
  • 20
  • 34
  • 3
    Number 3. Should be a comment in the question. It is not part of the answer. – Matt Dec 18 '17 at 12:47
  • 1
    @Matt Yeah... I noticed your comment just now (I know im quick.. :D). I rearranged the answer, thanks for the heads-up. – Paxz Aug 02 '18 at 11:52
2

(I would have preferred to add this as a comment on the accepted answer, but the code would not have fit.)

I think the following function can eliminate some unnecessary reboots. The PendingFileRenameOperations registry key supports not only renames, but also deletes (expressed essentially as "rename to null")*. The assumption I am making is that deletes represent pending cleanup operations that will not affect functionality in the meantime.

<#
.SYNOPSIS
Returns true if any true renames-- deletes are ignored-- are present in the
PendingFileRenameOperations registry key.
#>
function Test-PendingFileRename {
    [OutputType('bool')]
    [CmdletBinding()]
    param()
    $operations = (Get-Item 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\').GetValue('PendingFileRenameOperations')
    if ($null -eq $operations) {
        $false
    } else {
        $trueOperationsCount = $operations.Length / 2
        $trueRenames = [System.Collections.Generic.Dictionary[string, string]]::new($trueOperationsCount)
        for ($i = 0; $i -ne $trueOperationsCount; $i++) {
            $operationSource = $operations[$i * 2]
            $operationDestination = $operations[$i * 2 + 1]
            if ($operationDestination.Length -eq 0) {
                Write-Verbose "Ignoring pending file delete '$operationSource'"
            } else {
                Write-Host "Found a true pending file rename (as opposed to delete). Source '$operationSource'; Dest '$operationDestination'"
                $trueRenames[$operationSource] = $operationDestination
            }
        }
        $trueRenames.Count -gt 0
    }
}

One would implement this in the accepted answer's script by inserting the above function at the top and then replacing the line

if (Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager" -Name PendingFileRenameOperations -EA Ignore) { return $true }

with

if (Test-PendingFileRename) { return $true }

* refs:

weir
  • 4,521
  • 2
  • 29
  • 42
0

One thing I found that was causing this (and no end of headaches for me) was every time I tried to run the SCCM 1906 update it failed due to a pending reboot. Using this script in my investigations, I noticed it was ComponentBasedServicing that seemed to be holding up the works, which was the Optional Components were automatically installing. A little bit more digging lead me to a scheduled task called LanguageComponentsInstaller. I disabled this and I'm keeping an eye on it but it seems to have fixed this problem.

Thanks for the script. It's saved me a lot of stress trying to crack this egg :)

Brett
  • 1
  • 2