Jump to content

Need Help... Reading The Registry For Reboot Needs


Recommended Posts

I am building a util that checks to see if patches have been applied, and the computer needs to be rebooted. So far, I have the code that processes the reboot itself, running a countdown, so the user has plenty of time to save docs, etc...

What I am struggling with is checking the registry settings that dictate if a reboot is needed. According to

http://forum.shavlik.com/viewtopic.php?t=2940 and

http://myitforum.com/articles/6/print_view.asp?id=8833

one of the registry keys is HKLMSYSTEM\CurrentControlSet\Control\Session Manager\PendingFileRenameOperations. If the exists, and has values, then your machine is supposedly in need of a reboot. Also, the key below is supposed to be important:

HKLMSOFTWAREMICROSOFT\Updates\UpdateExeVolatile

0 -> no restart is pending

1 -> a software update removal is pending a restart

2 -> a software update installation is pending a restart

3 -> Both install and removal are pending a restart

I have been trying to use the regenumkey and regenumval functions to check these settings, with absolutely no luck. I think the first key only exists if there are pending reboots, but I can't be certain.

Anyone got any idea on how to check these keys? I'm posting my reboot code, but really just to show you guys where I'm at now. The current code works, I'm just trying to add this new functionality, even if it means a complete rewrite.

Thanks!

-Mike

; ==========================================================================
; NAME: reboot_agent.au3
; 
; AUTHOR: Mike Caouette
; DATE  : 3/29/2006
; 
; COMMENT: Agent used to remind people of the need to reboot. There are 5  
; command line parameters:
; remind = gentle reminder to reboot, only if uptime is > 6 days
; reboot = reboot message displays, with an 8hr timer. User can reboot at
; any time or wait. Only applies if uptime > 7 days
; nocheckreboot = same as reboot, but without uptime check
; debugremind = same as remind, but shorter uptime check and no real reboot
; debugreboot = same as reboot, but with shorter uptime check and no real reboot
; ==========================================================================

#include <GUIConstants.au3>
Autoitsetoption ("TrayIconHide",1)

Dim $Time = 28800, $t = ""  ; need to make $Time = 28800 for 8 hour delay
Dim $ticks, $hours = 8, $mins = "00", $seconds = "00"
;Opt("RunErrorsFatal", 0);1=fatal, 0=silent set @error

