Script for installing Microsoft security updates

arunykand
arunykand used Ask the Experts™
on
Hi,
      I would like to know if there is a way to install a list of Microsoft security patches via VB-Script or Batch files, etc.  Let's assume that I have downloaded 4 security patches from MS (Ex: KB12345, KB56789....etc) and burned them onto a CD and I run a script that is present on the CD that will go ahead and install the specified KB patches to the target computer (Including reboot if necessary after installing certain patches, and after reboot pickup installing the patches where it left of).  

I need to update 50 or so computers and it will be tedious to update each and every one of them manually, therefore i'm looking for a way to automate installing the updates.  

These are for Windows XP machines...

Thanks and any input/help is greatly appreciated!
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
If the 50+ computers are somehow connected to your network, use WSUS.
It uses BITS to download the updates, so even a small-band connections will be enough to get the updates down to the computer after a while. Reporting, retrying everything is handled by the WSUS agent.

If you want to stay with the CD solution:


Create a small batch:

for %%a in (Windows*.exe) do %%a /quiet /norestart
shutdown -r -t 5

This will install all patches on the disk and restart the computer afterwards.

HTH
Jason WatkinsIT Project Leader

Commented:
I have to jump on the WSUS band-wagon as well.
Acronis in Gartner 2019 MQ for datacenter backup

It is an honor to be featured in Gartner 2019 Magic Quadrant for Datacenter Backup and Recovery Solutions. Gartner’s MQ sets a high standard and earning a place on their grid is a great affirmation that Acronis is delivering on our mission to protect all data, apps, and systems.

Chris BRetired

Commented:
If the PC's are not networked, then consider autopatcher -

http://www.autopatcher.com/

Chris B

Author

Commented:
Ok, I heard a lot of 'WSUS'.  I am not exactly sure what it is or how to implement it for my problem.
Thanks
I agree with the WSUS votes.  However, there some rare situations where you cannot use WSUS.  Most patches can be installed and then you can reboot after all patches are installed.  However, some cannot.  What I do is have a few different scripts (Step1_XP.vbs, Step2_XP.vbs, etc) that then run in sequence.  At the end of each script, it reboots if necessary and puts the next script in the startup menu.  This will then call that step upon reboot.  The script can be set to loop through all files in a folder and install them.  It also checks to see if the patch has already been installed be installing.   If you are interested in going this path rather than the recommended WSUS, you can adapt the code below.  (I had to pull out some confidential stuff so I have not retested this code, but it should work).  The user running the script must have access to the registry as this will view and update the registry.

Option Explicit

' ******************
' Declare Variables
' ******************
Dim objExplorer								' Object to Display Internet Explorer Progress Message Window
Dim strIEMsg, strMsgH1, strMsgH2, strMsgM	' Strings to build IE Messages
Dim strMsgL, strMsgL2
Dim objShell, objFSO, strReturn				' Objects to access Windows Shell and the File System Object
Dim objFolder, objFiles, objFile			' Objects to parse through List of patches to install
Dim strFixPath, strWinSys					' File paths to Patch EXE files for installation
Dim arrKB(), blnReboot, blnFound, intKBCnt	' Array to store list of KB articles to look for and install
Dim intToInstall, intInstalled, intCnt		' Counters to keep track of patches for users
Dim intPos									' Variables to look for KB number in File name
Dim objRegistry, strRegKey, intRegValue		' objects/variables to look at registry
Dim strKey, arrSubKeys, strRegName, strRegValue
Dim objMainFolder, objFolders, strProfiles	' Objects for moving startup items.

' Set Constants
Const STEPNUM =  1' ###  Enter Step Number Here
Const OSPATCH = "Windows XP"  ' Message Title for Patch Updates - OS Type
Const VBFILE = "_WinXP.vbs" ' End of File Name - example Step1_XP.vbs:  VBFILE = _XP.vbs
Const COMPUTER = "."
Const HKLM = &H80000002 ' Registry Hive for HHKEY_LOCAL_MACHINE

