Mike Caouette Posted March 30, 2006 Share Posted March 30, 2006 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 andhttp://myitforum.com/articles/6/print_view.asp?id=8833one 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\UpdateExeVolatile0 -> no restart is pending1 -> a software update removal is pending a restart2 -> a software update installation is pending a restart3 -> Both install and removal are pending a restartI 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!-Mikeexpandcollapse popup; ========================================================================== ; 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 More sharing options...
Mike Caouette Posted March 30, 2006 Author Share Posted March 30, 2006 What? No takers? Link to comment Share on other sites More sharing options...
Moderators big_daddy Posted March 30, 2006 Moderators Share Posted March 30, 2006 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 More sharing options...
Mike Caouette Posted March 30, 2006 Author Share Posted March 30, 2006 Thanks big_daddy! That's the part I'm struggling with. I think I know how to read the first one... the 2nd one is giving me fits! -Mike Link to comment Share on other sites More sharing options...
Uten Posted March 30, 2006 Share Posted March 30, 2006 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. Please keep your sig. small! Use the help file. Search the forum. Then ask unresolved questions :) Script plugin demo, Simple Trace udf, TrayMenuEx udf, IOChatter demo, freebasic multithreaded dll sample, PostMessage, Aspell, Code profiling Link to comment Share on other sites More sharing options...
Moderators big_daddy Posted March 30, 2006 Moderators Share Posted March 30, 2006 (edited) 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 March 30, 2006 by big_daddy Link to comment Share on other sites More sharing options...
Mike Caouette Posted March 30, 2006 Author Share Posted March 30, 2006 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 More sharing options...
Mike Caouette Posted March 30, 2006 Author Share Posted March 30, 2006 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 More sharing options...
Moderators big_daddy Posted March 30, 2006 Moderators Share Posted March 30, 2006 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 More sharing options...
Mike Caouette Posted March 30, 2006 Author Share Posted March 30, 2006 Seems to work! I'll test it on a couple of other machines to verify, but this looks like it did it. Thanks big_daddy! Link to comment Share on other sites More sharing options...
Moderators big_daddy Posted March 30, 2006 Moderators Share Posted March 30, 2006 Seems to work! I'll test it on a couple of other machines to verify, but this looks like it did it. Thanks big_daddy!Glad to help, let me know if you have any problems with it. Link to comment Share on other sites More sharing options...
Mike Caouette Posted March 31, 2006 Author Share Posted March 31, 2006 (edited) In case anyone is interested... here is the final script: -Mike expandcollapse popup; ---------------------------------------------------------------------------- ; ; 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 March 31, 2006 by Mike Caouette MaxTrax 1 Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now