;Check to see if the OS is Worstation or Server   - Workstation = WinNT  Server = ServerNT
$ver = RegRead("HKLM\SYSTEM\CurrentControlSet\Control\ProductOptions", "ProductType")
If $ver = "WinNT" then 
;see if there are command line args
    If $cmdline[0] Then
        $command = $CmdLine[1]
        Select
            Case $command = "remind"
                ;Run the reboot process, checking to see if the computer has been rebooted this week.
                ;---------------------------Only run this code if the computer has been running longer than a week.----------------
                    $ret = DllCall("kernel32.dll", "long", "GetTickCount")
                    $uptime = ($ret[0]/1000)
                    If $uptime > 518400 Then; 518400 is 6 days in seconds - change to debug with shorter times
                        $inst_win = GUICreate("Reboot Recommended", 300, 125,-1,-1,$WS_Caption)
                        $go = GUICtrlCreateButton ("Reboot Now" , 30, 80, 75, 25)
                        $quit = GUICtrlCreateButton ("Wait until later" , 150, 80, 100, 25)
                        $message = GUICtrlCreateLabel("This computer has not beeen rebooted in 6 days", 20,10)
                        $message1 = GUICtrlCreateLabel("Please take time to reboot your computer,", 20,30)
                        $message2 = GUICtrlCreateLabel("or your computer may be rebooted automatically.", 20,50)
                        
                        GUISetState()
                        While 1
                            $msg = GUIGetMsg()
                            If $msg = $GUI_EVENT_CLOSE Then Exit
                            If $msg = $go Then Shutdown(6) 
                            If $msg = $quit Then ExitLoop
                        WEnd
                        GUIDelete($inst_win)
                        Exit
                    EndIf
    
    
    
                ;Message to remind users to reboot
                ;MsgBox(0,"Please Reboot Your Computer", "Critical security patches have been installed." & @CR & "Please take time to reboot your computer before Saturday," & @CR & "or your computer may be rebooted automatically.")
            Case $command = "reboot"
                ;Run the reboot process, checking to see if the computer has been rebooted this week.
                ;---------------------------Only run this code if the computer has been running longer than a week.----------------
                    $ret = DllCall("kernel32.dll", "long", "GetTickCount")
                    $uptime = ($ret[0]/1000)
                    If $uptime > 604800 Then; 604800 is 1 week in seconds - change to debug with shorter times
                        $inst_win = GUICreate("Reboot Required", 300, 100,-1,-1,$WS_Caption)
                        $go = GUICtrlCreateButton ("Reboot Now" , 30, 60, 75, 25)
                        $minimize = GUICtrlCreateButton ("Minimize and Wait" , 150, 60, 100, 25)
                        $message = GUICtrlCreateLabel("Reboot will Automatically continue in " & $hours & "h:" & $mins & "m" & $Seconds & "s", 20,30)
                        $message1 = GUICtrlCreateLabel("This computer has not beeen rebooted in 7 days", 20,10)
                        
                        GUISetState()
                        $a = TimerInit()
                        While 1
                            $msg = GUIGetMsg()
                            If $msg = $GUI_EVENT_CLOSE Then Exit
                            If $msg = $go Or $Time = 0 Then ExitLoop 
                            If $msg = $minimize Then GuiSetState(@SW_MINIMIZE)
                            If TimerDiff($a) > ($Time * 1000) Then ExitLoop
                            $ticks = $Time - Int(TimerDiff($a) / 1000)
                            $hours = Int($ticks / 3600)
                            $ticks = Mod($Ticks, 3600)
                            $Mins = Int($Ticks / 60)
                            $Seconds = Mod($Ticks, 60)
                            GUICtrlSetData( $message , "Reboot will Automatically continue in " & $hours & "h:" & $mins & "m:" & $Seconds & "s")
                            Sleep(100)  
                        WEnd
                        GUIDelete($inst_win)
                        Shutdown(6)
                    EndIf
            Case $command = "nocheckreboot"
                ;Run the reboot process, without checking to see if the computer has been rebooted this week.
                    
                        $inst_win = GUICreate("Reboot Required", 300, 100,-1,-1,$WS_Caption)
                        $go = GUICtrlCreateButton ("Reboot Now" , 30, 60, 75, 25)
                        $minimize = GUICtrlCreateButton ("Minimize and Wait" , 150, 60, 100, 25)
                        $message = GUICtrlCreateLabel("Reboot will Automatically continue in " & $hours & "h:" & $mins & "m" & $Seconds & "s", 20,30)
                        $message1 = GUICtrlCreateLabel("This computer has not beeen rebooted in 7 days", 20,10)
                        
                        GUISetState()
                        $a = TimerInit()
                        While 1
                            $msg = GUIGetMsg()
                            If $msg = $GUI_EVENT_CLOSE Then Exit
                            If $msg = $go Or $Time = 0 Then ExitLoop 
                            If $msg = $minimize Then GuiSetState(@SW_MINIMIZE)
                            If TimerDiff($a) > ($Time * 1000) Then ExitLoop
                            $ticks = $Time - Int(TimerDiff($a) / 1000)
                            $hours = Int($ticks / 3600)
                            $ticks = Mod($Ticks, 3600)
                            $Mins = Int($Ticks / 60)
                            $Seconds = Mod($Ticks, 60)
                            GUICtrlSetData( $message , "Reboot will Automatically continue in " & $hours & "h:" & $mins & "m:" & $Seconds & "s")
                            Sleep(100)  
                        WEnd
                        GUIDelete($inst_win)
                        Shutdown(6)                 
            Case $command = "debugreboot"
            ;Run the reboot process in debug mode, checking to see if the computer has been rebooted this week.
            ;---------------------------Only run this code if the computer has been running longer than 5 minutes.----------------
                $Time = 30
                $ret = DllCall("kernel32.dll", "long", "GetTickCount")
                $uptime = ($ret[0]/1000)
                If $uptime > 300 Then; 604800 is 1 week in seconds - change to debug with shorter times
                    $inst_win = GUICreate("Reboot Required", 300, 100,-1,-1,$WS_Caption)
                    $go = GUICtrlCreateButton ("Reboot Now" , 30, 60, 75, 25)
                    $minimize = GUICtrlCreateButton ("Minimize and Wait" , 150, 60, 100, 25)
                    $message = GUICtrlCreateLabel("Reboot will Automatically continue in " & $hours & "h:" & $mins & "m" & $Seconds & "s", 20,30)
                    $message1 = GUICtrlCreateLabel("This computer has not beeen rebooted in 7 days", 20,10)
                    
                    GUISetState()
                    $a = TimerInit()
                    While 1
                        $msg = GUIGetMsg()
                        If $msg = $GUI_EVENT_CLOSE Then Exit
                        If $msg = $go Or $Time = 0 Then ExitLoop 
                        If $msg = $minimize Then GuiSetState(@SW_MINIMIZE)
                        If TimerDiff($a) > ($Time * 1000) Then ExitLoop
                        $ticks = $Time - Int(TimerDiff($a) / 1000)
                        $hours = Int($ticks / 3600)
                        $ticks = Mod($Ticks, 3600)
                        $Mins = Int($Ticks / 60)
                        $Seconds = Mod($Ticks, 60)
                        GUICtrlSetData( $message , "Reboot will Automatically continue in " & $hours & "h:" & $mins & "m:" & $Seconds & "s")
                        Sleep(100)  
                    WEnd
                    GUIDelete($inst_win)
                    MsgBox(0,"","Rebooting")
                ;Shutdown(6)
                EndIf
            Case $command = "debugremind"
                ;Run the reboot process, checking to see if the computer has been rebooted this week.
                ;---------------------------Only run this code if the computer has been running longer than a week.----------------
                    $ret = DllCall("kernel32.dll", "long", "GetTickCount")
                    $uptime = ($ret[0]/1000)
                    If $uptime > 40 Then; 518400 is 6 days in seconds - change to debug with shorter times
                        $inst_win = GUICreate("Reboot Recommended", 300, 125,-1,-1,$WS_Caption)
                        $go = GUICtrlCreateButton ("Reboot Now" , 30, 80, 75, 25)
                        $quit = GUICtrlCreateButton ("Wait until later" , 150, 80, 100, 25)
                        $message = GUICtrlCreateLabel("This computer has not beeen rebooted in 6 days", 20,10)
                        $message1 = GUICtrlCreateLabel("Please take time to reboot your computer,", 20,30)
                        $message2 = GUICtrlCreateLabel("or your computer may be rebooted automatically.", 20,50)
                        GUISetState()
                        While 1
                            $msg = GUIGetMsg()
                            If $msg = $GUI_EVENT_CLOSE Then Exit
                            If $msg = $go Then 
                                GUIDelete($inst_win)
                                MsgBox(0,"","Rebooting")
                                Exitloop 
                            Endif
                            If $msg = $quit Then 
                                GUIDelete($inst_win)
                                Exitloop
                            Endif   
                        WEnd
                        GUIDelete($inst_win)
                        
                        Exit
                    EndIf
    
    
    
                ;Message to remind users to reboot
                ;MsgBox(0,"Please Reboot Your Computer", "Critical security patches have been installed." & @CR & "Please take time to reboot your computer before Saturday," & @CR & "or your computer may be rebooted automatically.")
            Case Else
            ;Incorrect parameter, throw up a message with proper syntax
                MsgBox(0,"Error", "The syntax of this command is:" & @CR & "Reboot_agent.exe <command>" & @CR & "Where <command> is either reboot, nocheckreboot or remind")
        EndSelect
    Else
    ;No parameter given, throw up a message with proper syntax
        MsgBox(0,"Error", "The syntax of this command is:" & @CR & "Reboot_agent.exe <command>" & @CR & "Where <command> is either reboot, nocheckreboot, or remind")
    EndIf