' Instantiate Objects and set defaults
Set objShell = CreateObject("WScript.Shell")
Set objFSO = CreateObject("Scripting.FileSystemObject")
strProfiles = objShell.ExpandEnvironmentStrings("%SYSTEMDRIVE%") & "\Documents and Settings"
strFixPath="C:\Patches"
strWinSys=objShell.ExpandEnvironmentStrings("%Windir%") & "\system32"
blnReboot = false
Set objRegistry = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & _
        COMPUTER & "/root/default:StdRegProv")
strRegKey = "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\"
intRegValue = objRegistry.EnumKey(HKLM, strRegKey, arrSubKeys)
intToInstall = 0
intInstalled = 0

Call ShowIE

' ******************
' Load List of Patches to Install
' ******************
Set objFolder = objFSO.GetFolder(strFixPath)
Set objFiles = objFolder.Files
intKBCnt = 0
ReDim arrKB(objFiles.count, 3)
For each objFile in objFiles
	' Look for KB Number in File Name
	intPos = instr(1, objFile.Name, "KB", VBTEXTCOMPARE)
	arrKB(intKBCnt, 0) =  mid(objFile.Name, intPos, instr(intPos, objFile.Name, "-") - intPos)
	arrKB(intKBCnt,1) = objFile.Name
	arrKB(intKBCnt,2) = """" & strFixPath & "\" & objFile.name & """ /norestart /quiet"
	intKBCnt = intKBCnt + 1
Next

' ******************
' Start Message Window
' ******************
strMsgH1 = "Running Step " & STEPNUM & " of the " & OSPATCH & " Updates/Hotfixes"
strMsgH1 = strMsgH1 & "<BR/>&nbsp;&nbsp;If necessary, the system will reboot when complete<BR>"
strIEMsg = strMsgH1
On Error Resume Next
objExplorer.Document.Body.InnerHTML = strIEMsg

If Err.Number <> 0 Then
	On Error Goto 0
	Call ShowIE
	objExplorer.Document.Body.InnerHTML = strIEMsg
Else
	On Error Goto 0
End IF

' ******************
' Check for Installation of Hotfixes
' ******************
For Each strKey In arrSubKeys
	' Reset Search defaults
	blnFound = False
	intCnt = 0

	' Grab registry Data
	intRegValue = objRegistry.GetStringValue(HKLM, strRegKey & strKey, "DisplayName", strRegValue)
	
	If intRegValue <> 0 Then
		objRegistry.GetStringValue HKLM, strRegKey & strKey, "QuietDisplayName", strRegValue
	End If
	
	' Check if this is on the list of updates
	Do While Not blnFound and intCnt <= intKBCnt
		If instr(strRegValue, arrKB(intCnt,0)) > 0 Then
			arrKB(intCnt,3)=True
			blnFound = True
		End If
		intCnt = intCnt + 1
	Loop
Next

strMsgH2 =  strMsgH2 & "<BR>Review is Complete.  Installing necessary Patches<BR>"
strIEMsg = strMsgH1 & strMsgH2
On Error Resume Next
objExplorer.Document.Body.InnerHTML = strIEMsg

If Err.Number <> 0 Then
	On Error Goto 0
	Call ShowIE
	objExplorer.Document.Body.InnerHTML = strIEMsg
Else
	On Error Goto 0
End IF

' ******************
' Installation of Hotfixes
' ******************
' Set Break and Header for List of Installed
strMsgL = "<BR>_________________________"
strMsgL = strMsgL & "<BR>COMPLETED LIST:"

' Count How many patches need to be installed
For intCnt = 0 to intKBCnt
	' If this patch was not found, increment counter
	If NOT arrKB(intCnt, 3) Then intToInstall = intToInstall + 1
Next

' Loop Through Array and Install
For intCnt = 0 to intKBCnt
	' If this patch was not found, install patch
	If NOT arrKB(intCnt, 3) Then
		intInstalled = intInstalled + 1
		blnReboot = true
		strMsgM = "<BR><strong>Currently Installing " & arrKB(intCnt,1) 
		strMsgM = strMsgM & "<BR>Patch " & intInstalled & " of " & intToInstall & "</strong>"
		strIEMsg = strMsgH1 & strMsgH2 & strMsgM & strMsgL & strMsgL2
		On Error Resume Next
		objExplorer.Document.Body.InnerHTML = strIEMsg

		If Err.Number <> 0 Then
			On Error Goto 0
			Call ShowIE
			objExplorer.Document.Body.InnerHTML = strIEMsg
		Else
			On Error Goto 0
		End IF

		strReturn = objShell.Run (arrKB(intCnt,2), 1, true)
		strMsgL2 = "<LI>" & arrKB(intCnt,1) & strMsgL2
	End If
