(NOTE: This was tested on Windows Vista only with SP 1. For windows XP you need to install the latest Windows Update Agent first before using. Admin privilages are needed - on Vista this is not an issue because the first account created in a Vista install has the necessary privilages (the first account is an admin privilage account and in my case this was the case because it was a fresh clean install pushed down, however, on XP this is not the case and you need to make sure the account has sufficient privilages on XP before using this.)
Code: Select all
XIncludeFile "COMate.pbi"
Procedure WMIReboot()
Define.COMateObject objWMIService, Reboot_Sys
colREBOOT.COMateEnumObject
strComputer.s = "."
objWMIService = COMate_GetObject("winmgmts:\\" + strComputer + "\root\cimv2", "")
If objWMIService
colREBOOT = objWMIService\CreateEnumeration("ExecQuery('Select * from Win32_OperatingSystem')")
If colREBOOT
Reboot_Sys = colREBOOT\GetNextObject()
While Reboot_Sys
Reboot_Sys\Invoke("Reboot()")
Reboot_Sys\Release()
Reboot_Sys = colREBOOT\GetNextObject()
Wend
colREBOOT\Release()
EndIf
objWMIService\Release()
Else
MessageRequester("Error", "RebootInfo")
EndIf
EndProcedure
Procedure WindowsUpdate_Download_Install() ; downloads and installs updates from Windows Update
Protected updateSession.COMateObject
Protected updateSearcher.COMateObject
Protected searchResult.COMateObject
Protected update.COMateObject
Protected Updates.COMateObject
Protected objItem.COMateObject
Protected updatesToDownload.COMateObject
Protected downloader.COMateObject
Protected DownloadResult.COMateObject
Protected updatesToInstall.COMateObject
Protected installer.COMateObject
Protected installationResult.COMateObject
Protected UpdateResult.COMateObject
Protected objItemToInstall.COMateObject
Protected objUpdateDownloadResult.COMateObject
updateSession = COMate_CreateObject("Microsoft.Update.Session")
updateSearcher = updateSession\GetObjectProperty("CreateUpdateSearcher()")
Debug "********************************************************" + #CRLF$
Debug "Searching for available items from Windows Update..." + #CRLF$
Debug "********************************************************" + #CRLF$
searchResult = updateSearcher\GetObjectProperty("Search('IsInstalled=0')") ; to get all updates for driver and software
;searchResult = updateSearcher\GetObjectProperty("Search('IsInstalled=0 and Type=$0027Software$0027')") ; to get updates for software only
;searchResult = updateSearcher\GetObjectProperty("Search('IsInstalled=0 and Type=$0027Driver$0027')") ; to get updates for drivers only
Updates = searchResult\GetObjectProperty("Updates()")
count = Updates\GetIntegerProperty("Count()")
; if there is just nothing at all
If count = 0
Debug #CRLF$
Debug "***********************" + #CRLF$
;Debug count
Debug Str(count) + " updates available"
Debug "***********************" + #CRLF$
updateSession\Release()
End
EndIf
; if there is something then we press on....
For I = 0 To count - 1
xfound = xfound
update = searchResult\GetObjectProperty("Updates()")
objItem = update\GetObjectProperty("Item('" + Str(I) + "')")
exclude_download$ = objItem\GetStringProperty("Title()") ; filter
If FindString(exclude_download$, "Update", 1) > 0 ; filter
xfound = xfound + 1 ; if it is an update each loop pass we add 1 to xfound
EndIf
Debug Str(I + 1) + " >>> " + objItem\GetStringProperty("Title")
Next
; if there were no actual updates we might as well make sure we quit
If count => 1 And xfound = 0
;If count = 0
Debug #CRLF$
Debug "////////////////////////////////////////" + #CRLF$
Debug "No actual updates available"
Debug "////////////////////////////////////////" + #CRLF$
updateSession\Release()
End
EndIf
;////////Collection//////////////
Debug #CRLF$
Debug "**********************************************" + #CRLF$
Debug "Creating collection of updates to download:"
Debug "**********************************************" + #CRLF$
Debug #CRLF$
updatesToDownload = COMate_CreateObject("Microsoft.Update.UpdateColl")
For I = 0 To count - 1
update = searchResult\GetObjectProperty("Updates()")
objItem = update\GetObjectProperty("Item('" + Str(I) + "')")
Debug Str(I + 1) + "> adding: " + objItem\GetStringProperty("Title()")
index = updatesToDownload\GetIntegerProperty("Add(" + Str(objItem) + " as COMateobject)")
Next
;////////////Downloader//////////////
Debug #CRLF$
Debug "Downloading updates..."
Debug #CRLF$
downloader = updateSession\GetObjectProperty("CreateUpdateDownloader()")
downloader\SetProperty("Updates(" + Str(updatesToDownload) + " as COMateobject)")
DownloadResult = downloader\GetObjectProperty("Download()")
For I = 0 To count - 1
update = searchResult\GetObjectProperty("Updates()")
objItem = update\GetObjectProperty("Item('" + Str(I) + "')")
exclude_download$ = objItem\GetStringProperty("Title") ; filter
objUpdateDownloadResult = DownloadResult\GetObjectProperty("GetUpdateResult(" + Str(I) + ")")
Select objUpdateDownloadResult\GetIntegerProperty("ResultCode()")
Case 0
DownloadResultCode$ = "Download Operation has not started."
Case 1
DownloadResultCode$ = "Download Operation is in progress."
Case 2
DownloadResultCode$ = "Download Operation completed successfully."
Case 3
DownloadResultCode$ = "Download Operation completed, but one or more errors occurred during the operation and the results are potentially incomplete."
Case 4
DownloadResultCode$ = "Download Operation failed to complete."
Case 5
DownloadResultCode$ = "Download Operation was aborted."
Default
DownloadResultCode$ = "Download Operation result could not be determined."
EndSelect
If objItem\GetIntegerProperty("IsDownloaded()") <> 0
Debug Str(I + 1) + "> " + objItem\GetStringProperty("Title") + " Download Status: " + DownloadResultCode$
EndIf
Next
;/////////Installer///////////////////
;
;
;///install collection
updatesToInstall = COMate_CreateObject("Microsoft.Update.UpdateColl")
Debug #CRLF$
Debug "Creating collection of downloaded updates to install:"
Debug #CRLF$
For I = 0 To count - 1
update = searchResult\GetObjectProperty("Updates()")
objItem = update\GetObjectProperty("Item('" + Str(I) + "')")
exclude_download$ = objItem\GetStringProperty("Title") ; filter
If FindString(exclude_download$, "Update", 1) > 0 ; filter here to keep anything but what we want out of the install collection
objItem\Invoke("AcceptEula()") ; this accepts the EULA automatically when needed, not all updates need it, mostly addin's
If objItem\GetIntegerProperty("IsDownloaded()") <> 0
Debug Str(I + 1) + "> install adding: " + objItem\GetStringProperty("Title()")
index = updatesToInstall\GetIntegerProperty("Add(" + Str(objItem) + " as COMateobject)")
EndIf
EndIf ; filter
;
Next
; ;////actual installer
Debug "Installing updates..." ; will only install whats in the install collection
installer = updateSession\GetObjectProperty("CreateUpdateInstaller()")
installer\SetProperty("Updates(" + Str(updatesToInstall) + " as COMateobject)")
installcount = updatesToInstall\GetIntegerProperty("Count()")
countinstalled = installcount - 1
Debug "Install count is = " + Str(installcount)
If installcount => 1 ; installcount should be 0 if the FindString(exclude_download$, "Update", 1) filter doesn't find any updates with the word Update.
; if installcount is => 1 we go ahead with install command
installationResult = installer\GetObjectProperty("Install()")
Else
Debug "Nothing to install."
; if installcount = 0 we don't go any further and just end it
End
EndIf
Select installationResult\GetIntegerProperty("ResultCode()")
Case 0
Operation_Result$ = "Operation has not started."
Case 1
Operation_Result$ = "Operation is in progress."
Case 2
Operation_Result$ = "Operation completed successfully."
Case 3
Operation_Result$ = "Operation completed, but one or more errors occurred during the operation and the results are potentially incomplete."
Case 4
Operation_Result$ = "Operation failed to complete."
Case 5
Operation_Result$ = "Operation was aborted."
Default
Operation_Result$ = "Operation result could not be determined."
EndSelect
reboot = reboot
rebootrequired = installationResult\GetIntegerProperty("RebootRequired()")
If rebootrequired =>1
reboot = reboot + 1
EndIf
;Output results of install
Debug "Installation Result Code: " + Operation_Result$
Debug "Reboot Required: " + Str(rebootrequired)
Debug "Listing of updates installed and individual installation results:"
;
For I = 0 To installcount - 1
updatedone = updatedone
objItemToInstall = updatesToInstall\GetObjectProperty("Item('" + Str(I) + "')")
objItemInstall$ = objItemToInstall\GetStringProperty("Title()")
UpdateResult = installationResult\GetObjectProperty("GetUpdateResult(" + Str(I) + ")")
OpResult = UpdateResult\GetIntegerProperty("ResultCode()")
If OpResult = 2
updatedone = updatedone + 1
countinstalled = installcount - 1 ; subtract each one as its installed, when 0 all are installed
Debug "Installs remaining = " + Str(countinstalled)
EndIf
Select OpResult
Case 0
UpdateOperation_Result$ = "Operation has not started."
Case 1
UpdateOperation_Result$ = "Operation is in progress."
Case 2
UpdateOperation_Result$ = "Operation completed successfully."
Case 3
UpdateOperation_Result$ = "Operation completed, but one or more errors occurred during the operation and the results are potentially incomplete."
Case 4
UpdateOperation_Result$ = "Operation failed to complete."
Case 5
UpdateOperation_Result$ = "Operation was aborted."
Default
UpdateOperation_Result$ = "Operation result could not be determined."
EndSelect
Debug Str(I + 1) + "> " + Str(objItemToInstall) + " " + objItemInstall$ + " " + UpdateOperation_Result$
Next
updateSession\Release()
updatesToDownload\Release()
updatesToInstall\Release()
;//////////reboot////////////
;uncomment below to use reboot if needed after install
; If reboot => 1 And countinstalled = 0 And updatedone => 1
; Debug "Rebooting computer in 30 seconds"
; Delay(30000)
; WMIReboot()
; EndIf
EndProcedure
By default, the above code gets updates that are applicapable to your system language and bits. In other words if your system language is German based it will retrieve updates that are for your language along with the others that are also applicapable for your system. It also will retrieve updates that are x64 specific for those with x64 bit operating systems installed, so there is really no need to filter specifically for language or X64 updates because these will be presented anyway because it only retrieves updates based on your system just like you see if you start up the GUI based Windows Update client and do it yourself manually. But, if you really want to, the above code can be setup to 'filter' for specific updates, drives, or service packs using the Microsoft naming conventions:
Updates
Service Packs
Security Updates
Critical Updates
x64
or languages (English, French, German, Japanese, Spanish, stc...)
For example, if you want to get all updates that are just x64 German system related then just change the filter 'FindString' where: exclude_download$ = objItem\GetStringProperty("Title") (in the above code):
Code: Select all
If FindString(exclude_download$, "Update", 1) > 0 And FindString(exclude_download$, "x64", 1) > 0 And FindString(exclude_download$, "German", 1) > 0
(although just getting updates that are specifically for x64 is not a good idea because there are updates that are agnostic bit wise and are for both x64 and x86 and don't reflect that in their naming.)
Code: Select all
FindString(exclude_download$, "Critical", 1) > 0
FindString(exclude_download$, "Security", 1) > 0
Code: Select all
FindString(exclude_download$, "Service Pack", 1) > 0
Note: For Service Packs its important to do "Service Pack" and not just "Service" or "Pack" because its possible those words could be included individually in the title for other optional things you might not want, like for example...language packs also include the word "Pack" (but don't include the word "Service"
Code: Select all
If FindString(exclude_download$, "Update", 1) > 0 And FindString(exclude_download$, "Media Center", 1) > 0
Note: Like for Service Packs above its important to do "Media Center" and not just "Media" or "Center" because its possible those words could be included individually in the title for other optional updates you might not want.
Also, the above gets updates that are not already installed on your system, if for some reason you want to get the updates again change all occurances of 'IsInstalled=0' to 'IsInstalled=1'. But, if you do this these 'duplicate' updates won't install if the system thinks the update is already installed so you will need to add this to force them to install again:
Code: Select all
In the Installer section of the code find this:
If installcount => 1 ; installcount should be 0 if the FindString(exclude_download$, "Update", 1) filter doesn't find any updates with the word Update.
; if installcount is => 1 we go ahead with install command
installationResult = installer\GetObjectProperty("Install()")
Else
Debug "Nothing to install."
; if installcount = 0 we don't go any further and just end it
End
EndIf
And change the area With installationResult = installer\GetObjectProperty("Install()") To this:
If installcount => 1 ; installcount should be 0 if the FindString(exclude_download$, "Update", 1) filter doesn't find any updates with the word Update.
; if installcount is => 1 we go ahead with install command
installer\SetProperty("Install('" + Str(#VARIANT_TRUE) + "')")
installationResult = installer\GetObjectProperty("Install()")
installer\SetProperty("Install('" + Str(#VARIANT_TRUE) + "')")
Else
Debug "Nothing to install."
; if installcount = 0 we don't go any further and just end it
End
EndIf