Endif
Link to comment
Share on other sites

  • Moderators

What? No takers? :)

You need to check both of these and if either one is present then it needs rebooted:

HKLM\SOFTWARE\Microsoft\Updates\UpdateExeVolatile
HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\PendingFileRenameOperations

I'll work on some code to check.

Link to comment
Share on other sites

Verify your code with PendMove and MoveFile from sysinternals. Have not done it my selfe, but my guess is that it will make the nescesary reg settings. While you test RegMon could be helpfull to.

Link to comment
Share on other sites

  • Moderators

What is the ValueName that is used under:

HKLM\SOFTWARE\Microsoft\Updates\UpdateExeVolatile

If I had that I believe this would work:

$sReboot = RegRead("HKLM\SOFTWARE\Microsoft\Updates\UpdateExeVolatile", "Need Vaule Name"); Need the valuename to read here
If @error Or $sReboot == 0 Then
    $a_Status = 0
Else
    $a_Status = 1
EndIf

SetError(0)

$sVaule = RegEnumVal("HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\PendingFileRenameOperations", 1)
If @error Then
    $b_Status = 0
Else
    $b_Status = 1
EndIf

If $a_Status == 1 Or $b_Status == 1 Then;Computer needs rebooted
Edited by big_daddy
Link to comment
Share on other sites

