Alert when server is prompting to reboot for updates

I monitor many client's servers. I need to find a way to know when a server is prompting to reboot due to updates. I can't log into all of them every week.  Is there anything I can key in on that would let me know the server needs to be rebooted?
ajdratchAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Thomas GrassiSystems AdministratorCommented:
Hello

Yes when you have many servers it takes a lot to know what is going on.

I found this for you that will help you

http://blogs.technet.com/b/heyscriptingguy/archive/2013/06/11/determine-pending-reboot-status-powershell-style-part-2.aspx

I am working on this script now if you need any help

HTH

Tom
0
Will SzymkowskiSenior Solution ArchitectCommented:
I would highly recommend using the Get-PendingReboot.ps1 script. Works great!
https://gallery.technet.microsoft.com/scriptcenter/Get-PendingReboot-Query-bdb79542

Will.
0
David Johnson, CD, MVPOwnerCommented:
from Scripting Guy link
all you need to do is wrap it in something like
$cred = Get-Credential mydomain\administrator
$servers = Invoke-Command -cn dc3 -cred $cred -script {import-module ActiveDirectory;
Get-ADComputer -LDAPFilter "(&(objectcategory=computer)(OperatingSystem=*server*))"}
$servers.count
$servers | foreach {$_.name} # one way
foreach($server in $servers) {
Get-PendingReboot -computername $servers
}

Open in new window

