-
-
'check for running jobs
'check for active patch deployments
'check windows update agent version?
'Performs most of the actions from these KBs
'http://support.microsoft.com/kb/971058
'http://support.microsoft.com/kb/822798
'use "wuauclt.exe /resetauthorization /detectnow" ???
'Do we want to do this?
' Method 9: Clear the temporary file and restart the hotfix installation or the service pack installation
' Note Skip this method if the operating system is Windows 2000.
'
' To clear the temporary file and restart the hotfix installation or the service pack installation, follow these steps:
' Delete all the tmp*.cat files in the following folders:
'
' %systemroot%\system32\CatRoot\{127D0A1D-4EF2-11D1-8608-00C04FC295EE}
'
' %systemroot%\system32\CatRoot\{F750E6C3-38EE-11D1-85E5-00C04FC295EE}
' Delete all the kb*.cat files in the following folders:
' %systemroot%\System32\CatRoot\{F750E6C3-38EE-11D1-85E5-00C04FC295EE}
' %systemroot%\System32\CatRoot\{127D0A1D-4EF2-11D1-8608-00C04FC295EE}
Option Explicit
Dim oFSO, WshShell
Dim sSystemRootLocation
Dim blnStopBITS, blnStopWUAUSERV, blnStartBITS, blnStartWUAUSERV
Dim sOSFromReg
Const sWBEMServiceName = "WinMgmt"
Const sSCCMServiceName = "CCMExec"
Const ForReading = 1, ForWriting = 2, ForAppending = 8
Set oFSO = CreateObject("Scripting.FileSystemObject")
Set WshShell = CreateObject("WScript.Shell")
sSystemRootLocation = WshShell.RegRead("HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\SystemRoot")
sOSFromReg = GetOSFromReg
WScript.Echo sOSFromReg
'Stop BITS/Windows Update Services
Call WriteLogEntry("Stopping Services", True)
blnStopBITS = StopServiceSC("BITS")
blnStopWUAUSERV = StopServiceSC("WUAUSERV")
Call RebuildWMI
'Delete QMGR files
Call DeleteQMGRFiles
'Delete old Patch files
Call Deltree(sSystemRootLocation & "\SoftwareDistribution\DataStore")
Call Deltree(sSystemRootLocation & "\SoftwareDistribution\Download")
Call Deltree(sSystemRootLocation & "\system32\catroot2")
'Reset Security Descriptors
WshShell.Run "sc.exe sdset bits D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;AU)(A;;CCLCSWRPWPDTLOCRRC;;;PU)", 0, True
WshShell.Run "sc.exe sdset wuauserv D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;AU)(A;;CCLCSWRPWPDTLOCRRC;;;PU)", 0 , True
'Register DLLs
Call WriteLogEntry("Registering DLLs", True)
Call RegisterWUDLLs
'Reset WinSock (KB article has the command wrong)
Call WriteLogEntry("Resetting Winsock (" & sSystemRootLocation & "\system32\NETSH.EXE WINSOCK RESET)", True)
WshShell.Run sSystemRootLocation & "\system32\NETSH.EXE WINSOCK RESET", 0, True
'winxp/server 2003 only
If sOSFromReg = "Windows XP" Or sOSFromReg = "Windows Server 2003" Then
Call WriteLogEntry("XP/2003 (proxycfg.exe -d)", True)
WshShell.Run "proxycfg.exe -d", 0, True
End If
'Start BITS/Windows Update Services
Call WriteLogEntry("Starting Services", True)
blnStartBITS = StartServiceSC("BITS")
blnStartWUAUSERV = StartServiceSC("WUAUSERV")
'vista/win7/2008 only
If sOSFromReg = "Windows Vista" Or sOSFromReg = "Windows 7" Then
Call WriteLogEntry("Vista/Win7/2008 (bitsadmin.exe /reset /allusers)", True)
WshShell.Run "bitsadmin.exe /reset /allusers", 0, True
End If
Call RefreshServerComplianceState
WScript.Quit
'***************************************************************************************
Sub RefreshServerComplianceState()
Call WriteLogEntry("Refreshing Server Compliance State", True)
' Script from http://msdn.microsoft.com/en-us/library/cc146437.aspx
Dim oCCMUpdatesStore
On Error Resume Next
Set oCCMUpdatesStore = CreateObject("Microsoft.CCM.UpdatesStore")
oCCMUpdatesStore.RefreshServerComplianceState
On Error GoTo 0
End Sub
Function RegisterWUDLLs
Call RegisterDLL(sSystemRootLocation & "\system32\atl.dll")
Call RegisterDLL(sSystemRootLocation & "\system32\urlmon.dll")
Call RegisterDLL(sSystemRootLocation & "\system32\mshtml.dll")
Call RegisterDLL(sSystemRootLocation & "\system32\shdocvw.dll")
Call RegisterDLL(sSystemRootLocation & "\system32\browseui.dll")
Call RegisterDLL(sSystemRootLocation & "\system32\jscript.dll")
Call RegisterDLL(sSystemRootLocation & "\system32\vbscript.dll")
Call RegisterDLL(sSystemRootLocation & "\system32\scrrun.dll")
Call RegisterDLL(sSystemRootLocation & "\system32\msxml.dll")
Call RegisterDLL(sSystemRootLocation & "\system32\msxml3.dll")
Call RegisterDLL(sSystemRootLocation & "\system32\msxml6.dll")
Call RegisterDLL(sSystemRootLocation & "\system32\actxprxy.dll")
Call RegisterDLL(sSystemRootLocation & "\system32\softpub.dll")
Call RegisterDLL(sSystemRootLocation & "\system32\wintrust.dll")
Call RegisterDLL(sSystemRootLocation & "\system32\dssenh.dll")
Call RegisterDLL(sSystemRootLocation & "\system32\rsaenh.dll")
Call RegisterDLL(sSystemRootLocation & "\system32\gpkcsp.dll")
Call RegisterDLL(sSystemRootLocation & "\system32\sccbase.dll")
Call RegisterDLL(sSystemRootLocation & "\system32\slbcsp.dll")
Call RegisterDLL(sSystemRootLocation & "\system32\cryptdlg.dll")
Call RegisterDLL(sSystemRootLocation & "\system32\oleaut32.dll")
Call RegisterDLL(sSystemRootLocation & "\system32\ole32.dll")
Call RegisterDLL(sSystemRootLocation & "\system32\shell32.dll")
Call RegisterDLL(sSystemRootLocation & "\system32\initpki.dll")
Call RegisterDLL(sSystemRootLocation & "\system32\wuapi.dll")
Call RegisterDLL(sSystemRootLocation & "\system32\wuaueng.dll")
Call RegisterDLL(sSystemRootLocation & "\system32\wuaueng1.dll")
Call RegisterDLL(sSystemRootLocation & "\system32\wucltui.dll")
Call RegisterDLL(sSystemRootLocation & "\system32\wups.dll")
Call RegisterDLL(sSystemRootLocation & "\system32\wups2.dll")
Call RegisterDLL(sSystemRootLocation & "\system32\wuweb.dll")
Call RegisterDLL(sSystemRootLocation & "\system32\qmgr.dll")
Call RegisterDLL(sSystemRootLocation & "\system32\qmgrprxy.dll")
Call RegisterDLL(sSystemRootLocation & "\system32\wucltux.dll")
Call RegisterDLL(sSystemRootLocation & "\system32\muweb.dll")
Call RegisterDLL(sSystemRootLocation & "\system32\wuwebv.dll")
Call RegisterDLL(sSystemRootLocation & "\system32\mssip32.dll") 'kb822798
End Function
Function RegisterDLL(sFilePath)
Call WriteLogEntry(vbTab & "REGSVR32 /S " & sFilePath, True)
'####
WshShell.Run "REGSVR32 /S " & sFilePath, 3, True
End Function
Function Deltree(sFolderPath)
Dim oFolder, oFile, oSubFolder
Call WriteLogEntry("DELTREE:" & vbTab & sFolderPath, True)
'#####
'Exit Function
If oFSO.FolderExists(sFolderPath) Then
Set oFolder = oFSO.GetFolder(sFolderPath)
For Each oFile In oFolder.Files
Dim sFilePath
sFilePath = oFile.Path
'Call WriteLogEntry(vbTab & vbTab & "FILEDELETE:" & vbTab & sFilePath, True)
'**********************************
On Error Resume Next
oFSO.DeleteFile sFilePath, True
On Error GoTo 0
'**********************************
Next
For Each oSubFolder In oFolder.SubFolders
Dim sSubFolderPath
sSubFolderPath = oSubFolder.Path
Call Deltree(sSubFolderPath)
'Call WriteLogEntry(vbTab & vbTab & "FOLDERDELETE2:" & vbTab & sSubFolderPath, True)
'**********************************
On Error Resume Next
If oFSO.FolderExists(sSubFolderPath) Then oFSO.DeleteFolder(sSubFolderPath)
On Error GoTo 0
'**********************************
Next
'Call WriteLogEntry(vbTab, vbTab & "FOLDERDELETE1:" & vbTab & sFolderPath)
On Error Resume Next
If oFSO.FolderExists(sFolderPath) Then oFSO.DeleteFolder(sFolderPath)
On Error GoTo 0
Else
Call WriteLogEntry(vbTab & "DELTREE Warning - Path not found:" & vbTab & sFolderPath, True)
End If
If oFSO.FolderExists(sFolderPath) Then
Deltree = False 'Failed if the folder is still there
Else
Deltree = True 'Succeeded if the folder is gone
End If
End Function 'Deltree
Function DeleteQMGRFiles
Dim sAllUsersProfile, oAllUsersProfile, oFile
sAllUsersProfile = WshShell.ExpandEnvironmentStrings("%ALLUSERSPROFILE%")
Set oAllUsersProfile = oFSO.GetFolder(sAllUsersProfile & "\Application Data\Microsoft\Network\Downloader")
For Each oFile In oAllUsersProfile.Files
'WScript.Echo oFile
'WScript.Echo vbTab & oFile.Name
If UCase(Left(oFile.Name, 4)) = "QMGR" And UCase(Right(oFile.Name, 4)) = ".DAT" Then
Call WriteLogEntry("DELETE: " & oFile, True)
'WScript.Echo vbTab & "DELETE: " & oFile
'#####
On Error Resume Next
oFile.Delete
On Error GoTo 0
End If
Next
End Function
Function GetOSType
'http://technet.microsoft.com/en-us/library/cc782360(WS.10).aspx
Dim sOStype
sOStype = WshShell.RegRead("HKLM\SYSTEM\CurrentControlSet\Control\ProductOptions\ProductType")
Select Case UCase(sOStype)
Case "WINNT" : GetOSType = "WORKSTATION"
Case "SERVERNT", "LANMANNT" : GetOSType = "SERVER"
Case Else : GetOSType = "UNKNOWN"
End Select
End Function 'GetOSType
Function GetOSFromReg
'Determines the OS based on Registry entries (only used when WMI is broken)
Dim sOSVersion, sOSName, sOSType
sOSType = GetOSType
'sProductType = WshShell.RegRead("HKLM\SYSTEM\CurrentControlSet\Control\ProductOptions\ProductType")
sOSVersion = WshShell.RegRead("HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\CurrentVersion")
Select Case True
Case (sOSVersion = "6.1" And sOSType = "WORKSTATION")
sOSName = "Windows 7"
Case sOSVersion = "6.0" And sOSType = "WORKSTATION"
sOSName = "Windows Vista"
Case sOSVersion = "5.1" And sOSType = "WORKSTATION", sOSVersion = "5.2.3790" And sOSType = "WORKSTATION"
sOSName = "Windows XP"
Case sOSVersion = "5.0" And sOSType = "WORKSTATION"
sOSName = "Windows 2000"
Case sOSVersion = "6.1" And sOSType = "SERVER"
sOSName = "Windows Server 2008 R2"
Case sOSVersion = "6.0" And sOSType = "SERVER"
sOSName = "Windows Server 2008"
Case sOSVersion = "5.2" And sOSType = "SERVER"
sOSName = "Windows Server 2003"
Case Else
sOSName = "UNKNOWN"
End Select
Call WriteLogEntry("GetOSFromReg (" & sOSVersion & "/" & sOSType & " = " & sOSName & ")", True)
GetOSFromReg = sOSName
End Function 'GetOSFromReg
Sub WriteLogEntry(sLogText, blnAlwaysLog)
'Logging sub..
'If blnAlwaysLog for a specific line is False, only logs entry if blnDEBUG Constant is set to True
WScript.Echo sLogText
' If blnDEBUG = True Then
' oLogfile.WriteLine(Now & vbTab & sComputer & vbTab & sLogText)
' Else
' If blnAlwaysLog = True Then
' oLogfile.WriteLine(Now & vbTab & sComputer & vbTab & sLogText)
' End If
' End If
End Sub 'WriteLogEntry
Function CheckServiceStateSC(sServiceName)
Dim sCmdLine, oExec, intReturn, sOutput
Dim sStateLine, arrStateLine1, arrStateLine2, intServiceState, sServiceState
sCmdLine = "sc QUERY " & sServiceName
'WScript.Echo sCmdLine
Set oExec = WshShell.Exec(sCmdLine)
Do While Not oExec.StdOut.AtEndOfStream
Dim sOutputLine
sOutputLine = oExec.StdOut.ReadLine
If InStr(1, sOutputLine, "STATE", vbTextCompare) 0 Then
sStateLine = sOutputLine
Exit Do 'Checking one service-exit once we find what we need
End If
sOutput = sOutput & sOutputLine
Loop
'Make sure we are done...
Do While oExec.Status 1
WScript.Sleep 100
Loop
Err.Clear
On Error Resume Next
arrStateLine1 = Split(sStateLine, ":")
'untested method to check if we don't get a response
If Err.Number 0 Then
CheckServiceStateSC = "9999"
On Error GoTo 0
Exit Function
Else
arrStateLine2 = Split(arrStateLine1(1), " ")
intServiceState = arrStateLine2(1)
sServiceState = arrStateLine2(3)
End If
On Error GoTo 0
'1 STOPPED
'2 START_PENDING
'3 STOP_PENDING
'4 RUNNING
'1056 = already running
Call WriteLogEntry(vbTab & vbTab & "CheckServiceStateSC:" & vbTab & sServiceName & vbTab & intServiceState & vbTab & sServiceState, False)
CheckServiceStateSC = intServiceState
End Function 'CheckServiceStateSC
Function StopServiceSC(sServiceName)
Dim sCmdLine, oExec, intReturn, intServiceState
Dim intCounter
sCmdLine = "sc STOP " & sServiceName
'WScript.Echo sCmdLine
Call WriteLogEntry(vbTab & "Stopping Service:" & vbTab & sServiceName, True)
Set oExec = WshShell.Exec(sCmdLine)
Do While oExec.Status 1
WScript.Sleep 100
Loop
intReturn = oExec.ExitCode
'WScript.Echo vbTab & vbTab & "StopServiceSC:" & vbTab & intReturn
If intReturn = 0 Then
intServiceState = CheckServiceStateSC(sServiceName)
Do While intServiceState 1
intCounter = intCounter + 1
If intCounter > 10 Then
'Give up after 10 attempts
StopServiceSC = False
Exit Function
End If
WScript.Sleep 2000
intServiceState = CheckServiceStateSC(sServiceName)
Loop
StopServiceSC = True
Else
'Error reported by SC when issuing stop command
'1051 = Dependent services still running
StopServiceSC = False
End If
End Function 'StopServiceSC
Function StartServiceSC(sServiceName)
Dim sCmdLine, oExec, intReturn, intServiceState
Dim intCounter
sCmdLine = "sc START " & sServiceName
'WScript.Echo vbTab & sCmdLine
Call WriteLogEntry(vbTab & "Starting Service:" & vbTab & sServiceName, True)
Set oExec = WshShell.Exec(sCmdLine)
Do While oExec.Status 1
WScript.Sleep 100
Loop
intReturn = oExec.ExitCode
'1056 = already running
'WScript.Echo vbTab & vbTab & "StartServiceSC:" & vbTab & intReturn
StartServiceSC = intReturn
intServiceState = CheckServiceStateSC(sServiceName)
Do While intServiceState 4
intCounter = intCounter + 1
If intCounter > 10 Then
'Give up after 10 attempts
StartServiceSC = False
Exit Function
End If
WScript.Sleep 2000
intServiceState = CheckServiceStateSC(sServiceName)
Loop
StartServiceSC = True
End Function 'StartServiceSC
Function RebuildWMI
'Stops WMI and all dependent services
'Renames Repository folder
'Starts WMI and all dependent services that were running
'Always starts CCMEXEC at the end
Dim sWBEMRepositoryLocation, sWBEMFolderPath, sRepositoryFolderRenamedPath
Dim blnDeltree
Call WriteLogEntry("Attempting to rebuild WMI", True)
'Some OSs store the Repository location using %systemroot%...
'sSystemRootLocation = WshShell.RegRead("HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\SystemRoot")
'Call WriteLogEntry(vbTab & "SystemRootLocation:" & vbTab & sSystemRootLocation, False)
'Need to look in the reg to find the repository location because some tools like SMS Client Center move the Repository location
sWBEMRepositoryLocation = WshShell.RegRead("HKLM\SOFTWARE\Microsoft\WBEM\CIMOM\Repository Directory")
sWBEMRepositoryLocation = Replace(sWBEMRepositoryLocation, "%systemroot%", sSystemRootLocation, 1, -1, vbTextCompare)
Call WriteLogEntry(vbTab & "WBEMRepositoryLocation:" & vbTab & sWBEMRepositoryLocation, False)
If sWBEMRepositoryLocation "FUNCTIONERROR" Then
'Make sure Repository folder exists
If oFSO.FolderExists(sWBEMRepositoryLocation) Then
Call WriteLogEntry(vbTab & "Folder Exists:" & vbTab & sWBEMRepositoryLocation, True)
'Get parent folder name
sWBEMFolderPath = oFSO.GetParentFolderName(sWBEMRepositoryLocation)
Call WriteLogEntry(vbTab & "WBEMFolderPath:" & vbTab & sWBEMFolderPath, True)
'Set name for repository to be renamed to
sRepositoryFolderRenamedPath = sWBEMRepositoryLocation & "-old"
Call WriteLogEntry(vbTab& "RepositoryFolderRenamedPath:" & vbTab & sRepositoryFolderRenamedPath, True)
'Delete any existing Repository backup folders
If oFSO.FolderExists(sRepositoryFolderRenamedPath) = True Then
Call WriteLogEntry(vbTab & "Backup Repository folder already exists - Deleting:" & vbTab & sRepositoryFolderRenamedPath, True)
blnDeltree = Deltree(sRepositoryFolderRenamedPath)
Call WriteLogEntry(vbTab & "Deltree Result:" & vbTab & blnDeltree, True)
Else
blnDeltree = True
End If
'If removal of any Repository backup folders was successful...
If blnDeltree = True Then
Dim intWMIServiceState, intSCCMServiceState, oKey
'StopServiceAndDependents for WMI Service
intWMIServiceState = CheckServiceStateSC(sWBEMServiceName)
If intWMIServiceState = 1 Then
'Already stopped
Else
'Get Dependent Services
Dim oDictDependentSvcs
Set oDictDependentSvcs = EnumServiceDepSC(sWBEMServiceName)
If CheckServiceStateSC("ccmexec") 1 Then
blnStopService = StopServiceSC("ccmexec")
Call WriteLogEntry(vbTab & vbTab & "blnStopService - " & oKey & vbTab & blnStopService, True)
End If
'Stop Dependent Services
For Each oKey In oDictDependentSvcs.Keys
Dim blnStopService
blnStopService = StopServiceSC(oKey)
Call WriteLogEntry(vbTab & vbTab & "blnStopService - " & oKey & vbTab & blnStopService, True)
Next
'Stop WinMgmt Service
Call StopServiceSC(sWBEMServiceName)
End If
'NEED TO CONFIRM SERVICE IS STOPPED BEFORE MOVING ON
intWMIServiceState = CheckServiceStateSC(sWBEMServiceName)
If intWMIServiceState = 1 Then 'STOPPED
Call WriteLogEntry(vbTab & "Renaming Folder '" & sWBEMRepositoryLocation & "' to '" & sRepositoryFolderRenamedPath & "'", True)
'Rename the active Repository folder
oFSO.MoveFolder sWBEMRepositoryLocation, sRepositoryFolderRenamedPath
'Startup the WMI service
Call StartServiceSC(sWBEMServiceName)
intWMIServiceState = CheckServiceStateSC(sWBEMServiceName)
'Startup dependent services
If intWMIServiceState = 4 Then 'RUNNING
For Each oKey In oDictDependentSvcs.Keys
Dim blnStartService
blnStartService = StartServiceSC(oKey)
Call WriteLogEntry(vbTab & vbTab & "blnStartService - " & oKey & vbTab & blnStartService, True)
Next
'Startup CCMExec
intSCCMServiceState = CheckServiceStateSC(sSCCMServiceName)
If intSCCMServiceState = 1 Then 'STOPPED
'SCCM may not have been running before-If not, go ahead and start it now
blnStartService = StartServiceSC(sSCCMServiceName)
Call WriteLogEntry(vbTab & vbTab & "blnStartService - " & sSCCMServiceName & vbTab & blnStartService, True)
End If
Call WriteLogEntry("WMI REBUILD COMPLETE", True)
Else
Call WriteLogEntry(vbTab & "ERROR - WMI Service didn't start back up", True)
End If
Else
Call WriteLogEntry(vbTab & "ERROR - WMI Service never stopped", True)
End If
Else
Call WriteLogEntry(vbTab & "ERROR - Old Repository folder could not be removed", True)
End If
Else
Call WriteLogEntry(vbTab & "ERROR - Cannot find folder:" & vbTab & sWBEMRepositoryLocation, True)
End If
Else
Call WriteLogEntry(vbTab & "ERROR - Could not get WBEM Repository location from the registry", True)
End If
End Function 'RebuildWMI
Function EnumServiceDepSC(sServiceName)
Dim sCmdLine, oExec, oDictTemp
Set oDictTemp = CreateObject("Scripting.Dictionary") : oDictTemp.CompareMode = vbTextCompare
sCmdLine = "sc ENUMDEPEND " & sServiceName
'WScript.Echo sCmdLine
Set oExec = WshShell.Exec(sCmdLine)
Do While Not oExec.StdOut.AtEndOfStream
Dim sOutputLine, sDepService, intServiceState
sOutputLine = oExec.StdOut.ReadLine
If InStr(1, sOutputLine, "SERVICE_NAME", vbTextCompare) 0 Then
sDepService = Replace(sOutputLine, "SERVICE_NAME: ", "", 1, -1, vbTextCompare)
'WScript.Echo vbTab & sDepService
End If
If InStr(1, sOutputLine, "STATE", vbTextCompare) 0 Then
intServiceState = ParseServiceStateLineSC(sOutputLine)
'WScript.Echo vbTab & intServiceState
End If
If sDepService "" And intServiceState "" Then
'We have info about one service
If intServiceState = 4 Then
oDictTemp.Add sDepService, Null
End If
sDepService = "" : intServiceState = ""
End If
Loop
Set EnumServiceDepSC = oDictTemp
End Function 'EnumServiceDepSC
Function ParseServiceStateLineSC(sStateLine)
Dim arrStateLine1, arrStateLine2, intServiceState, sServiceState
arrStateLine1 = Split(sStateLine, ":")
arrStateLine2 = Split(arrStateLine1(1), " ")
intServiceState = arrStateLine2(1)
sServiceState = arrStateLine2(3)
ParseServiceStateLineSC = intServiceState
End Function 'ParseServiceStateLineSC