;; 
;;=====================================================================================----- 
;; 
;;FUNCTION       WMIPathInfo() 
;; 
;;ACTION         Returns information about the system path 
;; 
;;AUTHOR         Glenn Barnas 
;; 
;;VERSION	 1.0 - 2008/11/04 
;; 
;;HISTORY        1.0 - 2008/11/04 - Initial Release 
;; 
;;SYNTAX         WMIPathInfo([Target] [, AuthPtr]) 
;; 
;;PARAMETERS     Target - OPTIONAL - String 
;;               - The name of system to query 
;; 
;;               AuthPtr - OPTIONAL - Object 
;;               - The pre-authenticated WMI object pointer. 
;;                 Use WMIAuthenticate() udf to create the AuthPtr value. 
;;                 AuthPtr is not needed if user has admin rights. 
;; 
;;REMARKS        Helps to manage the system PATH value to prevent application errors 
;;		 Same as PathInfo() but uses WMI for better remote Vista access.  
;;		 Uses registry reads for local computer queries 
;; 
;;RETURNS        Array 
;;		 1: Current Path 
;;		 2: Array of updated path elements - Admin, System, Apps1, Apps2, & Java 
;;		    Admin is anything that contains "local\", meeting specific parameters 
;;		    System is anything that contains %SystemRoot% 
;;		    Apps1 contains apps in C:\Program Files 
;;		    Apps2 are all other apps 
;;		    Java is anything with a JRE in the path 
;;		 3: # of duplicate path values found 
;;		 4: # of missing path values found 
;;		 5: # of invalid path values found 
;;		 6: Report of missing/invalid folders 
;; 
;;DEPENDENCIES   none 
;; 
;;TESTED WITH    W2K, WXP, W2K3, Vista 
;; 
;;EXAMPLES        
; 
Function WMIPathInfo(Optional $_Target, OPTIONAL $_pAuth)
 
  Dim $_
  Dim $_Tools					; array of admin tool locations 
  Dim $_SPath					; Source Path 
  Dim $_aPath, $_Dir				; array of path segments, Enumerator 
  Dim $_aTmp[3]					; Array of data to return 
  Dim $_UNCPath, $_NPath			; UNC and Normalized path elements 
  Dim $_SRoot, $_SDrv				; system root and drive values 
  Dim $_Admin, $_Af				; Admin tools paths, AdminFlag 
  Dim $_System					; system paths 
  Dim $_Java					; Java paths 
  Dim $_Apps1, $_Apps2				; path to primary/secondary apps 
  Dim $_Dup, $_Missing, $_Invalid		; counters for bad elements 
  Dim $_objWMIService, $_objItem, $_colItems	; WMI vars 
 
 
  ; ====================================================================== 
  ; Array of folders considered Admin tools 
  ; This array must be customized! - similar paths must be listed most to least specific! 
  $_Tools = 'local\bin', 'local', 'scripts', 'batch', 'cygwin'
  ; ====================================================================== 
 
 
  ; Initialize the error counters 
  $_Dup = 0
  $_Missing = 0
  $_Invalid = 0
 
  ; format the target name if defined by removing all "\" 
  $_Target = Join(Split($_Target,'\', 3),'')
 
  ; Get the PATH and SYSTEMROOT values from the local registry as default values 
  $_SPath = ReadValue('HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment', 'PATH')
  $_SRoot = ReadValue('HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion', 'SystemRoot')
 
  ; if the target was specified and is not the local computer, use WMI to obtain the values 
  If $_Target And $_Target <> '.' And $_Target <> @WKSTA
 
  ; If a pre-authenticated WMI object pointer was provided, use it, otherwise create a new object pointer 
    If $_pAuth
      $_objWMIService = $_pAuth
    Else
      $_objWMIService = GetObject('winmgmts:{impersonationLevel=impersonate}!\\' + $_Target + '\root\cimv2')
      If @ERROR Exit Val('&' + Right(DecToHex(@ERROR), 4)) EndIf
    EndIf
 
    ; Get the current and boot times from the client system 
    $_colItems = $_objWMIService.ExecQuery("Select * from Win32_Environment",,48)
    For each $_objItem in $_colItems
     Select
      Case $_objItem.Name = 'Path'
        $_SPath = $_objItem.VariableValue
        $_ = $_ + 1
      Case $_objItem.Name = 'SystemRoot'
        $_SRoot = $_objItem.VariableValue
        $_ = $_ + 1
     EndSelect
    Next
 
    ; Did not get both required values from the remote target - abort! 
    If $_ <> 2
      Exit 87
    EndIf
 
  EndIf
 
  $_SDrv = Left($_SRoot, 2)
  ; split the path segments into an array 
  $_aPath = Split($_SPath, ';')
 
  ; enumerate the path elements, eliminate duplicates, verify paths, and classify 
  For Each $_Dir in $_aPath
 
    ; remove trailing "\" 
    If Right($_Dir, 1) = '\' $_Dir = Left($_Dir, Len($_Dir) - 1) EndIf
 
    ; Create Normalized Path element with expanded environment vars 
    $_NPath = Join(Split($_Dir, '%%SYSTEMROOT%%'), $_SRoot)
    $_NPath = Join(Split($_NPath, '%%SYSTEMDRIVE%%'), $_SDrv)
    ; convert normalized path to UNC path for folder validation 
    If $_Target
      $_UNCPath = $_Target + Join(Split($_NPath, ':'), Chr(36))
    Else
      $_UNCPath = $_NPath
    EndIf
 
    ; PERFORM FOLDER ELEMENT VALIDATION 
    ; NPV must begin with a drive letter to be a valid, rooted path element 
    ; UNC must exist to be a valid element 
    If Not InStr($_NPath, '%%')		; ignore unresolved env vars 
      $_ = Exist($_UNCPath)
      If @ERROR
          $_aTmp[3] = $_aTmp[3] + 'Unverified Folder: ' + $_Dir + ' : ' + @ERROR + @CRLF
      Else
        If Not $_
          $_aTmp[3] = $_aTmp[3] + 'Missing Folder: ' + $_Dir + @CRLF
          $_Missing = $_Missing + 1
          $_Dir = ''
        EndIf
      EndIf
      If Not InStr($_NPath, ':')
        $_aTmp[3] = $_aTmp[3] + 'Invalid Folder: ' + $_Dir + @CRLF
        $_Invalid = $_Invalid + 1
        $_Dir = ''
      EndIF
    EndIf
 
    ; CHECK AND CLASSIFY PATH ELEMENT 
    $_Af = 0
    For Each $_ in $_Tools
      If InStr($_NPath, $_) And Not $_Af			; ADMIN PATH ELEMENT 
        If InStr($_Admin, $_Dir + ';')
          $_aTmp[3] = $_aTmp[3] + 'Duplicate folder: ' + $_Dir + @CRLF
          $_Dup = $_Dup + 1
        Else
          $_Admin = $_Admin + $_Dir + ';'
        EndIf
        $_Af = 1
      EndIf
    Next
 
    If Not $_Af
      Select
       Case $_Dir = ''						; TRAP INVALID ELEMENT 
 
       Case InStr($_NPath, $_SRoot)				; SYSTEM PATH ELEMENT 
        If InStr($_System, $_Dir + ';')
          $_aTmp[3] = $_aTmp[3] + 'Duplicate folder: ' + $_Dir + @CRLF
          $_Dup = $_Dup + 1
        Else
          $_System = $_System + $_Dir + ';'
        EndIf
 
       Case InStr($_NPath, 'jre') Or InStr($_NPath, 'j2re')	; JAVA PATH ELEMENT 
        If InStr($_Java, $_Dir + ';')
          $_aTmp[3] = $_aTmp[3] + 'Duplicate folder: ' + $_Dir + @CRLF
          $_Dup = $_Dup + 1
        Else
          $_Java = $_Java + $_Dir + ';'
        EndIf
 
       Case InStr($_NPath, $_SDrv + '\progra') = 1		; PRIMARY APP ELEMENT 
        If InStr($_Apps1, $_Dir + ';')
          $_aTmp[3] = $_aTmp[3] + 'Duplicate folder: ' + $_Dir + @CRLF
          $_Dup = $_Dup + 1
        Else
          $_Apps1 = $_Apps1 + $_Dir + ';'
        EndIf
 
       Case 1							; SECONDARY APP ELEMENT 
        If InStr($_Apps2, $_Dir + ';')
          $_aTmp[3] = $_aTmp[3] + 'Duplicate folder: ' + $_Dir + @CRLF
          $_Dup = $_Dup + 1
        Else
          $_Apps2 = $_Apps2 + $_Dir + ';'
        EndIf
 
      EndSelect
 
    EndIf
 
  Next
 
  $_aTmp[0] = $_aPath
  $_aTmp[1] = $_Admin, $_System, $_Apps1, $_Apps2, $_Java
  $_aTmp[2] = $_Dup, $_Missing, $_Invalid
  $_aTmp[3] = Split($_aTmp[3], @CRLF)
  $WMIPathInfo = $_aTmp
 
  Exit 0
 
EndFunction