Next

' ******************
' Finalize and Reboot
' ******************
' Reboot Machine
If blnReboot then
	' Set Next Script to Run after Reboot via RunOnce
	strRegKey = "Software\Microsoft\Windows\CurrentVersion\RunOnce"
	strRegName = "WindowsUpdateScripts"
	strRegValue = strFixPath &  "\Step" & STEPNUM + 1 & VBFILE
	objRegistry.SetStringValue HKCU,strRegkey,strRegName,strRegValue
	
	strMsgH2 = "<BR>Installation of Patches has completed"
	strMsgM = "<BR><BR><Strong>System will now reboot</strong>"
	strIEMsg = strMsgH1 & strMsgH2 & strMsgM & strMsgL & strMsgL2
	objExplorer.Document.Body.InnerHTML = strIEMsg
	Wscript.sleep 3000

	Call ReleaseVar()

	objShell.run "shutdown -r -t 2"

Else
	' Run Next File
	strMsgH2 = "<BR>All Patches were already installed"
	strMsgM = "<BR>Moving to Step " & STEPNUM + 1
	strIEMsg = strMsgH1 & strMsgH2 & strMsgM
	objExplorer.Document.Body.InnerHTML = strIEMsg
	Wscript.sleep 3000
	
	Call ReleaseVar()

	objShell.Run """" & strFixPath &  "\Step" & STEPNUM + 1 & VBFILE & """"

End If

Set objShell = nothing

Wscript.quit

' ******************
' Release Variables
' ******************
Private Sub ReleaseVar()
	' Release objects
	objExplorer.Quit
	Set objExplorer = nothing
	Set objFSO = nothing
	Set objRegistry = nothing
End Sub

' ******************
' Show Internet Explorer Window
' ******************
Private Sub ShowIE
	' Instantiate Object
	Set objExplorer = WScript.CreateObject("InternetExplorer.Application")
	
	' Set Window Defaults
	objExplorer.Navigate "about:blank"   
	objExplorer.ToolBar = 0
	objExplorer.StatusBar = 0
	objExplorer.Width=600
	objExplorer.Height = 550 
	objExplorer.Left = 0
	objExplorer.Top = 0
	
	' Start Message Window
	Do While (objExplorer.Busy)
		Wscript.Sleep 200
	Loop 
	objExplorer.Visible = 1
End Sub

Open in new window

Author

Commented:
ltlbearand3: Thanks for the sample script....Going through it, almost all of it makes sense to me, but I am a little unsure about '' Set Next Script to Run after Reboot via RunOnce'.  I understand the concept that the "first script" will (before rebooting) copy the "second script" to the startup directory so that it will run upon startup.  My question is, is the "second script" same as the "first script" or is that different?

Thanks
It would pretty much be the same, just point to a different directory with the set of scripts to run after the reboot.  You might want to check all your scripts and see if you can install them all together and then reboot.  

-Bear
If your workstations are joined to a domain, then WSUS is the best long-term solution.  A script will no doubt be helpful for some situations, and you could use it to meet your immediate requirements, but in the long run WSUS is much easier and more reliable.  I would advise you check out the Technet link provided in Post #33151348 above if you're in a position to use WSUS.
DonNetwork Administrator

Commented:
Here's a very good Step-By-Step guide to get you up and running on WSUS
 
http://blogs.microsoft.co.il/blogs/yanivf/archive/2007/09/23/install-wsus-3-0-step-by-step.aspx
 
WSUS will save you alot of work and headache
DonNetwork Administrator

Commented:
You might find this interesting as well, if for some reason you dont want to use WSUS just yet.
 
http://www.megaleecher.net/WSUS_Offline_Updater_Client 

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial