;; 
;;=====================================================================================----- 
;; 
;;FUNCTION       OSInfo() - DEPRECATED in ITCG CODING - SEE WMISysInfo() 
;; 
;;ACTION         Returns an array containing operating system information 
;;               from local or remote system 
;; 
;;AUTHOR         Glenn Barnas  
;; 
;;VERSION	 2.0  - 2007/10/08 
;; 
;;HISTORY        2.0  - 2007/10/08 - rewrite for x64 & Vista updates 
;; 
;;SYNTAX         OSInfo([hostname] [,WMIAuth]) 
;; 
;;PARAMETERS     Hostname - Optional - String 
;;               - Parameter defining target system to obtain information from. 
;; 
;;               WMIAuth  - Optional - Object 
;;               - Pre-authenticated WMI object pointer for WMI calls 
;;               
;;REMARKS        ERROR is set to 0 if success, 1 otherwise. 
;;		 All bets are off when checking x64 systems on Kix versions before 
;;		 4.60 due to Microsoft's use of "registry reflection" and incomplete 
;;		 reflection. Elements 6, 7, 8, 9, and possibly 14 are affected by this. 
;;               This is not an issue with Kix 4.6 and higher. 
;; 
;;RETURNS        20 element array 
;;               OSInfo[0]  short/full operating system description 
;;               OSInfo[1]  kernel description (Win9x, WinNT, Win2K, WinXP, Win2K3) 
;;               OSInfo[2]  operating system role (workstation, member server, domain controller) 
;;               OSInfo[3]  operating system service pack level 
;;               OSInfo[4]  operating system build level 
;;               OSInfo[5]  uni/multi-processor type 
;;               OSInfo[6]  registered owner 
;;               OSInfo[7]  registered organization 
;;               OSInfo[8]  Product key 
;;               OSInfo[9]  Install Date - CTime format 
;;               OSInfo[10] OEM Duplicator String (Sysprep Cloning info) 
;;               OSInfo[11] UpTime 
;;               OSInfo[12] TimeZone info (Std, Daylight, Bias) 
;;               OSInfo[13] Primary Domain Affiliation 
;;               OSInfo[14] Installed Hotfix list 
;;               OSInfo[15] OS Version (numeric) 
;;               OSInfo[16] OS Class Description 
;;               OSInfo[17] OS Suite Description 
;;               OSInfo[18] Install type: Fresh, Upgrade, Sysprep 
;;               OSInfo[19] RAM/PageFile Info (location MinSize MaxSize) 
;; 
;;DEPENDENCIES   WMIUpTime(), OSI() [embedded in this file], WMI 
;; 
;;TESTED WITH    NT4, W2K, WXP, W2K3 
;; 
;;EXAMPLES       $aInfo = OSInfo('hostname')       ; returns remote host info 
;;               $aInfo = OSInfo()                 ; returns local host info 
 