function Get-RebootPending 
{
    [CmdletBinding()]
    param(
[Parameter(Position=0,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
    [Alias("CN","Computer")]
    [String[]]$ComputerName="$env:COMPUTERNAME"
    )
    $PendFileRename,$Pending,$SCCM = $false,$false,$false
    $CBSRebootPend = $null
    $WMI_OS = Get-WmiObject -Class Win32_OperatingSystem -Property BuildNumber, CSName -ComputerName $ComputerName
    $RegCon = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey([Microsoft.Win32.RegistryHive]"LocalMachine",$ComputerName)
    If ($WMI_OS.BuildNumber -ge 6001) {
    $CBSRebootPend = $RegSubKeysCBS -contains "RebootPending"        
    }
    ## End If ($WMI_OS.BuildNumber -ge 6001)
    $RegWUAU = $RegCon.OpenSubKey("SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\")
    $RegWUAURebootReq = $RegWUAU.GetSubKeyNames()
    $WUAURebootReq = $RegWUAURebootReq -contains "RebootRequired"
    $RegSubKeySM = $RegCon.OpenSubKey("SYSTEM\CurrentControlSet\Control\Session Manager\")
    $RegValuePFRO = $RegSubKeySM.GetValue("PendingFileRenameOperations",$null)
    $RegCon.Close()
    If ($RegValuePFRO)
    {
    $PendFileRename = $true
    }#End If ($RegValuePFRO)
    $CCMClientSDK = $null
    $CCMSplat = @{
    NameSpace='ROOT\ccm\ClientSDK'
    Class='CCM_ClientUtilities'
    Name='DetermineIfRebootPending'
    ComputerName=$Computer
    ErrorAction='SilentlyContinue'
    }
    $CCMClientSDK = Invoke-WmiMethod @CCMSplat
    If ($CCMClientSDK)
    {
    If ($CCMClientSDK.ReturnValue -ne 0)
    {
    Write-Warning "Error: DetermineIfRebootPending returned error code $($CCMClientSDK.ReturnValue)"
    }## End If ($CCMClientSDK -and $CCMClientSDK.ReturnValue -ne 0)
    If ($CCMClientSDK.IsHardRebootPending -or $CCMClientSDK.RebootPending)
        {
        $SCCM = $true
        }## End If ($CCMClientSDK.IsHardRebootPending -or $CCMClientSDK.RebootPending)
        }## End If ($CCMClientSDK)
            Else
            {
            $SCCM = $null
            }
        If ($CBSRebootPend -or $WUAURebootReq -or $SCCM -or $PendFileRename)
    {
        $Pending = $true
    }## End If ($CBS -or $WUAU -or $PendFileRename)
    $SelectSplat = @{
        Property=('Computer','CBServicing','WindowsUpdate','CCMClientSDK','PendFileRename','PendFileRenVal','RebootPending')
        }
    New-Object -TypeName PSObject -Property @{
    Computer=$WMI_OS.CSName
    CBServicing=$CBSRebootPend
    WindowsUpdate=$WUAURebootReq
    CCMClientSDK=$SCCM
    PendFileRename=$PendFileRename
    PendFileRenVal=$RegValuePFRO
    RebootPending=$Pending
    } | Select-Object @SelectSplat
}

Open in new window

http://blogs.technet.com/b/heyscriptingguy/archive/2012/08/15/use-powershell-to-query-ad-ds-for-servers-and-then-find-hotfixes.aspx
http://blogs.technet.com/b/heyscriptingguy/archive/2013/06/11/determine-pending-reboot-status-powershell-style-part-2.aspx
0
Simplify Active Directory Administration

Administration of Active Directory does not have to be hard.  Too often what should be a simple task is made more difficult than it needs to be.The solution?  Hyena from SystemTools Software.  With ease-of-use as well as powerful importing and bulk updating capabilities.

ajdratchAuthor Commented:
Thanks for the links to the powershell script get-pendingreboot. I run this and i get no output. I am running Get-PendingReboot -ComputerName  server1
After running it I am back at the powershell prompt. No errors, no output
0
Thomas GrassiSystems AdministratorCommented:
Here is a working one

Function Get-PendingReboot
{
<#
.SYNOPSIS
    Gets the pending reboot status on a local or remote computer.

.DESCRIPTION
    This function will query the registry on a local or remote computer and determine if the
    system is pending a reboot, from either Microsoft Patching or a Software Installation.
    For Windows 2008+ the function will query the CBS registry key as another factor in determining
    pending reboot state.  "PendingFileRenameOperations" and "Auto Update\RebootRequired" are observed
    as being consistant across Windows Server 2003 & 2008.
	
    CBServicing = Component Based Servicing (Windows 2008)
    WindowsUpdate = Windows Update / Auto Update (Windows 2003 / 2008)
    CCMClientSDK = SCCM 2012 Clients only (DetermineIfRebootPending method) otherwise $null value
    PendFileRename = PendingFileRenameOperations (Windows 2003 / 2008)

.PARAMETER ComputerName
    A single Computer or an array of computer names.  The default is localhost ($env:COMPUTERNAME).

.PARAMETER ErrorLog
    A single path to send error data to a log file.

.EXAMPLE
    PS C:\> Get-PendingReboot -ComputerName (Get-Content C:\ServerList.txt) | Format-Table -AutoSize
	
    Computer CBServicing WindowsUpdate CCMClientSDK PendFileRename PendFileRenVal RebootPending
    -------- ----------- ------------- ------------ -------------- -------------- -------------
    DC01           False         False                       False                        False
    DC02           False         False                       False                        False
    FS01           False         False                       False                        False

    This example will capture the contents of C:\ServerList.txt and query the pending reboot
    information from the systems contained in the file and display the output in a table. The
    null values are by design, since these systems do not have the SCCM 2012 client installed,
    nor was the PendingFileRenameOperations value populated.

.EXAMPLE
    PS C:\> Get-PendingReboot
	
    Computer       : WKS01
    CBServicing    : False
    WindowsUpdate  : True
    CCMClient      : False
    PendFileRename : False
    PendFileRenVal : 
    RebootPending  : True
	
    This example will query the local machine for pending reboot information.
	
.EXAMPLE
    PS C:\> $Servers = Get-Content C:\Servers.txt
    PS C:\> Get-PendingReboot -Computer $Servers | Export-Csv C:\PendingRebootReport.csv -NoTypeInformation
	
    This example will create a report that contains pending reboot information.

.LINK
    Component-Based Servicing:
    http://technet.microsoft.com/en-us/library/cc756291(v=WS.10).aspx
	
    PendingFileRename/Auto Update:
    http://support.microsoft.com/kb/2723674
    http://technet.microsoft.com/en-us/library/cc960241.aspx
    http://blogs.msdn.com/b/hansr/archive/2006/02/17/patchreboot.aspx

    SCCM 2012/CCM_ClientSDK:
    http://msdn.microsoft.com/en-us/library/jj902723.aspx

.NOTES
    Author:  Brian Wilhite
    Email:   bwilhite1@carolina.rr.com
    Date:    08/29/2012
    PSVer:   2.0/3.0
    Updated: 05/30/2013
    UpdNote: Added CCMClient property - Used with SCCM 2012 Clients only
             Added ValueFromPipelineByPropertyName=$true to the ComputerName Parameter
             Removed $Data variable from the PSObject - it is not needed
             Bug with the way CCMClientSDK returned null value if it was false
             Removed unneeded variables
             Added PendFileRenVal - Contents of the PendingFileRenameOperations Reg Entry
#>

[CmdletBinding()]
param(
	[Parameter(Position=0,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
	[Alias("CN","Computer")]
	[String[]]$ComputerName="$env:COMPUTERNAME",
	[String]$ErrorLog
	)

Begin
	{
		# Adjusting ErrorActionPreference to stop on all errors, since using [Microsoft.Win32.RegistryKey]
        # does not have a native ErrorAction Parameter, this may need to be changed if used within another
        # function.
		$TempErrAct = $ErrorActionPreference
		$ErrorActionPreference = "Stop"
	}#End Begin Script Block
Process
	{
		Foreach ($Computer in $ComputerName)
			{
				Try
					{
						# Setting pending values to false to cut down on the number of else statements
						$PendFileRename,$Pending,$SCCM = $false,$false,$false
                        
                        # Setting CBSRebootPend to null since not all versions of Windows has this value
                        $CBSRebootPend = $null
						
						# Querying WMI for build version
						$WMI_OS = Get-WmiObject -Class Win32_OperatingSystem -Property BuildNumber, CSName -ComputerName $Computer

						# Making registry connection to the local/remote computer
						$RegCon = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey([Microsoft.Win32.RegistryHive]"LocalMachine",$Computer)
						
						# If Vista/2008 & Above query the CBS Reg Key
						If ($WMI_OS.BuildNumber -ge 6001)
							{
								$RegSubKeysCBS = $RegCon.OpenSubKey("SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\").GetSubKeyNames()
								$CBSRebootPend = $RegSubKeysCBS -contains "RebootPending"
									
							}#End If ($WMI_OS.BuildNumber -ge 6001)
							
						# Query WUAU from the registry
						$RegWUAU = $RegCon.OpenSubKey("SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\")
						$RegWUAURebootReq = $RegWUAU.GetSubKeyNames()
						$WUAURebootReq = $RegWUAURebootReq -contains "RebootRequired"
						
						# Query PendingFileRenameOperations from the registry
						$RegSubKeySM = $RegCon.OpenSubKey("SYSTEM\CurrentControlSet\Control\Session Manager\")
						$RegValuePFRO = $RegSubKeySM.GetValue("PendingFileRenameOperations",$null)
						
						# Closing registry connection
						$RegCon.Close()
						
						# If PendingFileRenameOperations has a value set $RegValuePFRO variable to $true
						If ($RegValuePFRO)
							{
								$PendFileRename = $true

							}#End If ($RegValuePFRO)

						# Determine SCCM 2012 Client Reboot Pending Status
						# To avoid nested 'if' statements and unneeded WMI calls to determine if the CCM_ClientUtilities class exist, setting EA = 0
						$CCMClientSDK = $null
                        $CCMSplat = @{
                            NameSpace='ROOT\ccm\ClientSDK'
                            Class='CCM_ClientUtilities'
                            Name='DetermineIfRebootPending'
                            ComputerName=$Computer
                            ErrorAction='SilentlyContinue'
                            }
                        $CCMClientSDK = Invoke-WmiMethod @CCMSplat
						If ($CCMClientSDK)
                            {
                                If ($CCMClientSDK.ReturnValue -ne 0)
							        {
								        Write-Warning "Error: DetermineIfRebootPending returned error code $($CCMClientSDK.ReturnValue)"
                            
							        }#End If ($CCMClientSDK -and $CCMClientSDK.ReturnValue -ne 0)

						        If ($CCMClientSDK.IsHardRebootPending -or $CCMClientSDK.RebootPending)
							        {
								        $SCCM = $true

							        }#End If ($CCMClientSDK.IsHardRebootPending -or $CCMClientSDK.RebootPending)

                            }#End If ($CCMClientSDK)
                        Else
                            {
                                $SCCM = $null

                            }                        
                        
                        # If any of the variables are true, set $Pending variable to $true
						If ($CBSRebootPend -or $WUAURebootReq -or $SCCM -or $PendFileRename)
							{
								$Pending = $true

							}#End If ($CBS -or $WUAU -or $PendFileRename)
							
						# Creating Custom PSObject and Select-Object Splat
                        $SelectSplat = @{
                            Property=('Computer','CBServicing','WindowsUpdate','CCMClientSDK','PendFileRename','PendFileRenVal','RebootPending')
                            }
						New-Object -TypeName PSObject -Property @{
								Computer=$WMI_OS.CSName
								CBServicing=$CBSRebootPend
								WindowsUpdate=$WUAURebootReq
								CCMClientSDK=$SCCM
								PendFileRename=$PendFileRename
                                PendFileRenVal=$RegValuePFRO
								RebootPending=$Pending
								} | Select-Object @SelectSplat

					}#End Try

				Catch
					{
						Write-Warning "$Computer`: $_"
						
						# If $ErrorLog, log the file to a user specified location/path
						If ($ErrorLog)
							{
								Out-File -InputObject "$Computer`,$_" -FilePath $ErrorLog -Append

							}#End If ($ErrorLog)
							
					}#End Catch
					
			}#End Foreach ($Computer in $ComputerName)
			
	}#End Process
	
End
	{
		# Resetting ErrorActionPref
		$ErrorActionPreference = $TempErrAct
	}#End End
	
}#End Function

$Servers = Get-Content C:\UTIL\Servers.txt
Get-PendingReboot -ComputerName $Servers | Export-CSV C:\Util\PendingRebootReportServers.csv -NoTypeInformation
$Computers = Get-Content C:\UTIL\Computers.txt
Get-PendingReboot -ComputerName $Computers | Export-CSV C:\Util\PendingRebootReportComputers.csv -NoTypeInformation

Open in new window


You will notice at the bottom I added this  you need a folder c:\util and place all the files in that folder or what ever you want

$Servers = Get-Content C:\UTIL\Servers.txt
Get-PendingReboot -ComputerName $Servers | Export-CSV C:\Util\PendingRebootReportServers.csv -NoTypeInformation
$Computers = Get-Content C:\UTIL\Computers.txt
Get-PendingReboot -ComputerName $Computers | Export-CSV C:\Util\PendingRebootReportComputers.csv -NoTypeInformation

Open in new window




This calls the files servers and computers just text file with the list of your network devices

computers.txt
wks001
wks002
wks003

Servers.txt
server01
server02
server03

Then I created a batch file rebootstatus.cmd

 
@echo off

del c:\util\pendingrebootreportservers.csv
del c:\util\pendingrebootreportcomputers.csv

%SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe -file Get-PendingReboot.ps1



Exit

Open in new window


After that I added code to email the reports to me  and set it up as a task to run daily

This lets you run this automatically


To run what you have in powershell you must do this

ps c:> ./Get-PendingReboot.ps1
ps c:>  Get-PendingReboot -ComputerName server01
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Will SzymkowskiSenior Solution ArchitectCommented:
You have to add the script to the powershell session. .\Get-PendingReboot.ps1. Once you have done this then you can type Get-PendingReboot -computername computer1 and it should work for you.

Will.
0
ajdratchAuthor Commented:
Thanks so much. I got that to work.

Now I need to figure out how to incorporate that into Level Platforms RMM
0
Will SzymkowskiSenior Solution ArchitectCommented:
Although Thomas provided more detail in regards to get this working, I ultimately provided the solution that you have used? Not sure why points were not split (to some degree)?


Will.
0
ajdratchAuthor Commented:
Valid point. Sorry about that. Can I redo that?
0
Will SzymkowskiSenior Solution ArchitectCommented:
I have requested attention but i think you should be able to modify it. Not 100% sure.

If you cannot undo it we can just wait for a moderator.

Will.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Windows Server 2008

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.