Client Health: Repair the WMI Path and ensure WMI is added

Once upon a time I wrote a Client Health repair script for Windows XP SMS and SCCM 2007 environments.  By far and away the biggest issue was WMI corruption.  The point of this script was to fix as much as humanly possible WITHOUT using WMI.  No minor feat and you can see one section below here.   A major issue that was EASILY remedied was ensuring WMI was in the system path.  This was recently pointed out to me that people were charging for simple logic.  So here is a nice way to do it for free with a few more frills thrown in for free.

Solution: Fix the WMI in the System Path

The fix below will parse you entire system path and remove any %variable%, remove duplicates, and ensure certain items are in the System path like WMI.  I always wanted to add in a check to look for UNC (\\) paths as those always make a system go slower.

The following script will NOT work.  Please see the full CLIFIX script


Dim windir: windir = WSHShell.ExpandEnvironmentStrings("%WINDIR%")

' =============================================================================
' Description: checks that wbem is near the front of the sys path and cleans
' any duplicate statements from the path environment
' =============================================================================


 WindirPath = LCase(windir)
 System32path = LCase(windir & "\system32")
 WBEMpath = LCase(windir & "\system32\wbem")

 WindirPathFound = False
 System32pathFound = False
 WBEMpathFound = False
 SystemRoot = False

 strKeyNamePath = "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"
 strValueName = "Path"

 strValue = wshshell.regRead("HKLM\" & strKeyNamePath & "\" & strValueName)
 strValue = LCase(strValue)
 ARRpath = Split(LCase(strValue), ";")

 For i = 0 To UBound(ARRpath)
  'Repalce SystemRoot with actual value
  If InStr(ARRpath(i), LCase("%systemroot%")) <> 0 Then strValue = Replace(strValue, LCase("%systemroot%"), LCase(windir)) : SystemRoot = True : COLLECTMSG "CHK_SYSTEMPATH","Warning Replaced %systemroot%",SystemRoot
  If ARRpath(i) = WindirPath Then WindirPathFound = True
  If ARRpath(i) = System32path Then System32pathFound = True
  If ARRpath(i) = WBEMpath Then WBEMpathFound = True

If (WBEMpathFound = True) And (System32pathFound = True) And (WindirPathFound = True) And (SystemRoot = False) Then COLLECTMSG "CHK_SYSTEMPATH","All Paths Found",WBEMpathFound: Exit Sub

 '// Log the results
 If WBEMpathFound = False Then strValue = WBEMpath & ";" & strValue : COLLECTMSG "CHK_SYSTEMPATH","Error WBEMpathFound", WBEMpathFound:logit=True : CLIENTSTATE = CLIENTSTATE + 1
 If WindirPathFound = False Then strValue = WindirPath & ";" & strValue : COLLECTMSG "CHK_SYSTEMPATH","Error WindirPathFound", WindirPathFound :logit=True : CLIENTSTATE = CLIENTSTATE + 1
 If System32pathFound = False Then strValue = System32path & ";" & strValue : COLLECTMSG "CHK_SYSTEMPATH","Error System32pathFound",System32pathFound:logit=True : CLIENTSTATE = CLIENTSTATE + 1
 If logit = True Then StrERRType = StrERRType & "SYSTEMPATH_"

 '//Take out duplicates
 'Dictionary Object is Much faster
 ARRpath = Split(LCase(strValue), ";")
 Set PureString = CreateObject("Scripting.Dictionary")
 For i = 0 To UBound(ARRpath)
  If Not PureString.Exists(ARRpath(i)) Then PureString.Add ARRpath(i), ARRpath(i) : Debug(ARRpath(i))
 strValues = ""
 For Each strKeyName in PureString.Keys
  strValues = strValues & strKeyName & ";"
 Set PureString = Nothing
 'Remove duplicate semicolons
 If InStr(strValues, ";;") <> 0 Then strValues = Replace(Replace(strValues, ";;", ";"), ";;", ";")
 'Remove trailing semicolons
 ln = Len(strValues)
 If InStr(ln, strValues, ";") <> 0 Then strValues = Left(strValues, ln - 1)
 'Set to current runtime path
 Set oEnv = WshShell.Environment("System")
 Set oEnv = Nothing
 'Set to Registry for next restart
 wshshell.regwrite "HKLM\" & strKeyNamePath & "\" & strValueName,strValues,"REG_SZ" 
 RegCounter "CHK_SYSTEMPATH",1
End Sub

Author: shauncassells

Shaun Cassells, Senior Solutions Engineer, 1E Shaun is a Microsoft MVP Windows Insider MVP and executive at Central Texas Systems Management User Group (CTSMUG). Shaun is a frequent speaker at conferences like MMS, Gartner, TechEd Europe, TechEd North America, IT Dev Connections, System Center Rallies, and Systems Management User Groups (SMUGs). Shaun is an award winning blogger syndicated from Shaun specializes in analysis, optimization, and design of Tactical Solutions to Strategic Business Goals. Prior to joining 1E in 2010, he worked for a Global 100 company as the Configuration Manager Service Owner and Architect. Recently as a Principle Consultant at 1E, he accomplished design, review, and improvements to a variety of Configuration Manager environments from the very small to sites with a half million seats. He provided leadership that created a patented automated application rationalization and usage based OSD mapping solution in use by multiple fortune 500 companies. These days you can find Shaun traveling to help discover, review, and improve business productivity across the world.

1 thought on “Client Health: Repair the WMI Path and ensure WMI is added”

  1. Hi Shaun question is the script also written in a Powershell?
    Allot of those steps are resolved allot easier with Powershell and also we want to remove VBS script within our environment.
    I already have a client health script setup with the WMI repair on will rename the repository: Also following script looks pretty good to repair WMI:

    # Stop WMI
    # Only if SCCM/SMS Client is installed. Stop ccmexec.
    Stop-Service -Force ccmexec -ErrorAction SilentlyContinue
    Stop-Service -Force winmgmt

    #(Re)Register WMI binary components
    foreach ($sWMIPath in @(($ENV:SystemRoot+”\System32\wbem”),($ENV:SystemRoot+”\SysWOW64\wbem”))){
    if(Test-Path -Path $sWMIPath){
    push-Location $sWMIPath
    foreach($sBin in $aWMIBinaries){
    if(Test-Path -Path $sBin){
    $oCurrentBin=Get-Item -Path $sBin
    Write-Host ” Register $sBin”
    & $oCurrentBin.FullName /RegServer
    # Warning only for System32
    if($sWMIPath -eq $ENV:SystemRoot+”\System32\wbem”){
    Write-Warning “File $sBin not found!”
    #Reregister WMI Managed Objects
    if([System.Environment]::OSVersion.Version.Major -eq 5)
    foreach ($sWMIPath in @(($ENV:SystemRoot+”\System32\wbem”),($ENV:SystemRoot+”\SysWOW64\wbem”))){
    if(Test-Path -Path $sWMIPath){
    push-Location $sWMIPath
    Write-Host ” Register WMI Managed Objects”
    $aWMIManagedObjects=Get-ChildItem * -Include @(“*.mof”,”*.mfl”)
    foreach($sWMIObject in $aWMIManagedObjects){
    $oWMIObject=Get-Item -Path $sWMIObject
    & mofcomp $oWMIObject.FullName
    if([System.Environment]::OSVersion.Version.Minor -eq 1)
    & rundll32 wbemupgd,UpgradeRepository
    & rundll32 wbemupgd,RepairWMISetup

    # Other Windows Vista, Server 2008 or greater
    Write-Host ” Reset Repository”
    & ($ENV:SystemRoot+”\system32\wbem\winmgmt.exe”) /resetrepository
    & ($ENV:SystemRoot+”\system32\wbem\winmgmt.exe”) /salvagerepository

    #Starting services
    Start-Service -Force winmgmt
    Start-Service -Force ccmexec -ErrorAction SilentlyContinue


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s