Function OSInfo(OPTIONAL $_Target, Optional $_pAuth)
 
  Dim $_OS_Name, $_OS_Short, $_OS_Role, $_OS_Sp, $_OS_Build
  Dim $_OS_Proc, $_OS_Owner, $_OS_Org, $_OS_Key, $_OS_Date
  Dim $_OS_OEM, $_OS_UpTime, $_OS_TimeZone, $_OS_Hotfix, $_OS_Domain
  Dim $_OS_Version, $_OS_Class, $_OS_Suite, $_OS_Install, $_OS_PFile
  Dim $_OS_Root, $_OS_Type, $_OS_CSD, $_OS_RootUNC, $_OS_Info
  Dim $_RegSoft, $_RegCtrl, $_SClass, $_NT
  Dim $_Build, $_KeyLoc, $_OS_Sub, $_Tmp1, $_Tmp2, $_Tmp3, $_aTmp
  Dim $_, $_FTmp, $_TZ, $_OSV, $_ARV
 
  ; Base registry paths for registry reads 
  $_RegSoft='HKEY_LOCAL_MACHINE\Software\Microsoft\'
  $_RegCtrl='HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\'
 
 
  ; $System defines local machine (null) or remote server name   
  $_Target =  IIf(CStr($_Target) <> '', '\\' + Join(Split(CStr($_Target), '\'), '', 3) + '\', '')
 
  ; start by obtaining base info from the registry 
  ; If the 'Windows NT' key exists, the system is an "Enterprise Edition" class (NT, 2K, XP, etc) 
  ; otherwise it is a "Desktop Edition" class system (W95, W98, ME) 
  If KeyExist($_Target + $_RegSoft + 'Windows NT') <> 0
 
    $_SClass  = ''                ; no "D" prefix 
    $_NT      = ' NT'             ; " NT" required in Windows registry path 
 
  Else
 
    $_SClass  = 'D'               ; "D" prefix for desktop systems 
    $_NT      = ''                ; no NT in Windows registry path 
    $_OS_Sp   = 0                 ; service pack level (none) 
    $_OS_Role = 'Workstation'     ; Workstation role 
 
  EndIf
 
  ; If remote registry access is unavailable, an error will occur on the above 
  ; ExistKey operation. Abort further processing and return the error. 
  If @ERROR
    $OSInfo = '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ''
    Exit @ERROR
  EndIf
 
  ; Enable Alternate Registry View if Kix 4.6 or higher - the remaining reads to SOFTWARE must read the active 
  ; registry location and not the 32b mirrored location 
 
  If 1.0 * @KIX >= 4.6  $_ARV = SetOption('WOW64AlternateRegView', 'On') EndIf
 
  ; Extract information from registry common to all system classes 
  $_OS_Version = Join(Split(ReadValue($_Target + $_RegSoft + 'Windows' + $_NT + '\CurrentVersion', 'CurrentVersion'), '.', 2), '.')
  $_OS_Build   = ReadValue($_Target + $_RegSoft + 'Windows' + $_NT + '\CurrentVersion', 'CurrentBuildNumber')
  $_OS_Owner   = ReadValue($_Target + $_RegSoft + 'Windows' + $_NT + '\CurrentVersion', 'RegisteredOwner')
  $_OS_Org     = ReadValue($_Target + $_RegSoft + 'Windows' + $_NT + '\CurrentVersion', 'RegisteredOrganization')
  $_OS_CSD     = ReadValue($_Target + $_RegSoft + 'Windows' + $_NT + '\CurrentVersion', 'CSDVersion')
  $_Tmp2       = ReadValue($_Target + $_RegCtrl + 'Control\Session Manager\Memory Management', 'PagingFiles')
  ; Trim the trailing "|" separator character if found 
  If Right($_Tmp2, 1) = "|"
    $_Tmp2 = Left($_Tmp2, Len($_Tmp2) - 1)
  EndIf
  ; Break multiple definitions into Space Delimited values 
  $_Tmp2 = Join(Split($_Tmp2, '|'), ' ')
  ; handle system-managed, multi-drive paging files 
  If Left($_Tmp2, 1) = '?'
    $_Tmp2 = 'Auto Managed - all drives'
  EndIf
 
  ; Universal method of determining physical RAM 
  $_Tmp1 = Memory($_Target)
 
  ; WMI uptime  
  $_aTmp = WMIUpTime($_Target, $_pAuth)
  If @ERROR
    $_OS_Uptime = 'Not Determined' 
  Else
    $_OS_Uptime = '' + $_aTmp[0] + '-' + Right('00' + $_aTmp[1], 2) + ':' + Right('00' + $_aTmp[2], 2) + ':' + Right('00' + $_aTmp[3], 2)
  EndIf
 
  $_OS_PFile = CStr($_Tmp1) + ' ' + $_Tmp2
 
  ; OSV defines the INI section - a combination of DeskTop ClassID and OS Version 
  $_OSV = $_SClass + $_OS_Version
 
 
  ; extract information specific to Enterprise-class systems 
  If $_SClass = '' ; ------------------------------------------------------------------------- 
 
    $_OS_Proc    = ReadValue($_Target + $_RegSoft + 'Windows NT\CurrentVersion', 'CurrentType')
    $_OS_OEM     = ReadValue($_Target + $_RegSoft + 'Windows NT\CurrentVersion', 'OEMDuplicatorString')
    $_OS_Date    = Val(ReadValue($_Target + $_RegSoft + 'Windows NT\CurrentVersion', 'InstallDate'))
    $_OS_Domain  = ReadValue($_Target + $_RegSoft + 'Windows NT\CurrentVersion\WinLogon', 'CachePrimaryDomain')
    If Not $_OS_Domain
      $_OS_Domain  = ReadValue($_Target + $_RegCtrl + 'Services\Tcpip\Parameters', 'Domain')
    EndIf
    $_OS_Root    = ReadValue($_Target + $_RegSoft + 'Windows NT\CurrentVersion', 'SystemRoot')
    $_OS_RootUNC = $_Target + Left($_OS_Root,1) + Chr(36) + Right($_OS_Root, Len($_OS_Root) - 2)
    $_OS_Suite   = ReadValue($_Target + $_RegCtrl + 'Control\ProductOptions', 'ProductSuite')
    $_OS_Type    = ReadValue($_Target + $_RegCtrl + 'Control\ProductOptions', 'ProductType')
 
    $_TZ = ReadValue($_Target + $_RegCtrl + 'Control\TimeZoneInformation', 'StandardName')
    If Left($_TZ, 1) <> Chr(64)
      $_TZ = $_TZ + ' / ' + ReadValue($_Target + $_RegCtrl + 'Control\TimeZoneInformation', 'DaylightName')
      $_TZ = $_TZ + ' / ' + Val(ReadValue($_Target + $_RegCtrl + 'Control\TimeZoneInformation', 'Bias')) / 60
    Else
      $_ = ReadValue($_Target + $_RegCtrl + 'Control\TimeZoneInformation', 'TimeZoneKeyName')
      $_TZ = ReadValue($_Target + $_RegSoft + 'Windows NT\CurrentVersion\Time Zones\' + $_, 'Std')
      $_TZ = $_TZ + ' / ' + ReadValue($_Target + $_RegSoft + 'Windows NT\CurrentVersion\Time Zones\' + $_, 'Dlt')
      $_TZ = $_TZ + ' / ' + Val(ReadValue($_Target + $_RegCtrl + 'Control\TimeZoneInformation', 'Bias')) / 60
    EndIf
 
    $_OS_TimeZone = $_TZ
 
    ; Determine Server Role and Class 
    Select
    Case $_OS_Type = 'LanManNT'          ; DC Role 
      $_OS_Role  = 'Domain Controller'
      $_OS_Class = 'Server'
 
    Case $_OS_Type = 'ServerNT'          ; Server Role 
      $_OS_Role  = 'Member Server'
      $_OS_Class = 'Server'
 
    Case $_OS_Type = 'WinNT'             ; Workstation Role 
      $_OS_Role  = 'Workstation'
      $_OS_Class = OSI($_OSV, 'Class', '', $_Target)
 
    Case 1                              ; Undefined 
      $_OS_Role  = 'Undefined'
      $_OS_Class = 'Undefined'
 
    EndSelect
 
 
    ; trim any trailing separator character from the OS Suite string 
    If Right($_OS_Suite, 1) = '|'
      $_OS_Suite = Left($_OS_Suite, Len($_OS_Suite) - 1)
    EndIF
 
 
    ; Get service pack level from the OSD string 
    If InStr($_OS_CSD,'Service Pack')
      $_OS_Sp = Split($_OS_CSD ,'Service Pack')
      $_OS_Sp = Trim($_OS_Sp[UBound($_OS_Sp)])
 
    ; Identify the NT4 SP6 rerelease as 6a 
      If $_OS_Sp = 6 And $_OS_Version = '4.0'
        $_Tmp1 = ReadValue($_Target + $_RegSoft + 'Windows' + $_NT + '\CurrentVersion\Hotfix\Q246009','Comments')
        If $_Tmp1 = "Windows NT 4.0 Hotfix:  Service Pack 6 Re-release"
          $_OS_Sp = $_OS_Sp + 'a'
          $_OS_CSD = $_OS_CSD + 'a'
        EndIf
      EndIf
 
    EndIf
 
  
    ; get the list of installed hotfixes by enumerating the HotFix registry 
    ; key and identifying keys with an "installed" value of "1" 
    $_Tmp1 = 0	; index 
    $_Tmp2 = ''	; Hotfix enumerated 
    $_Tmp3 = 0	; Hotfix "installed" value 
    Do
      $_Tmp2 = EnumKey($_Target + $_RegSoft + 'Windows' + $_NT + '\CurrentVersion\Hotfix\', $_Tmp1)
      $_Tmp3 = ReadValue($_Target + $_RegSoft + 'Windows' + $_NT + '\CurrentVersion\Hotfix\' + $_Tmp2,'Installed')
      If $_Tmp3 = 1  $_OS_HotFix = $_OS_HotFix + $_Tmp2 + ' ' EndIf
      $_Tmp1 = $_Tmp1 + 1
    Until @ERROR <> 0
 
 
    ; OS install type is Clean, Upgrade, or Sysprep 
    ; Default is Clean Install 
    $_OS_Install = 'Clean'
 
    ; If key values are 'yes', this system was upgraded 
    $_FTmp = $_OS_RootUNC + '\System32\' + Chr(36) + 'Winnt' + Chr(36) + '.inf'
    $_Tmp1 = ReadProfileString($_FTmp, 'Data', 'StandardServerUpgrade')
    $_Tmp1 = $_Tmp1 + ReadProfileString($_FTmp, 'Data', 'WinNtUpgrade')
    If InStr($_Tmp1, 'Yes')
      $_OS_Install = 'Upgrade'
    EndIf
 
    ; If unattend value is defined, it is a Sysprep image 
    $_Tmp1 = ReadProfileString($_FTmp, 'Unattended', 'InstallFilesPath')
    If InStr($_Tmp1, 'Sysprep')
      $_OS_Install = 'Sysprep'
    EndIF
 
    $_Build = $_OS_Build
 
  Else ; ------------------------------------------------------------------------------------ 
    ; extract information specific to Desktop-class systems 
 
    $_Build = ReadValue($_Target + $_RegSoft + 'Windows' + $_NT + '\CurrentVersion', 'SubVersionNumber')
 
  EndIF ; ----------------------------------------------------------------------------------- 
 
 
  ; Extract OS identification info from the INI file 
  ; INI file is used to simplify maintenance of build-level identifications 
 
  ; Get long name (ie: Windows 2000) 
  $_OS_Name = OSI($_OSV, 'Name')
 
  ; Get short name (ie: Win2K) 
  $_OS_Short = OSI($_OSV, 'Short')
 
  ; Get info based on build (ie: beta, RC, or other specialized releases) 
  $_OS_Info  = OSI($_OSV, 'Build', $_Build)
  If $_OS_Info <> ''
    $_OS_Name = $_OS_Name + ' ' + $_OS_Info
  EndIf
 
 
  ; Get registry key location 
  $_KeyLoc = OSI($_OSV, 'KeyLoc')
  ; get the license key from the defined location 
  $_OS_Key = ReadValue($_Target + $_RegSoft + 'Windows' + $_NT + '\CurrentVersion', $_KeyLoc)
 
  $OSInfo = $_OS_Name, $_OS_Short, $_OS_Role, $_OS_Sp, $_OS_Build, $_OS_Proc, $_OS_Owner, $_OS_Org, $_OS_Key, $_OS_Date, $_OS_OEM, $_OS_UpTime, $_OS_TimeZone , $_OS_Domain, $_OS_HotFix, $_OS_Version, $_OS_Class, $_OS_Suite, $_OS_Install, $_OS_PFile
 
  ; Restore the Alternate Registry View setting if Kix 4.6 or higher 
  If Val(@KIX) >= 4.6 $_ARV = SetOption('WOW64AlternateRegView', $_ARV) EndIf
 
  Exit 0
 
EndFunction
 
 
;; Maintain array of O/S variable information 
;; 
;; $OSList is an array of OS version numbers determined in the code above 
;; $NmList is an array of parameter names 
;; These two variables reference a value in a two-dimensional array that contains 
;; the Full Name, Short Name, serial # RegKey name, Class Name, and list of build identifiers 
;; 
;; The requested name value is returned, based on the O/S version 
;; 
Function OSI($_OSVer, $_Name, Optional $_BldID, Optional $_Host)
 
  Dim $_, $_OSList, $_NmList, $_NmID, $_TMP, $_BLD, $_OSID
 
  ; array of OS version identifiers - add new version numbers as relesaed 
  $_OSList = 'D4.0', 'D4.10', 'D4.90', '4.0', '5.0', '5.1', '5.2', '6.0'
 
  ; array of name identifiers 
  $_NmList = 'Nam', 'Sho', 'Key', 'Cla', 'Bui'
 
  ; first value of the OS array is determined by the UBound of the OSList array 
  ; [0]=O/S Long Name 
  ; [1]=O/S Short Name 
  ; [2]= 
  ; [3]=Name of non-server version 
  ; [4]=Sub-release values 
  Dim $_OS[UBound($_OSList),4]
    ; populate the array 
    $_OS[0,0] = 'Windows 95'
    $_OS[0,1] = 'Win95'
    $_OS[0,2] = 'ProductKey'
    $_OS[0,3] = ''
    $_OS[0,4] = 'a=Service Pack 1,b=OSR2.0,c=OSR2.5'
 
    $_OS[1,0] = 'Windows 98'
    $_OS[1,1] = 'Win98'
    $_OS[1,2] = 'ProductKey'
    $_OS[1,3] = ''
    $_OS[1,4] = 'a=Second Edition,b=B,c=SE'
 
    $_OS[2,0] = 'Windows ME'
    $_OS[2,1] = 'WinME'
    $_OS[2,2] = 'ProductKey'
    $_OS[2,3] = ''
    $_OS[2,4] = ''
 
    $_OS[3,0] = 'Windows NT'
    $_OS[3,1] = 'WinNT'
    $_OS[3,2] = 'ProductID'
    $_OS[3,3] = 'Workstation'
    $_OS[3,4] = ''
 
    $_OS[4,0] = 'Windows 2000'
    $_OS[4,1] = 'Win2K'
    $_OS[4,2] = 'ProductID'
    $_OS[4,3] = 'Professional'
    $_OS[4,4] = '1515=(Beta 2),2031=(Beta 3),2183=(Beta 3),2128=(Beta 3 RC2)'
 
    $_OS[5,0] = 'Windows XP'
    $_OS[5,1] = 'WinXP'
    $_OS[5,2] = 'ProductID'
    $_OS[5,3] = 'Professional'
    $_OS[5,4] = '2505=(RC1)'
 
    $_OS[6,0] = 'Windows 2003'
    $_OS[6,1] = 'Win2K3'
    $_OS[6,2] = 'ProductID'
    $_OS[6,3] = ''
    $_OS[6,4] = '3718=(Eval)'
 
    $_ = Split(ReadValue($_Host + 'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion', 'ProductName'), 'Vista ')
    $_ = $_[UBound($_)]
    If InStr($_, ')') $_ = Trim(Split($_, ')')[1]) EndIf
    $_OS[7,0] = 'Windows Vista'
    $_OS[7,1] = 'WinV'
    $_OS[7,2] = 'ProductID'
    $_OS[7,3] = ReadValue($_Host + 'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion', 'EditionID')
    $_OS[7,4] = ''
    ; add entries for new OS versions as needed 
 
  
  ; Find the OS version and variable name values 
  $_OSID = AScan($_OSList, $_OSVer)
  $_NmID = AScan($_NmList, Left($_Name,3))
 
  ; Either return the value indicated by the OSID and NMID, or split the BUILD info and return that 
  If $_NmID < 4
    $OSI = $_OS[$_OSID, $_NmID]
  Else
    $_Tmp = Split($_OS[$_OSID, $_NmID], ',')
    For Each $_Bld in $_Tmp
      If InStr($_Bld, $_BldID) = 1
        $OSI = Split($_Bld, '=')[1]
      EndIf
    Next
  EndIf
 
EndFunction