The value name is called "Flags"... I found this by adding a new update on my machine.. Below is the exported registry locations, in case that helps:

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Updates\UpdateExeVolatile]

"Flags"=dword:00000002

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager]

"PendingFileRenameOperations"=hex(7):5c,00,3f,00,3f,00,5c,00,43,00,3a,00,5c,00,\

57,00,49,00,4e,00,44,00,4f,00,57,00,53,00,5c,00,53,00,79,00,73,00,74,00,65,\

00,6d,00,33,00,32,00,5c,00,5f,00,30,00,30,00,30,00,30,00,34,00,35,00,5f,00,\

2e,00,74,00,6d,00,70,00,00,00,5c,00,3f,00,3f,00,5c,00,43,00,3a,00,5c,00,57,\

00,49,00,4e,00,44,00,4f,00,57,00,53,00,5c,00,53,00,79,00,73,00,74,00,65,00,\

6d,00,33,00,32,00,5c,00,53,00,45,00,54,00,44,00,30,00,2e,00,74,00,6d,00,70,\

00,00,00,21,00,5c,00,3f,00,3f,00,5c,00,43,00,3a,00,5c,00,57,00,49,00,4e,00,\

44,00,4f,00,57,00,53,00,5c,00,53,00,79,00,73,00,74,00,65,00,6d,00,33,00,32,\

00,5c,00,77,00,69,00,6e,00,68,00,74,00,74,00,70,00,2e,00,64,00,6c,00,6c,00,\

00,00,5c,00,3f,00,3f,00,5c,00,43,00,3a,00,5c,00,57,00,49,00,4e,00,44,00,4f,\

00,57,00,53,00,5c,00,53,00,79,00,73,00,74,00,65,00,6d,00,33,00,32,00,5c,00,\

5f,00,30,00,30,00,30,00,31,00,30,00,33,00,5f,00,2e,00,74,00,6d,00,70,00,2e,\

00,64,00,6c,00,6c,00,00,00,00,00

Link to comment
Share on other sites

big_daddy,

Here is the code I built to grab whether a reboot was needed (just the UpdateExeVolatile section)

$var = RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Updates\UpdateExeVolatile", "Flags")
;0 -> no restart is pending
;1 -> a software update removal is pending a restart
;2 -> a software update installation is pending a restart
;3 -> Both install and removal are pending a restart
Select
     Case $var = 0
         MsgBox(0, "No Reboot Needed", "No pending reboot")
     Case $var = 1
         MsgBox(0, "Reboot Needed", "A software update removal is pending a restart")
     Case $var = 2
         MsgBox(0, "Reboot Needed", "A software update installation is pending a restart")
     Case $var = 3
         MsgBox(0, "Reboot Needed", "Both install and removal are pending a restart")
EndSelect

The second part of your sample doesn't seem to work, if I comment out the $a_Status section.

-Mike

Link to comment
Share on other sites

  • Moderators

Test this for me:

$a_Value = RegRead("HKLM\SOFTWARE\Microsoft\Updates\UpdateExeVolatile", "Flags")
If @error Or $a_Vaule == 0 Then
    $a_Status = 0
Else
    $a_Status = 1
EndIf

SetError(0)

$b_Vaule = RegRead("HKLM\SYSTEM\CurrentControlSet\Control\Session Manager", "PendingFileRenameOperations")
If @error Then
    $b_Status = 0
Else
    $b_Status = 1
EndIf

If $a_Status == 1 Or $b_Status == 1 Then;Computer needs rebooted
Link to comment
Share on other sites

In case anyone is interested... here is the final script:

-Mike

; ----------------------------------------------------------------------------
;
; AutoIt Version: reboot_needed_agent.au3
; Author:   Michael Caouette
;
; Script Function:
;   This script reads 2 registry locations to see if reboots are pending
;   due to patch installs. If the machine needs to be rebooted, it prompts
;   the user with the option to reboot
; ----------------------------------------------------------------------------

; Script Start - Add your code below here
#include <GUIConstants.au3>
Autoitsetoption ("TrayIconHide",1)

;------Read the first value to see if the machine has pending reboots
$reboot_check1 = RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Updates\UpdateExeVolatile", "Flags")
;0 -> no restart is pending
;1 -> a software update removal is pending a restart
;2 -> a software update installation is pending a restart
;3 -> Both install and removal are pending a restart

;------Read the second value to see if the machine has pending reboots
SetError(0)
$b_Value = RegRead("HKLM\SYSTEM\CurrentControlSet\Control\Session Manager", "PendingFileRenameOperations")
If @error Then
    $reboot_check2 = 0
Else
    $reboot_check2 = 1
EndIf

;------If either check says that a reboot is needed, then prompt the user
If $reboot_check1 <> 0 or $reboot_check2 == 1 Then   
;Computer needs to be rebooted
;MsgBox(0, "Reboot Needed", "Pending a restart")
    $inst_win = GUICreate("Reboot Recommended", 300, 125,-1,-1,$WS_Caption)
    $go = GUICtrlCreateButton ("Reboot Now" , 30, 80, 75, 25)
    $quit = GUICtrlCreateButton ("Not at this time" , 150, 80, 100, 25)
    $message = GUICtrlCreateLabel("This computer has had updates installed,", 20,10)
    $message1 = GUICtrlCreateLabel("and needs to be rebooted", 20,30)
    $message2 = GUICtrlCreateLabel("Please take time to reboot your computer.", 20,50)
    
    GUISetState()
    While 1
        $msg = GUIGetMsg()
        If $msg = $GUI_EVENT_CLOSE Then Exit
        If $msg = $go Then Shutdown(6) 
        If $msg = $quit Then ExitLoop
    WEnd
    GUIDelete($inst_win)
    Exit
else
;Compueter does NOT need a reboot
;MsgBox(0, "Reboot Not Needed", "No restart needed")
EndIf
Edited by Mike Caouette
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...