Tec Posted August 13, 2009 Share Posted August 13, 2009 Hi all I create a simple WindowsUpdate script to Update my Clients at work. I use a WSUS Server too. But sometimes I want to update the client as quickly as possible. It creates a vbs script on the client and a scheduled task to start the vbs script. View the Client Eventlog for update status. I test this with Windows XP SP3. expandcollapse popup#include <Date.au3> #RequireAdmin Opt('MustDeclareVars', 1) Global $strComputer = InputBox("Force Windows Updates", "Enter Computername to force updates:", "", "", 250, 120) If @error = 1 OR $strComputer = "" Then Exit EndIf Global $strpassword = InputBox("Administrator Password", "Please enter " & $strComputer & "\Administrator password to create the scheduled task:", "", "*", 250, 130) If @error = 1 OR $strpassword = "" Then Exit EndIf Global $strPatchScript = "\\" & $strComputer & "\c$\patchscript.vbs" Global $strJobfile = "\\"& $strComputer & "\admin$\tasks\WindowsUpdate.job" Local $strUserName = $strComputer & "\Administrator" Local $strExe = "\\" & $strComputer & "\admin$\system32\wscript.exe c:\patchscript.vbs " Local $strNewTime = _RemoteDateTime() If @OSLang = "0407" Then Local $strSC = "EINMAL" Else Local $strSC = "ONCE" EndIf Global $strCommand = "SCHTASKS /s " & $strComputer & " /Create /SC " & $strSC & " /TN WindowsUpdate /TR " & chr(34) & $strExe & chr(34) & " /ST "& $strNewTime & " /RU " & chr(34) & $strUserName & chr(34) & " /RP " & chr(34) & $strpassword & chr(34) _PatchScript() Exit Func _RemoteDateTime() Local $strRmtDate, $strRmtTime, $strTime Dim $objWMI = ObjGet("winmgmts:\\" & $strComputer & "\root\CIMV2") If IsObj($objWMI) Then Dim $colItems = $objWMI.ExecQuery("SELECT * FROM Win32_Localtime") For $objItem In $colItems $strRmtDate = $objItem.Year & "/" & $objItem.Month & "/" & $objItem.Day $strRmtTime = $objItem.Hour & ":" & $objItem.Minute & ":" & $objItem.Second Next $strRmtTime = _DateAdd("n", 2, $strRmtDate & " " & $strRmtTime) $strTime = _DateTimeFormat($strRmtTime, 5) Return String($strTime) Else MsgBox(16, "Error", "Failed to connect to WMI at !!!") Exit EndIf EndFunc Func _PatchScript() Local $TextStream Local $strScript = "Dim strEventText" & @CRLF & _ "strEventText = "& chr(34) & chr(34) & @CRLF & _ "Set objShell = Wscript.CreateObject(" & chr(34) & "Wscript.Shell" & chr(34) & ")" & @CRLF & _ "Set objSession = CreateObject(" & chr(34) & "Microsoft.Update.Session" & chr(34) & ")" & @CRLF & _ "Set AutoUpdate = CreateObject(" & chr(34) & "Microsoft.Update.AutoUpdate" & chr(34) & ")" & @CRLF & _ @CRLF & _ "Set UpdateSearcher = objSession.CreateUpdateSearcher" & @CRLF & _ "Set SearchResult = UpdateSearcher.Search(" & chr(34) & " IsAssigned=1 and IsHidden=0 and IsInstalled=0 and Type='Software'" & chr(34) & ")" & @CRLF & _ @CRLF & _ "Autoupdate.DetectNow()" & @CRLF & _ @CRLF & _ "If searchResult.Updates.Count = 0 Then" & @CRLF & _ " objShell.LogEvent 4, " & chr(34) & "No updates to install. Script terminated." & chr(34) & @CRLF & _ " DeleteSelf" & @CRLF & _ " WScript.Quit(0)" & @CRLF & _ "End If " & @CRLF & _ @CRLF & _ "strEventText = " & chr(34) & "The following updates will be installed:" & chr(34) & " & vbCRLF" & @CRLF & _ "Set updatesToDownload = CreateObject(" & chr(34) & "Microsoft.Update.UpdateColl" & chr(34) & ")" & @CRLF & _ "For i = 0 To SearchResult.Updates.Count-1" & @CRLF & _ " Set update = SearchResult.Updates.Item(I) " & @CRLF & _ " strEventText = strEventText & I + 1 & " & chr(34) & "> " & chr(34) & " & update.Title & vbCRLF" & @CRLF & _ " If Not update.EulaAccepted Then update.AcceptEula " & @CRLF & _ " updatesToDownload.Add(update)" & @CRLF & _ "Next" & @CRLF & _ "objShell.LogEvent 4, strEventText" & @CRLF & _ @CRLF & _ "Set downloader = objSession.CreateUpdateDownloader()" & @CRLF & _ "downloader.Updates = updatesToDownload" & @CRLF & _ "downloader.Download()" & @CRLF & _ @CRLF & _ "Set UpdatesToInstall = CreateObject(" & chr(34) & "Microsoft.Update.UpdateColl" & chr(34) & ")" & @CRLF & _ "For I = 0 To searchResult.Updates.Count-1" & @CRLF & _ " set update = searchResult.Updates.Item(I)" & @CRLF & _ " If update.IsDownloaded = true Then" & @CRLF & _ " UpdatesToInstall.Add(update)" & @CRLF & _ " End If" & @CRLF & _ "Next" & @CRLF & _ @CRLF & _ "Set installer = objSession.CreateUpdateInstaller()" & @CRLF & _ "installer.Updates = updatesToInstall" & @CRLF & _ "installer.Install()" & @CRLF & _ @CRLF & _ "Set objSysInfo = CreateObject(" & chr(34) & "Microsoft.Update.SystemInfo" & chr(34) & ")" & @CRLF & _ "If objSysInfo.RebootRequired Then" & @CRLF & _ " objShell.LogEvent 4, " & chr(34) & "Completed the installation of updates. Restart required..." & chr(34) & @CRLF & _ " Set objWMIService = GetObject(" & chr(34) & " winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2" & chr(34) & ")" & @CRLF & _ " Set objEnum = objWMIService.ExecQuery(" & chr(34) & " Select __relpath from win32_process where caption = 'explorer.exe'" & chr(34) & ")" & @CRLF & _ " If objEnum.Count = 0 then" & @CRLF & _ " objShell.LogEvent 4, " & chr(34) & "Force Restart. No User online..." & chr(34) & @CRLF & _ " Set OpSysSet = GetObject(" & chr(34) & "winmgmts:{(Shutdown)}//./root/cimv2" & chr(34) & ").ExecQuery(" & chr(34) & "select * from Win32_OperatingSystem where Primary=true" & chr(34) & ") " & @CRLF & _ " Const EWX_REBOOT = 2 " & @CRLF & _ " Const EWX_FORCE = 4" & @CRLF & _ " For each OpSys in OpSysSet" & @CRLF & _ " opSys.win32shutdown EWX_REBOOT + EWX_FORCE" & @CRLF & _ " Next" & @CRLF & _ " End If" & @CRLF & _ "Else" & @CRLF & _ " objShell.LogEvent 4, " & chr(34) & "Completed the installation of updates. No restart is required." & chr(34) & @CRLF & _ "End If" & @CRLF & _ @CRLF & _ "DeleteSelf" & @CRLF & _ "WScript.Quit(0)" & @CRLF & _ @CRLF & _ "Sub DeleteSelf()" & @CRLF & _ " Dim objFSO" & @CRLF & _ " Set objFSO = CreateObject(" & chr(34) & "Scripting.FileSystemObject" & chr(34) & ")" & @CRLF & _ " objFSO.DeleteFile WScript.ScriptFullName" & @CRLF & _ " Set objFSO = Nothing" & @CRLF & _ "End Sub" Local $fso = ObjCreate("Scripting.FileSystemObject") If IsObj($fso) Then If $fso.FileExists($strPatchScript) Then $fso.DeleteFile($strPatchScript, true) EndIf $TextStream = $fso.CreateTextFile($strPatchScript) $TextStream.Write($strScript) $TextStream.Close If $fso.FileExists($strJobFile) Then $fso.DeleteFile($strJobFile, True) EndIf Else MsgBox(16, "Error", "Failed to create FileSystemObject !!!") Exit EndIf Dim $wshShell = ObjCreate("WScript.Shell") Local $retval = $wshShell.Run($strCommand, 0, True) If $retval = 0 Then MsgBox(0, "Windows Update","The patch task was successfully created to start at " & $strNewTime) Else MsgBox(16, "Error", "There were problems creating the patch task. ") EndIf EndFunc The client vbs script. You dont need this. Only for clear view. expandcollapse popupDim strEventText strEventText = "" Set objShell = Wscript.CreateObject("Wscript.Shell") Set objSession = CreateObject("Microsoft.Update.Session") Set AutoUpdate = CreateObject("Microsoft.Update.AutoUpdate") Set UpdateSearcher = objSession.CreateUpdateSearcher Set SearchResult = UpdateSearcher.Search(" IsAssigned=1 and IsHidden=0 and IsInstalled=0 and Type='Software'") Autoupdate.DetectNow() If searchResult.Updates.Count = 0 Then objShell.LogEvent 4, "No updates to install. Script terminated." DeleteSelf WScript.Quit(0) End If strEventText = "The following updates will be installed:" & vbCRLF Set updatesToDownload = CreateObject("Microsoft.Update.UpdateColl") For i = 0 To SearchResult.Updates.Count-1 Set update = SearchResult.Updates.Item(I) strEventText = strEventText & I + 1 & "> " & update.Title & vbCRLF If Not update.EulaAccepted Then update.AcceptEula updatesToDownload.Add(update) Next objShell.LogEvent 4, strEventText Set downloader = objSession.CreateUpdateDownloader() downloader.Updates = updatesToDownload downloader.Download() Set UpdatesToInstall = CreateObject("Microsoft.Update.UpdateColl") For I = 0 To searchResult.Updates.Count-1 set update = searchResult.Updates.Item(I) If update.IsDownloaded = true Then UpdatesToInstall.Add(update) End If Next Set installer = objSession.CreateUpdateInstaller() installer.Updates = updatesToInstall installer.Install() Set objSysInfo = CreateObject("Microsoft.Update.SystemInfo") If objSysInfo.RebootRequired Then objShell.LogEvent 4, "Completed the installation of updates. Restart required..." Set objWMIService = GetObject(" winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2") Set objEnum = objWMIService.ExecQuery(" Select __relpath from win32_process where caption = 'explorer.exe'") If objEnum.Count = 0 then objShell.LogEvent 4, "Force Restart. No User online..." Set OpSysSet = GetObject("winmgmts:{(Shutdown)}//./root/cimv2").ExecQuery("select * from Win32_OperatingSystem where Primary=true") Const EWX_REBOOT = 2 Const EWX_FORCE = 4 For each OpSys in OpSysSet opSys.win32shutdown EWX_REBOOT + EWX_FORCE Next End If Else objShell.LogEvent 4, "Completed the installation of updates. No restart is required." End If DeleteSelf WScript.Quit(0) Sub DeleteSelf() Dim objFSO Set objFSO = CreateObject("Scripting.FileSystemObject") objFSO.DeleteFile WScript.ScriptFullName Set objFSO = Nothing End Sub Link to comment Share on other sites More sharing options...
spudw2k Posted August 13, 2009 Share Posted August 13, 2009 I did something like this too. I basically converted a vb script to autoit; we then push out the file remotely. expandcollapse popup#include <misc.au3> #include <Array.au3> #NoTrayIcon $oMyError = ObjEvent("AutoIt.Error","MyErrFunc") Opt("TrayMenuMode",1) TraySetIcon("Shell32.dll",-47) Global $reboot=0 TraySetToolTip("Automatic Updates - Checking for Needed Patches") $patches = _CollectPatches() If Not IsObj($patches) Then Exit If $patches.Updates.Count > 0 Then TraySetToolTip("Automatic Updates - Found " & $patches.Updates.Count & _Iif($patches.Updates.Count > 1," Patches"," Patch")) _UpdatesDownloadAndInstall($patches) Else TraySetToolTip("Automatic Updates - No Patches Needed.") EndIf Do sleep(10000) Until $reboot=0 Func _CreateMSUpdateSession($strHost = @ComputerName) $objSession = ObjCreate("Microsoft.Update.Session",$strHost) If Not IsObj($objSession) Then Return 0 Return $objSession EndFunc Func _CreateSearcher($objSession) If Not IsObj($objSession) Then Return -1 Return $objSession.CreateUpdateSearcher EndFunc Func _CollectPatches() $objSearcher = _CreateSearcher(_CreateMSUpdateSession()) $colNeeded = _GetNeededUpdates($objSearcher) $objSearcher = 0 Return $colNeeded EndFunc Func _Force() EndFunc Func _GetNeededUpdates($objSearcher) If Not IsObj($objSearcher) Then Return -5 $colNeeded = $objSearcher.Search("IsInstalled=0 and Type='Software'") Return $colNeeded EndFunc Func _UpdatesDownloadAndInstall($colNeeded) $objSearcher = _CreateMSUpdateSession() For $i = 0 To $colNeeded.Updates.Count-1 $update = $colNeeded.Updates.Item($i) ;If $item = $update.Title Then TraySetToolTip("Automatic Updates - Downloading " & ($i+1) & " of " & $colNeeded.Updates.Count) $updatesToDownload = ObjCreate("Microsoft.Update.UpdateColl") $updatesToDownload.Add ($update) $DownloadSession = $objSearcher.CreateUpdateDownloader() $DownloadSession.Updates = $updatesToDownload $DownloadSession.Download ;EndIf Next For $i = 0 To $colNeeded.Updates.Count-1 $update = $colNeeded.Updates.Item($i) ;If $item = $update.Title And $update.IsDownloaded Then If $update.IsDownloaded Then TraySetToolTip("Automatic Updates - Installing " & ($i+1) & " of " & $colNeeded.Updates.Count) $InstallSession = $objSearcher.CreateUpdateInstaller() $updatesToInstall = ObjCreate("Microsoft.Update.UpdateColl") $updatesToInstall.Add($update) $InstallSession.Updates = $updatesToInstall $installresult = $InstallSession.Install If $installresult.RebootRequired Then $reboot = 1 EndIf Next If $reboot Then TraySetToolTip("Automatic Updates - Patching Complete. A Reboot is Required.") Else TraySetToolTip("Automatic Updates - Patching Complete.") EndIf $DownloadSession = 0 $updatesToDownload = 0 Return 0 EndFunc Func MyErrFunc() Exit Endfunc Spoiler Things I've Made: Always On Top Tool ◊ AU History ◊ Deck of Cards ◊ HideIt ◊ ICU ◊ Icon Freezer ◊ Ipod Ejector ◊ Junos Configuration Explorer ◊ Link Downloader ◊ MD5 Folder Enumerator ◊ PassGen ◊ Ping Tool ◊ Quick NIC ◊ Read OCR ◊ RemoteIT ◊ SchTasksGui ◊ SpyCam ◊ System Scan Report Tool ◊ System UpTime ◊ Transparency Machine ◊ VMWare ESX BuilderMisc Code Snippets: ADODB Example ◊ CheckHover ◊ Detect SafeMode ◊ DynEnumArray ◊ GetNetStatData ◊ HashArray ◊ IsBetweenDates ◊ Local Admins ◊ Make Choice ◊ Recursive File List ◊ Remove Sizebox Style ◊ Retrieve PNPDeviceID ◊ Retreive SysListView32 Contents ◊ Set IE Homepage ◊ Tickle Expired Password ◊ Transpose ArrayProjects: Drive Space Usage GUI ◊ LEDkIT ◊ Plasma_kIt ◊ Scan Engine Builder ◊ SpeeDBurner ◊ SubnetCalcCool Stuff: AutoItObject UDF ◊ Extract Icon From Proc ◊ GuiCtrlFontRotate ◊ Hex Edit Funcs ◊ Run binary ◊ Service_UDF Link to comment Share on other sites More sharing options...
res2cpu Posted August 14, 2009 Share Posted August 14, 2009 I work in a computer store where we build and sell more pc's a day then i care to count, i use the same kind of thing. Its a bit annoying how Microsoft don't send out all updates to the wsus servers as it means we still have to eat bandwidth getting them upto date. 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