;; 
;;=====================================================================================----- 
;; 
;;FUNCTION       WMISysInfo() 
;; 
;;ACTION         Returns an array of system information needed by inventory apps. 
;; 
;;AUTHOR         Glenn Barnas 
;; 
;;VERSION        1.3 - 2014/01/07 
;; 
;;HISTORY        1.0 - 2007/10/20 - Initial release 
;;		 1.1 - 2008/02/29 - enhances O/S and hardware processor detection 
;;		 1.2 - 2009/03/06 - Revert to reg-scrape for HF list on local systems 
;;                                  - PERFORMANCE!! WMI queries of QuickFixEngineering 
;;                                  cause TrustedInstaller to launch at 50%+ CPU load 
;;                                  on certain Vista systems, resulting in delays of 
;;                                  up to several minutes to obtain the HF list.  
;;                                  Registry scrapes are completed in sub-second times 
;;                                  on local systems. 
;;               1.3 - 2014/01/07 - Update the embedded _osid UDF for newer O/S IDs; 
;;				    Addressed reg read issue on X64 platforms. All 
;;                                  fields returning multiple values are now consistently 
;;				    delimited with semicolons (;) These are marked as 
;;                                  "(;-List)" below 
 
;; 
;;SYNTAX         WMISysInfo([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        Replaced independent OSInfo and HWInfo UDFs 
;; 
;;RETURNS        40 element array 
;;               0   short/full operating system description 
;;               1   kernel description (ie: Win2K, WinXP, Win2K3, Vista) 
;;               2   operating system role (workstation, member server, domain controller) 
;;               3   operating system service pack level 
;;               4   operating system build level 
;;               5   uni/multi-processor type 
;;               6   Computer Name 
;;               7   registered owner;organization                    (;-List) 
;;               8   Serial Number 
;;               9   Install Date - YYYY/MM/DD hh:mm:ss 
;;               10  Local Date/Time  - YYYY/MM/DD hh:mm:ss 
;;               11  Last Boot Time - YYYY/MM/DD hh:mm:ss 
;;               12  TimeZone info (Std, Daylight, Bias)              (;-List) 
;;               13  Primary Domain Affiliation                       (;-List) 
;;               14  Installed Hotfix list                            (;-List) 
;;               15  OS Version                                       (numeric) 
;;               16  Future Use 
;;               17  O/S Architecture 
;;               18  Install Method (Clean, Upgrade, SysPrep) 
;;               19  RAM/PageFile Info (RAM; PFPath;MinSize;MaxSize)  (;-List) 
;;               20  System Brand 
;;               21  System Model 
;;               22  System S/N 
;;               23  System BIOS Revision 
;;               24  Processor Type 
;;               25  Processor Speed (MHz) 
;;               26  Processor Count (Physical) 
;;               27  Processor Count (Logical) 
;;               28  Processor Cores 
;;               29  Physical Memory 
;;               30  Fixed-Disk Labels, null if none                  (;-List) 
;;               31  Fixed-Disk Mount Point ("d:\" for drives, path for mounted volumes) (2K3 & higher)	(;-List) 
;;               32  Fixed-Disk Drives (A:-Z:, or "MV:" for mounted Volumes)	(;-List) 
;;               33  Fixed-Disk Capacities, bytes                     (;-List) 
;;               34  Fixed-Disk FreeSpace, bytes                      (;-List) 
;;               35  CD-ROM Disk List                                 (;-List) 
;;               36  Connected Network Drives                         (;-List) 
;;               37  Hardware Architecture 
;;               38  Processor DataWidth 
;;               39  Video Adapter;Resolution;Monitor_ID              (;-List) 
;; 
;;DEPENDENCIES   WMI support 
;; 
;;TESTED WITH    W2K, WXP, W2K3, Vista, X64 
;; 
;;EXAMPLES       $Host = '' 
;;               $aHWI = WMISysInfo($Host) 
;;               $Host ' has ' $aHWI[26] ' Physical/Logical processors!' 
;; 
;;               $Host = 'RemoteComputerName' 
;;		 ; Create an authenticated WMI object 
;;               $_objWMI = WMIAuthenticate($Host, 'userid', 'User-P@ss!') 
;;		 ; Make the SysInfo query with the pre-authenticated object pointer 
;;               $Up = WMISysInfo($Host, $_objWMI) 
;;               'Secure host ' $Host ' was last booted on' $Up[11] 
; 
Function WMISysInfo(OPTIONAL $_Computer, OPTIONAL $_pAuth)
 
 
  Dim $_SI[39]						; Var for return array 
  Dim $_, $_Delim, $_SRoot, $_WFile, $_OSVer
  Dim $_objWMIService, $_colItems, $_objItem		; WMI object vars 
  Dim $_Key, $_Index, $_KeyName, $_HFp, $_Hotfix	; vars for HF registry scrape 
  Dim $_HF[0]						; array of detected hotfixes 
  Dim $_Reg						; Reg Redirect 
 
  ; insure a properly formatted computer name, default to local computer is not specified 
  $_Computer = IIf(Not $_Computer, '.', Join(Split($_Computer,'\'),''))
 
  ; 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}!\\' + $_Computer + '\root\cimv2')
    If @ERROR Exit Val('&' + Right(DecToHex(@ERROR), 4)) EndIf
  EndIf
 
  ; Save and Set the SysWOW Registry 
  $_Reg = SetOption('WOW64AlternateRegView', 'On')
 
 
; O/S SECTION		####################################################### 
 
  ; OperatingSystem	======================================================= 
  $_colItems = $_objWMIService.ExecQuery("Select * from Win32_OperatingSystem",,48)
  For Each $_objItem in $_colItems
    $_SRoot  = '\\' + $_Computer + '\' + Join(Split($_objItem.SystemDirectory, ':'), Chr(36)) + '\'
    $_SI[0]  = Trim(Split($_objItem.Name, '|')[0])
    $_SI[15] = $_objItem.Version
    $_       = _osid($_SI[0])			; get kernel name, fix OS name 
    $_SI[0]  = $_[0]
    $_SI[1]  = $_[1]
    $_OSVer  = Trim(Join(Split($_SI[15], '.', 2), '.'))
    $_       = Split($_objItem.CSDVersion, ' ')
    $_SI[3]  = $_[UBound($_)]
    $_SI[4]  = $_objItem.BuildNumber
    $_SI[5]  = $_objItem.BuildType
    $_SI[6]  = $_objItem.CSName
    $_SI[7]  = $_objItem.RegisteredUser + ';' + $_objItem.Organization 
    $_SI[8]  = $_objItem.SerialNumber
    ; Translate the following in to standard date strings (yyyy/mm/dd hh:mm:ss) 
    $_       = $_objItem.InstallDate
    $_SI[9]  = Left($_, 4) + '/' + SubStr($_, 5, 2) + '/' + SubStr($_, 7, 2) + ' '
             + SubStr($_, 9, 2) + ':' + SubStr($_, 11, 2) + ':'  + SubStr($_, 13, 2)
    $_       = $_objItem.LocalDateTime
    $_SI[10] = Left($_, 4) + '/' + SubStr($_, 5, 2) + '/' + SubStr($_, 7, 2) + ' '
            + SubStr($_, 9, 2) + ':' + SubStr($_, 11, 2) + ':'  + SubStr($_, 13, 2)
    $_       = $_objItem.LastBootUpTime
    $_SI[11] = Left($_, 4) + '/' + SubStr($_, 5, 2) + '/' + SubStr($_, 7, 2) + ' '
            + SubStr($_, 9, 2) + ':' + SubStr($_, 11, 2) + ':'  + SubStr($_, 13, 2)
    $_SI[17] = $_objItem.OSArchitecture
  Next
  $_colItems  = 0
 
  ; Time Zone		======================================================= 
  $_colItems = $_objWMIService.ExecQuery("Select * from Win32_TimeZone",,48)
  For Each $_objItem in $_colItems
    $_SI[12]  = $_objItem.StandardName + ';' + $_objItem.DaylightName + ';' + Abs($_objItem.Bias) / 60
  Next
  $_colItems  = 0
 
  ; Domain		======================================================= 
  $_colItems = $_objWMIService.ExecQuery("Select * from Win32_NTDomain",,48)
  For Each $_objItem in $_colItems
    $_SI[13]  = $_objItem.DNSForestName + ';' + $_objItem.DomainName
  Next
  $_colItems  = 0
 
  ; Hotfixes		======================================================= 
  If $_Computer = '.' ; use reg-scrape for local system 
    ; Key for Vista & W2K8 
    $_Key = 'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\Packages'
 
    $_Index = 0
    Dim $_HF[0]
    $_HFp = -1
    If KeyExist($_Key)
      $_KeyName = EnumKey($_Key, $_Index)
      While Not @ERROR
        If InStr($_KeyName, 'Package') = 1
          $_HotFix = Split(Split(Split($_KeyName, 'for_')[1], '_')[0], '~')[0]
          If AScan($_HF, $_Hotfix) < 0
            $_HFp = $_HFp + 1
            ReDim Preserve $_HF[$_HFp]
            $_HF[$_HFp] = $_HotFix
          EndIf
        EndIf
        $_Index = $_Index + 1
        $_KeyName = EnumKey($_Key, $_Index)
      Loop
    Else
      ; If O/S = XP and host = '', then query the registry 
      $_Key = 'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\HotFix'
      $_KeyName = EnumKey($_Key, $_Index)
      While Not @ERROR
        If InStr('KQ', Left($_KeyName, 1))
              $_HotFix = $_KeyName
          If AScan($_HF, $_Hotfix) < 0
            $_HFp = $_HFp + 1
            ReDim Preserve $_HF[$_HFp]
            $_HF[$_HFp] = $_HotFix
          EndIf
            EndIf
        $_Index = $_Index + 1
        $_KeyName = EnumKey($_Key, $_Index)
      Loop
    EndIf
    $_SI[14] = Join($_HF, ';')
  Else
    $_colItems = $_objWMIService.ExecQuery("Select * from Win32_QuickFixEngineering",,48)
    For Each $_objItem in $_colItems
      If InStr('KQ', Left($_objItem.HotFixID, 1))
        $_SI[14]  = $_SI[14] + ';' + $_objItem.HotFixID
      EndIf
    Next
    $_SI[14] = SubStr($_SI[14], 2)	; trim result 
    $_colItems  = 0
  EndIf
 
  ; PageFile		======================================================= 
  $_colItems = $_objWMIService.ExecQuery("Select * from Win32_PageFile",,48)
  If UBound($_colItems) > -1
    For Each $_objItem in $_colItems
      $_SI[19] = $_SI[19] + ';' + $_objItem.EightDotThreeFileName + ';' + $_objItem.InitialSize + ';' + $_objItem.MaximumSize
    Next
  Else
    $_colItems  = 0
    $_colItems = $_objWMIService.ExecQuery("Select * from Win32_PageFileUsage",,48)
    For Each $_objItem in $_colItems
      $_SI[19] = $_SI[19] + ';' + $_objItem.Description + ';' + $_objItem.AllocatedBaseSize  + ';-1'
    Next
  EndIf
  $_colItems  = 0
 
  ; Check for build status 
  $_SI[18] = 'Clean'
  $_WFile = $_SRoot + Chr(36) + 'winnt' + Chr(36) + '.inf'
  If Exist($_WFile)
    If ReadProfileString($_WFile, 'Data', 'StandardServerUpgrade') = 'yes' Or
       ReadProfileString($_WFile, 'Data', 'WinNtUpgrade') = 'yes'
      $_SI[18] = 'Upgrade'
    EndIf
    If ReadProfileString($_WFile, 'Unattended', 'InstallFilesPath')
      $_SI[18] = 'SysPrep'
    EndIf
  EndIf 
 
 
; HARDWARE SECTION	####################################################### 
 
 
  ; ComputerSystem	======================================================= 
  $_colItems = $_objWMIService.ExecQuery("Select * from Win32_ComputerSystem",,48)
  For Each $_objItem in $_colItems
    $_ = 'Standalone Workstation', 'Member Workstation', 'Standalone Server', 'Member Server', 'Backup Domain Controller', 'Primary Domain Controller'
    $_SI[2]   = $_[Val($_objItem.DomainRole)]
    $_SI[37]  = Left($_objItem.SystemType, 3)
    $_SI[20]  = $_objItem.Manufacturer
    $_SI[21]  = $_objItem.Model
    $_SI[26]  = $_objItem.NumberOfProcessors
    $_SI[29]  = $_objItem.TotalPhysicalMemory
    $_        = CInt((CDbl($_SI[29]) + 655360.0) / 1048576.0)
    $_SI[19]  = '' + $_ + $_SI[19]
  Next
  $_colItems  = 0
 
  ; BIOS		======================================================= 
  $_colItems = $_objWMIService.ExecQuery("Select * from Win32_BIOS",,48)
  For Each $_objItem in $_colItems
    $_SI[22]  = $_objItem.SerialNumber
    $_Delim = ''
    For Each $_ in $_objItem.BIOSVersion
      $_SI[23] = $_SI[23] + $_Delim + $_
      $_Delim = ','
    Next
  Next
  $_colItems  = 0
 
  ; Processor		======================================================= 
  $_colItems = $_objWMIService.ExecQuery("Select * from Win32_Processor",,48)
  For Each $_objItem in $_colItems
    $_SI[24]  = Trim($_objItem.Name)
    $_SI[25]  = $_objItem.MaxClockSpeed
    $_SI[27]  = $_objItem.NumberOfLogicalProcessors
    $_SI[28]  = $_objItem.NumberOfCores
    $_SI[38]  = $_objItem.DataWidth
  Next
  $_colItems  = 0
 
  ; Disk Storage	======================================================= 
  $_colItems = $_objWMIService.ExecQuery("Select * from Win32_LogicalDisk",,48)
  For Each $_objItem in $_colItems
    If $_objItem.DriveType = 3	; fixed disk 
      $_SI[30]  = $_SI[30] + ';' + $_objItem.VolumeName
      $_SI[31]  = $_SI[31] + ';' + $_objItem.Caption + '\'
      $_SI[32]  = $_SI[32] + ';' + $_objItem.Caption
      $_SI[33]  = $_SI[33] + ';' + $_objItem.Size
      $_SI[34]  = $_SI[34] + ';' + $_objItem.FreeSpace
    EndIf
    If $_objItem.DriveType = 5	; CD-ROM 
      $_SI[35]  = $_SI[35] + ';' + $_objItem.Caption
    EndIf
    If $_objItem.DriveType = 4	; Network Drive 
      $_SI[36]  = $_SI[36] + ';' + $_objItem.Caption + '=' + $_objItem.ProviderName
    EndIf
  Next
  $_colItems  = 0
 
  If $_OSVer > 5.1 ; only supported on W2K3 and higher - return mounted volume info 
    $_colItems = $_objWMIService.ExecQuery("Select * from Win32_Volume",,48)
    For Each $_objItem in $_colItems
      If $_objItem.DriveType = 3	And $_objItem.DriveLetter = ''
        $_SI[30]  = $_SI[30] + ';' + $_objItem.Label
        $_SI[31]  = $_SI[31] + ';' + $_objItem.Caption
        $_SI[32]  = $_SI[32] + ';' + 'MV:'
        $_SI[33]  = $_SI[33] + ';' + $_objItem.Capacity
        $_SI[34]  = $_SI[34] + ';' + $_objItem.FreeSpace
      EndIf
    Next
  EndIf
  $_colItems  = 0
 
  If Not $_SI[17]
    $_colItems = $_objWMIService.ExecQuery("Select * from Win32_Environment",,48)
    For Each $_objItem in $_colItems
      If InStr($_objItem.Caption, '<SYSTEM>\PROCESSOR_ARCHITECTURE')
        $_SI[17]  = IIf($_objItem.VariableValue = 'AMD64', '64-bit', '32 bit')
      EndIf
    Next
  EndIf
  $_colItems  = 0
 
 
  ; Video Hardware	======================================================= 
  $_colItems = $_objWMIService.ExecQuery("Select * from Win32_VideoController",,48)
  For Each $_objItem in $_colItems
    $_SI[39]  = $_objItem.Description + ';' + $_objItem.VideoModeDescription
  Next
  $_colItems  = 0
  $_colItems = $_objWMIService.ExecQuery("Select * from Win32_DesktopMonitor",,48)
  For Each $_objItem in $_colItems
    $_SI[39]  = $_SI[39] + ';' + $_objItem.Name
  Next
  $_colItems  = 0
 
 
  ; trim leading "," from strings 
  For $_ = 30 to 36
    $_SI[$_] = SubStr($_SI[$_], 2)
  Next
 
  ; Return the array 
  $WMISysInfo= $_SI
 
  ; Save and Set the SysWOW Registry 
  $_Reg = SetOption('WOW64AlternateRegView', $_Reg)
 
  Exit 0
 
EndFunction
 
 
; _osid - supporting function 
; Defines a "kernel short name" and removes special characters from the description string 
Function _osid($_Vs)
 
  Dim $_aR[1]			; Cleaned Descriptive Name, Short (KernelID) name 
 
  ; clean up the O/S description string - remove special chars 
  $_Vs = Join(Split($_Vs, Chr(153)), '')	; (tm) 
  $_Vs = Join(Split($_Vs, Chr(169)), '')	; (c) 
  $_Vs = Join(Split($_Vs, Chr(174)), '')	; (r) 
 
  $_aR[0] = $_Vs
 
  Select
   ; Server Platforms 
   Case InStr($_Vs, '2012')
    $_aR[1] = 'Win2K12'
   Case InStr($_Vs, '2008')
    $_aR[1] = 'Win2K8'
   Case InStr($_Vs, '2003')
    $_aR[1] = 'Win2K3'
   Case InStr($_Vs, '2000')
    $_aR[1] = 'Win2K'
    If InStr($_Vs, 'Pro') $_aR[1] = $_aR[1] + 'W' EndIf
 
   ; Desktop Platforms 
   Case InStr($_Vs, '8.1')
    $_aR[1] = 'Win8.1'
   Case InStr($_Vs, '8')
    $_aR[1] = 'Win8'
   Case InStr($_Vs, '7')
    $_aR[1] = 'Win7'
   Case InStr($_Vs, 'Vista')
    $_aR[1] = 'Vista'
  EndSelect
 
  If InStr($_Vs, 'R2')
    $_aR[1] = $_aR[1] + 'R2'
  EndIf
 
  $_osid = $_aR
 
  Exit 0  
 
EndFunction