narrow default width wide
colour style colour style colour style colour style

SCCM - Fix Patch Issues

This is just a script I have put together to try to fix common patch issues. It is based off of the Microsoft articles referenced in the code. Their fix was in EXE form and I wanted the flexibility to enabled/disable certain things.

Generally, this is meant to be advertised to all clients without specifying a Mandatory Execution time so that it can easily be run ad-hoc.

'check for running jobs
'check for active patch deployments
'check windows update agent version?

'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)
    ' Initialize the UpdatesStore variable.
    Dim newCCMUpdatesStore 
 
    ' Create the COM object.
    Set newCCMUpdatesStore = CreateObject ("Microsoft.CCM.UpdatesStore")
 
    ' Refresh the server compliance state by running the RefreshServerComplianceState method.
    newCCMUpdatesStore.RefreshServerComplianceState
 
    ' Output success message.
    'wscript.echo "Ran RefreshServerComplianceState."

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
'#####
      oFile.Delete
    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