'==========================================================================
'
' NAME: Script-Compliance-1.0.0-M-R1.vbs
'
' AUTHOR:  Max Erenburg 
' DATE  : 3/22/2018
'
' COMMENT: This script will copy blat mailer & CMTrace locally to the asset
' Health check the OS (basics) and execute any other scripts per classification.
' Update 04/11/2018 added Script-LADM-Compliance-M-R1.vbs for Clients.
' Update 04/18/2018 added logic for HOSTS file entry exceptions (client/Server) and paths for both forests based on FQDN found at run time.
' Update 04/26/2018 added Install-Qualys-Cloud-Security-Agent-1.6.3.8-M-R1.vbs for Clients/Servers.
' Update 05/01/2018 added Install-UniversalForwarder-x64-6.6.4.0-M-R1.vbs for Servers.
' Update 05/02/2018 added Install-FireEye-Endpoint-Agent-24.9.0-M-R1.vbs for Clients/Servers.
' Update 05/08/2018 added Install-Cylance-PROTECT-x64-2.0.1480.24-M-R1.vbs for Clients/Servers.
' Update 05/18/2018 added ServerCore check, cleaned up some code.
' Update 05/29/2018 added CB check for Win10/Srv2016
' Update 06/06/2018 added test of new Qualys Agent version, and SME changed Client Activation Key (need to reinstall all clients...)
' Update 06/13/2018 added Recieved go ahead from SME to changed Client Activation Key (need to reinstall all clients...) AND move to new Qualys Agent version.
' Update 07/23/2018 added Install-Cylance-PROTECT-x64-2.0.1490.27-M-R1.vbs for Clients/Servers. Detect corrupted quarantine, deal with PRODUCTCODE that does not change.
' Update 07/30/2018 added Install-FireEye-Endpoint-Agent-26.21.10-M-R1.vbs for Clients/Servers. (upgrade)
' Update 10/30/2018 added Install-Qualys-Cloud-Security-Agent-2.1.1.34-M-R1.vbs for Clients/Servers/DC's.
' Update 12/14/2018 noticed EMET (last package) script was being blocked by Cylance installation (immediately after install blocks all scripts automatically).
' Update 01/02/2019 added Install-Cylance-PROTECT-x64-2.0.1500.18-M-R1.vbs for Clients/Servers.
' Update 01/04/2019 added Script-Gather-DataCollect-M-R1.vbs for Clients/Servers.
' Update 02/18/2019 added sync up with PROD versiondue to changes for Win10 without DEV testing (Script-Gather-DataCollect-M-R1.vbs for clients, also added update GetOSInfo funtion.)
' Update 04/02/2019 added new version of Cylance Agent
' Update 04/16/2019 added new version of Qualys Agent and FireEye agent for Clients
' Update 08/02/2019 added new version of Cylance Agent and Pilot version as well (added code to generate ticket with SD system): Mandatory Patch for Vuln.
' Update 08/05/2019 added new version of Cylance Agent (changed code to generate ticket as as it@theorchard.com): Mandatory Patch for Vuln.
' Update 10/30/2019 added Install-FireEye-Endpoint-Agent-30.19.0-M-R1.vbs for Clients (only approved of clients by A.O. at this time)
' Update 10/31/2019 added Install-FireEye-Endpoint-Agent-30.19.0-M-R1.vbs for Servers (approved by A.O.)
' Update 11/01/2019 update logic to not produce multipule tickets on same failure
' Upadte 04/14/2020 added Install-Cylance-PROTECT-x64-2.0.1540.8-M-R1.vbs for Clients/Servers. Updated to utilize PROD-T1-BISSELL for modified host files.
' Update 05/10/2020 move to new host at AVL and FQDN the host names
' Update 05/21/2020 added Install-Qualys-Cloud-Security-Agent-3.1.5.43-M-R1.vbs (SME didnt alert us nor provide source for this new version)
' Update 06/29/2020 added Install-FireEye-Endpoint-Agent-31.28.8-M-R1.vbs as PROD version for Clients/Servers (only copying out to NYC not AVL yet.) | case sensitivity fix for CLIENT SERVICES 
' Update 07/01/2020 added ability to Pilot more than one software at a time on different assets individually.
' Update 08/05/2020 added Install-Qualys-Cloud-Security-Agent-4.0.0.404-M-R1.vbs (SME didnt provide source for this new version)
' Update 08/10/2020 added Install-Qualys-Cloud-Security-Agent-4.0.0.411-M-R1.vbs (hotfix by vendor)
' Upadte 08/13/2020 altered Install-Cylance-PROTECT-x64-2.0.1540.8-M-R1.vbs to also version 2.1.1560.25 and not perform helath chech (transition to UD model)
' Upadte 08/17/2020 added Install-Cylance-PROTECT-x64-2.1.1560.25-M-R1.vbs as PROD version
' Upadte 08/20/2020 added Install-Cylance-PROTECT-x64-2.1.1564.39-M-R1.vbs available for Pilot testing
' Upadte 09/01/2020 added Install-Cylance-PROTECT-x64-2.1.1564.39-M-R1.vbs as PROD version
' Update 09/30/2020 Cylance update to new package version 2.1.1564.40 Security hotfix and allow pilot of 1570.35
' Update 04/28/2021 added Install-Qualys-Cloud-Security-Agent-4.2.0.8-M-R1.vbs available for Pilot testing (NEW as of 1-23-2021)
' Update 05/03/2021 added Install-Qualys-Cloud-Security-Agent-4.2.0.8-M-R1.vbs as PROD version
' Update 05/18/2021 added Install-Cylance-PROTECT-x64-2.1.1574.39-M-R1.vbs available for Pilot testing
' Update 05/20/2021 added Install-Qualys-Cloud-Security-Agent-4.4.0.38-M-R1.vbs (SME didnt provide source for this new version) for Pilot testing
' Update 06/07/2021 added Install-Qualys-Cloud-Security-Agent-4.4.1.5-M-R1.vbs (SME didnt provide source for this new version) for Pilot testing
' Update 06/07/2021 added Install-Qualys-Cloud-Security-Agent-4.4.1.5-M-R1.vbs as PROD version emergency upgrade per Qualys for version 4.4.0.38
' Update 07/12/2021 added Install-Qualys-Cloud-Security-Agent-4.4.1.7-M-R1.vbs as PROD version
'==========================================================================

Option Explicit

Dim vDate, vTime, altTime, altDate, vDateTime
vDateTime = Now

Dim oShell, oFSO, oProcessEnv, sScript, iErrCode, sMsg
Dim sDebug, sDebugBlat, sSuccess, sPilot, sTicket
Dim sMailbox1, sMailbox2, sMailbox3, sSD, sRelayHost, sFrom, sCN, sFQDN, sTry
Dim sSrcRoot, sSystem32, sLogDir, sScriptsDir, sEmailDir, sDebugLog
Dim sDomFQDN, sDN, sLib, sBlat, sEngKey
Dim sCoreBlat, sCoreBlat2, sCoreWMI, sCoreInfo, sCoreInfo2, sCoreInfo3, DebugLog
Dim ProductName, IsServer, IsServerCore, CBVer, CSDver, s64Bit, DC, sPBV, PBV, sPTV, PTV
Dim sWBEM, sWBEM2, sMSHTA, sMSI, sWU, sWUver, sWMIver, sHTAver, sWIver, sIEver, sFileVer
Dim oWMI, sWMIFailed, sWMIMsgBody2
Dim LBT, iOSLang, sOSLangHex, sOSLanguage
Dim TZ, description, address, subnet, subnetmask, CMPDomain, ADSite

Set oShell = CreateObject("WScript.Shell")
Set oFSO = CreateObject("Scripting.FileSystemObject")
Set oProcessEnv = oShell.Environment("PROCESS")

Const DEPLOYNAME = "Compliance-1.2.4"
Const SIDE = "-M"
Const RELEASE = "-R1"
sScript = "Script-" & DEPLOYNAME & SIDE & RELEASE

sDebug = "False" : sDebugBlat = "False" ' Email if blat found missing and copied down local.
sSuccess = "False" ' Set to False if you dont want success emails. ' For enterprise deployment set to false, for one off installations leave as True
sPilot = "False" ' Set to False if you dont want attachment of debug file to success emails. ' Use for QA/UAT, once ready for Production deployments set to false
sTicket = "False"

sMailbox1 = "merenburg@theorchard.com" : sMailbox2 = "" : sMailbox3 = "bwilliams@theorchard.com" : sSD = "techsupport@theorchard.com"
sRelayHost = "smtp-relay.gmail.com"
sFrom = "it"
sCN = oProcessEnv("COMPUTERNAME")
sFQDN = "@TheOrchard.com"
sTry = "2"

sSrcRoot = Replace(WScript.ScriptFullName, WScript.ScriptName, "")
sSystem32 = oProcessEnv("SYSTEMROOT") & "\system32\"
sLogDir = oProcessEnv("SYSTEMROOT") & "\EngLogs"
sScriptsDir = sLogDir & "\Scripts"
sEmailDir = sLogDir & "\Email"
sDebugLog = sScriptsDir & "\" & sScript & ".log"

sBlat = sSystem32 & "blat.exe"
sEngKey = "HKLM\SOFTWARE\ORCDENG\"

sMsg = "Scriptname: " & WScript.ScriptName
sMsg = sMsg & "|ScriptPath: " & WScript.ScriptFullName

' Get Domain Name we are working with so we dont have to have additional copies of same script per AD Forest/Domain.
Call GetDomainName
sLib = "\\" & sDomFQDN & "\netlogon\lib\"

' Ensure email alerts are available
Call CopyBlat

' Get OS, CSD information
Call GetOSInfo

' Get OS Install Date
Call GetInstallDate

' Get WSH & VBscript version
sMsg = sMsg & "|WSH Version: " & WScript.Version & ", VBScript Version: " & ScriptEngineMajorVersion & "." & ScriptEngineMinorVersion

' Get WMI dll version for logging/analysis
sWBEM = oProcessEnv("SYSTEMROOT") & "\system32\wbem\repdrvfs.dll"
sWBEM2 = oProcessEnv("SYSTEMROOT") & "\system32\wbem\wbemupgd.dll" ' W2K original version
Call GetFileVer(sWBEM)
If sFileVer = "File not found." Then Call GetFileVer(sWBEM2)
sWMIver = sFileVer
sMsg = sMsg & "|WMI Version: " & sWMIver
sFileVer = ""

' Get MSHTA version for logging/analysis
sMSHTA = oProcessEnv("SYSTEMROOT") & "\system32\mshta.exe"
Call GetFileVer(sMSHTA)
sHTAver = sFileVer
sMsg = sMsg & "|HTA Version: " & sHTAver
sFileVer = ""

' Get MSI version for logging/analysis
sMSI = oProcessEnv("SYSTEMROOT") & "\system32\msi.dll"
Call GetFileVer(sMSI)
sWIver = sFileVer
sMsg = sMsg & "|Windows Installer Version: " & sWIver & "." ' Do not remove this last & "." otherwise it wraps
sFileVer = ""

' Get Windows Update Agent version for logging/analysis
sWU = oProcessEnv("SYSTEMROOT") & "\system32\wuaueng.dll"
Call GetFileVer(sWU)
sWUver = sFileVer
sMsg = sMsg & "|Windows Update Agent Version: " & sWUver & "." ' Do not remove this last & "." otherwise it wraps
sFileVer = ""

' Get IE version for logging/analysis
Call GetIEInfo

' Check health state of WMI, if found to be currupted script will NOT exit.
Call WMIHealthCheck

If sWMIFailed <> "Failed" Then
	Set oWMI = GetObject("winmgmts:\\.\root\cimv2")
End If	

' Get OS Locale (Get Locale information)
Call GetOSLocale

' Get Time Zone description
Call GetTZ

' Get Nic information we are working with
Call GetNetworkInterface
	
' Get Manufacturer/Model info on the device
Call GetDeviceInfo
	
' Get device's Domain/Workgroup name
Call GetCMPDomain

' Get AD Site information
Call GetADSite

sMsg = sMsg & "|ScriptPath: " & WScript.ScriptFullName

' Create directory(s) for local centralized logging
Call CreateLogDirs

' Create debug log or append to log if this script has been run before
Call CreateDebugLog("FirstCheck")

' Copy CMTrace for Real-time event log parsing
Call CopyCMTrace

' Export local HOST file
Call CopyLH

If sWMIFailed = "Failed" Then 'fail with hard error as we need WMI up and running (health to perform installs, etc..)
	If Not IsObject(DebugLog) Then Call CreateDebugLog("WriteLog")
	WSHLog "CriticalFailure", sWMIMsgBody2
End If

' Based on asset classification, run next scripts
Call ExecNextScripts

If IsObject(DebugLog) Then DebugLog.WriteLine(Now & "__ Wrapper execution complete, total execution time: " & DateDiffToWords(vDateTime,Now))
WSHLog "Information", "Wrapper execution complete, total execution time: " & DateDiffToWords(vDateTime,Now)

' Log/email exit code, cleanup and exit
If Not (IsNull(iErrCode) Or IsEmpty(iErrCode)) Then
	If Not IsObject(DebugLog) Then Call CreateDebugLog("WriteLog")
	DebugLog.WriteLine(Now & "__ Exiting... Wrapper exit code : " & iErrCode)
	If (sSuccess = "True") And (sPilot = "False") And (sCoreBlat = "") Then Email sScript & "  Status", "Wrapper exit code : " & iErrCode & "|" & sMsg
	Call Cleanup(sScript & "  Status", "Wrapper exit code : " & iErrCode & "|" & sMsg)
	WScript.Quit(iErrCode)
Else
	If IsObject(DebugLog) Then DebugLog.WriteLine(Now & "__ Exiting... Wrapper exit code  : " & Err.Number)
	If (sSuccess = "True") And (sPilot = "False") And (sCoreBlat = "") Then Email sScript & "  Status", "Wrapper exit code  : " & Err.Number & "|" & sMsg
	If sTicket = "True" Then sTicket = "False" : sMailbox2 = "" : sMailbox3 = ""
	Call Cleanup(sScript & "  Status", "Wrapper exit code  : " & Err.Number & "|" & sMsg)
	WScript.Quit
End If

' ------------------------------------------Function / Subs -------------------------------------------

' Based on asset classification, run next scripts
Function ExecNextScripts
	Dim sPilot_LAPS : sPilot_LAPS = False
	Dim sPilot_DataCollect : sPilot_DataCollect = False
	Dim sPilot_LADM : sPilot_LADM = False
	Dim sPilot_DISM : sPilot_DISM = False
	Dim sPilot_GlobalProtect : sPilot_GlobalProtect = False
	Dim sPilot_Qualys : sPilot_Qualys = False
	Dim sPilot_Splunk : sPilot_Splunk = False
	Dim sPilot_FireEye : sPilot_FireEye = False
	Dim sPilot_EMET : sPilot_EMET = False
	Dim sPilot_Cylance : sPilot_Cylance = False

	On Error Resume Next
	Const E_ADS_PROPERTY_NOT_FOUND  = &h8000500D
	Dim oCMP, aMemberOf, oGroup

	Set oCMP = GetObject("LDAP://" & sDN)
	aMemberOf = oCMP.GetEx("memberOf")

	If NOT (Err.Number = E_ADS_PROPERTY_NOT_FOUND) Then ' otherwise it means the asset has no other memberships other than a primary group and we dont bother checking any further
		' MsgBox "Member of " & uBound(aMemberOf) + 1 & " groups: " ' for debug
		For Each oGroup in aMemberOf
			'MsgBox oGroup ' for debug
			If InStr(UCase(oGroup), UCase("Compliance_Pilot_LAPS")) Then
				sPilot_LAPS = True
			ElseIf InStr(UCase(oGroup), UCase("Compliance_Pilot_DataCollect")) Then
				sPilot_DataCollect = True
			ElseIf InStr(UCase(oGroup), UCase("Compliance_Pilot_LADM")) Then
				sPilot_LADM = True
			ElseIf InStr(UCase(oGroup), UCase("Compliance_Pilot_DISM")) Then
				sPilot_DISM = True
			ElseIf InStr(UCase(oGroup), UCase("Compliance_Pilot_GlobalProtect")) Then
				sPilot_GlobalProtect = True
			ElseIf InStr(UCase(oGroup), UCase("Compliance_Pilot_Qualys")) Then
				sPilot_Qualys = True
			ElseIf InStr(UCase(oGroup), UCase("Compliance_Pilot_Splunk")) Then
				sPilot_Splunk = True
			ElseIf InStr(UCase(oGroup), UCase("Compliance_Pilot_FireEye")) Then
				sPilot_FireEye = True
			ElseIf InStr(UCase(oGroup), UCase("Compliance_Pilot_EMET")) Then
				sPilot_EMET = True
			ElseIf InStr(UCase(oGroup), UCase("Compliance_Pilot_Cylance")) Then
				sPilot_Cylance = True
			End If
		Next
	End If
	On Error Goto 0

	Dim sClass
	If IsServer = "True" Then
		If DC = "True" Then
			sClass = "DC"
		Else
			sClass = "Server"
		End If
		' All servers are x64
		If NOT (DC = "True") AND sPilot_LAPS = False Then
			Call ExecScript(sClass, "LAPS\6.2\Install-LAPS-6.2.0.0-M-R1.vbs") ' Currently synced Prod and DEV
		ElseIf NOT (DC = "True") AND sPilot_LAPS = True Then ' Run new Pilot version for QA
			Call ExecScript(sClass, "LAPS\6.2\Install-LAPS-6.2.0.0-M-R1.vbs") ' LAPS\X.X\Install-LAPS-X.X.X.X-M-R1.vbs
		End If
		If sPilot_DataCollect = False Then
			Call ExecScript(sClass, "DataCollect\Script-Gather-DataCollect-M-R1.vbs") ' NOT SYNCED 
		Else ' Run new Pilot version for QA
			Call ExecScript(sClass, "DataCollect\Script-Gather-DataCollect-M-R1-DEV.vbs") ' Debug, seems like race or nic driver condition
		End If
		If NOT (DC = "True") AND sPilot_LADM = False Then
			Call ExecScript(sClass, "LADM\Script-LADM-Compliance-M-R1.vbs") ' Currently synced Prod and DEV
		ElseIf NOT (DC = "True") AND sPilot_LADM = True Then ' Run new Pilot version for QA
			Call ExecScript(sClass, "LADM\Script-LADM-Compliance-M-R1.vbs") ' Script-LADM-Compliance-M-R1-DEV.vbs"
		End If
		If sPilot_DISM = False Then
			Call ExecScript(sClass, "PatchState\Script-PatchState-DISM-M-R1.vbs") ' Currently synced Prod and DEV
		Else ' Run new Pilot version for QA
			Call ExecScript(sClass, "PatchState\Script-PatchState-DISM-M-R1.vbs") ' Script-PatchState-DISM-M-R1-DEV.vbs NEW 5-18-2020
		End If
		If sPilot_Qualys = False Then
			'Call ExecScript(sClass, "Qualys\4.4.1.5\Install-Qualys-Cloud-Security-Agent-4.4.1.5-M-R1.vbs") ' NEW 6-07-2021 (now rollback)
			Call ExecScript(sClass, "Qualys\4.4.1.7\Install-Qualys-Cloud-Security-Agent-4.4.1.7-M-R1.vbs") ' NEW 7-12-2021
		Else' Run new Pilot version for QA
			'Call ExecScript(sClass, "Qualys\4.4.1.5\Install-Qualys-Cloud-Security-Agent-4.4.1.5-M-R1.vbs") ' NEW 6-07-2021
			Call ExecScript(sClass, "Qualys\4.4.1.7\Install-Qualys-Cloud-Security-Agent-4.4.1.7-M-R1.vbs") ' NEW 7-12-2021
		End If
		If sPilot_Splunk = False Then ' Servers ONLY
			Call ExecScript(sClass, "SplunkUF\6.6.4.0\Install-UniversalForwarder-x64-6.6.4.0-M-R1.vbs") ' Currently synced Prod and DEV
		Else ' Run new Pilot version for QA
			Call ExecScript(sClass, "SplunkUF\6.6.4.0\Install-UniversalForwarder-x64-6.6.4.0-M-R1.vbs") ' Install-UniversalForwarder-x64-x.x.x.x-M-R1.vbs
		End If
		If sPilot_FireEye = False Then
			'Call ExecScript(sClass, "FireEye\30.19.0\Install-FireEye-Endpoint-Agent-30.19.0-M-R1.vbs") ' NOT SYNCED new version in pilot (now rollback)
			Call ExecScript(sClass, "FireEye\31.28.8\Install-FireEye-Endpoint-Agent-31.28.8-M-R1.vbs") ' NEW 6-29-2020 approval to deploy to all prod
		Else ' Run new Pilot version for QA
			Call ExecScript(sClass, "FireEye\31.28.8\Install-FireEye-Endpoint-Agent-31.28.8-M-R1.vbs") ' NEW 5-20-2020
		End If
		' EMET is EOL no newer version for OS versions greater than 2012 R2
		If Not (InStr(UCase(ProductName), "2016") Or InStr(UCase(ProductName), "2019")) Then Call ExecScript(sClass, "EMET\5.52\Install-EMET-5.52-M-R1.vbs")
		If sPilot_Cylance = False Then
			'Call ExecScript(sClass, "Cylance\2.1.1564.40\Install-Cylance-PROTECT-x64-2.1.1564.40-M-R1.vbs") ' Rollback optionNEW 9-30-2020
			Call ExecScript(sClass, "Cylance\2.1.1570.35\Install-Cylance-PROTECT-x64-2.1.1570.35-M-R1.vbs") ' NEW 5-18-2021
		Else ' Run new Pilot version for QA
			'Call ExecScript(sClass, "Cylance\2.1.1564.40\Install-Cylance-PROTECT-x64-2.1.1564.40-M-R1.vbs") ' Rollback optionNEW 9-30-2020
			'Call ExecScript(sClass, "Cylance\2.1.1570.35\Install-Cylance-PROTECT-x64-2.1.1570.35-M-R1.vbs") ' Rollback optionNEW 9-30-2020
			Call ExecScript(sClass, "Cylance\2.1.1574.39\Install-Cylance-PROTECT-x64-2.1.1574.39-M-R1.vbs") ' NEW 5-18-2021
		End If
	Else ' Clients, separating in order to allow deploying to individual class.
		sClass = "Client"
		If (s64Bit = "1" AND sPilot_LAPS = False) Then
			Call ExecScript(sClass, "LAPS\6.2\Install-LAPS-6.2.0.0-M-R1.vbs") ' Currently synced Prod and DEV
		ElseIf (s64Bit = "1" AND sPilot_LAPS = True) Then ' Run new Pilot version for QA
			Call ExecScript(sClass, "LAPS\6.2\Install-LAPS-6.2.0.0-M-R1.vbs") ' LAPS\X.X\Install-LAPS-X.X.X.X-M-R1.vbs
		End If
		If sPilot_DataCollect = False Then
			Call ExecScript(sClass, "DataCollect\Script-Gather-DataCollect-M-R1.vbs") ' NOT SYNCED 
		Else ' Run new Pilot version for QA
			Call ExecScript(sClass, "DataCollect\Script-Gather-DataCollect-M-R1-DEV.vbs") ' Debug, seems like race or nic driver condition
		End If
		If sPilot_LADM = False Then
			Call ExecScript(sClass, "LADM\Script-LADM-Compliance-M-R1.vbs") ' Currently synced Prod and DEV
		Else ' Run new Pilot version for QA
			Call ExecScript(sClass, "LADM\Script-LADM-Compliance-M-R1.vbs") ' Script-LADM-Compliance-M-R1-DEV.vbs"
		End If
		If sPilot_DISM = False Then
			Call ExecScript(sClass, "PatchState\Script-PatchState-DISM-M-R1.vbs") ' Currently synced Prod and DEV
		Else ' Run new Pilot version for QA
			Call ExecScript(sClass, "PatchState\Script-PatchState-DISM-M-R1.vbs") ' Script-PatchState-DISM-M-R1-DEV.vbs NEW 5-18-2020
		End If
		If sPilot_GlobalProtect = False Then ' Clients ONLY
			Call ExecScript(sClass, "GlobalProtect\Script-PA-GP-M-R1.vbs") ' Currently synced Prod and DEV
		Else ' Run new Pilot version for QA
			Call ExecScript(sClass, "GlobalProtect\Script-PA-GP-M-R1.vbs")  ' GlobalProtect\Script-PA-GP-M-R1-DEV.vbs
		End If
		If sPilot_Qualys = False Then
			'Call ExecScript(sClass, "Qualys\4.4.1.5\Install-Qualys-Cloud-Security-Agent-4.4.1.5-M-R1.vbs") ' NEW 6-07-2021 (now rollback)
			Call ExecScript(sClass, "Qualys\4.4.1.7\Install-Qualys-Cloud-Security-Agent-4.4.1.7-M-R1.vbs") ' NEW 7-12-2021
		Else' Run new Pilot version for QA
			'Call ExecScript(sClass, "Qualys\4.4.1.5\Install-Qualys-Cloud-Security-Agent-4.4.1.5-M-R1.vbs") ' NEW 6-07-2021
			Call ExecScript(sClass, "Qualys\4.4.1.7\Install-Qualys-Cloud-Security-Agent-4.4.1.7-M-R1.vbs") ' NEW 7-12-2021
		End If
		If sPilot_FireEye = False Then
			'Call ExecScript(sClass, "FireEye\30.19.0\Install-FireEye-Endpoint-Agent-30.19.0-M-R1.vbs") ' NOT SYNCED new version in pilot (now rollback)
			Call ExecScript(sClass, "FireEye\31.28.8\Install-FireEye-Endpoint-Agent-31.28.8-M-R1.vbs") ' NEW 6-29-2020 approval to deploy to all prod
		Else ' Run new Pilot version for QA
			Call ExecScript(sClass, "FireEye\31.28.8\Install-FireEye-Endpoint-Agent-31.28.8-M-R1.vbs") ' NEW 5-20-2020
		End If
		' EMET is EOL no newer version for OS versions greater than Windows 10 CB 1703
		If CBVer < 1703 Then Call ExecScript(sClass, "EMET\5.52\Install-EMET-5.52-M-R1.vbs")
		If (s64Bit = "1" AND sPilot_Cylance = False) Then
			'Call ExecScript(sClass, "Cylance\2.1.1564.40\Install-Cylance-PROTECT-x64-2.1.1564.40-M-R1.vbs") ' Rollback optionNEW 9-30-2020
			Call ExecScript(sClass, "Cylance\2.1.1570.35\Install-Cylance-PROTECT-x64-2.1.1570.35-M-R1.vbs") ' NEW 5-18-2021
		ElseIf (s64Bit = "1" AND sPilot_Cylance = True) Then ' Run new Pilot version for QA
			'Call ExecScript(sClass, "Cylance\2.1.1564.40\Install-Cylance-PROTECT-x64-2.1.1564.40-M-R1.vbs") ' Rollback optionNEW 9-30-2020
			'Call ExecScript(sClass, "Cylance\2.1.1570.35\Install-Cylance-PROTECT-x64-2.1.1570.35-M-R1.vbs") ' Rollback optionNEW 9-30-2020
			Call ExecScript(sClass, "Cylance\2.1.1574.39\Install-Cylance-PROTECT-x64-2.1.1574.39-M-R1.vbs") ' NEW 5-18-2021
		End If
	End If
End Function

Sub ExecScript(sClass, sNSN)
	On Error Resume Next
	Dim sCMD, vCT, iStat, iErrDesc
	If UCase(sClass) = "DC" Then
		sCMD = "\\" & sDomFQDN & "\netlogon\DC\" & sNSN
	ElseIf UCase(sClass) = "SERVER" Then
		sCMD = "\\" & sDomFQDN & "\netlogon\Servers\" & sNSN
	ElseIf UCase(sClass) = "CLIENT" Then
		sCMD = "\\" & sDomFQDN & "\netlogon\Clients\" & sNSN
	Else
		WSHLog "CriticalFailure", "Execution class specified was " & sClass & " which is not 1 of the 3 coded for. Must be a typo and requires to be corrected, script exiting."
	End If
	If Not oFSO.FileExists(sCMD) Then
		If Not IsObject(DebugLog) Then Call CreateDebugLog("WriteLog")
		sTicket = "True"
		DebugLog.WriteLine(Now & "__ Script doesnt exist to execute: " & sCMD)
		WSHLog "Failure", "Script doesnt exist to execute: " & sCMD
	Else
		If IsObject(DebugLog) Then DebugLog.WriteLine(Now & "__ Executing" & sCMD)
		vCT = Now
		If IsServerCore = "True" Then
			iStat = oShell.Run("cscript.exe " & Chr(34) & sCMD & Chr(34), 1, True)
		Else
			iStat = oShell.Run("wscript.exe " & Chr(34) & sCMD & Chr(34), 1, True)
		End If
		If iStat = 0 Or iStat = 3010 Then
			If IsObject(DebugLog) Then DebugLog.WriteLine(Now & "__ Execution completed, exit code: " & iStat & ", total execution time: " & DateDiffToWords(vCT,Now))
		Else
			iErrCode = iStat
			iErrDesc = CStr(iStat) & " " & Err.Description & "."
			If Not IsObject(DebugLog) Then Call CreateDebugLog("WriteLog")
			DebugLog.WriteLine(Now & "__ Execution of " & sCMD & ", FAILED. Result code: " & iErrDesc)
			WSHLog "Failure", "Execution of " & sCMD & ", FAILED. Result code: " & iErrDesc
		End If
	End If
	iStat = Null
	On Error GoTo 0
End Sub

' Export local HOST file if altered
Function CopyLH
	On Error Resume Next
	Const ForReading = 1 : Const ForWriting = 2 : Const ForAppending = 8
	Dim Info, sClass, sExcl, sEx, LCount, sBody, oExFile, sExLine, Exclusions, oExclusions
	Dim HOSTS, oFile, sLine, Check, sLogIt, sExclusion, oHOSTS, vTimeThis, sLenghtTM, iErrDesc
	Info = "True"
	If IsServer = "True" Then
		If DC = "True" Then
			sExcl = "\\" & sDomFQDN & "\netlogon\DC\HOSTS\"
		Else
			sExcl = "\\" & sDomFQDN & "\netlogon\Servers\HOSTS\"
		End If
	Else ' Client
		sExcl = "\\" & sDomFQDN & "\netlogon\Clients\HOSTS\"
	End If

	If Not oFSO.FileExists(sExcl & "Exclusion.txt") Then
		sEx = "False"' proceed without exclusion list
		LCount = "N/A"
		sBody = "Exclusion file not found in " & sExcl & "Exclusion.txt, proceeding without exclusion list. || "
	Else
		sEx = "True"
		Set oExFile = oFSO.OpenTextFile(sExcl & "Exclusion.txt:RealDeal.txt", ForReading)', True)
		Do Until oExFile.AtEndOfStream
			LCount = LCount + 1
			sExLine = oExFile.ReadLine
			sExLine = Split(sExLine, " ")'''
'MsgBox sExLine(0)
			If LCount = 1 Then
				Exclusions = sExLine(0)'''
			Else
				Exclusions = Exclusions & "|" & sExLine(0)'''
			End If
		Loop
		oExFile.Close
		oExclusions = Split(Exclusions, "|")
	End If

	HOSTS = sSystem32 & "drivers\etc\hosts"
'	HOSTS = sSrcRoot & "hosts" 'debug test hosts file
	If Not oFSO.FileExists(HOSTS) Then
		If Not IsObject(DebugLog) Then Call CreateDebugLog("WriteLog")
		sTicket = "True"
		DebugLog.WriteLine(Now & "__ " & HOSTS & " file does not exist. This should be looked into.")
		WSHLog "Warning", HOSTS & " file does not exist. This should be looked into. | |"
	End If
	Set oFile = oFSO.OpenTextFile(HOSTS, ForReading)
	Do Until oFile.AtEndOfStream
		sLine = oFile.ReadLine
		sLine = LTrimEx(sLine)' = Trim(sLine)
		If sLine = "" Then
			'Skip empty line
		Else
			Check = Left(sLine, 1)
			If NOT Check = "#" Then
				'Check against exclusion list
				sLogIt = "True"
				If sEx = "True" Then
					For Each sExclusion In oExclusions
						If InStr(UCase(sLine), UCase(sExclusion)) Then
							sLogIt = "False"
						End If
					Next
				End If
				If sLogIt = "True" Then				
					If Info = "True" Then
						sBody = sLine & " |"
						Info = "False"
					Else
						sBody = sBody & sLine & " |"
					End If
				End If
			End If
		End If
	Loop
	oFile.Close
	Dim sCopy
	If Info <> "True" Then
		Dim sNYCSRV, sAVLSRV, sShare, sSrvShare
		sNYCSRV = "PROD-T1-BISSELL"
		sAVLSRV = "PROD-T1-HOOVER" ' sAVLSRV = "DRSTR17"
		sShare =  "HOSTS$"
		If UCASE(sDomFQDN) = "THEORCHARD.LOCAL" Then
			sSrvShare = "\\" & sNYCSRV & "." & sDomFQDN & "\" & sShare & "\" 'was nyfs01
			sCopy = "Yes"
		ElseIf UCASE(sDomFQDN) = "AVL.THEORCHARD" Then
			sSrvShare = "\\" & sAVLSRV & "." & sDomFQDN & "\" & sShare & "\" 'was DRSTR17
			sCopy = "Yes"
		Else
			If Not IsObject(DebugLog) Then Call CreateDebugLog("WriteLog")
			sTicket = "True"
			DebugLog.WriteLine(Now & "__ Will not attempt to copy HOSTS file as we detected an unknown FQDN Domain name: " & sDomFQDN & ". |" & sBody)
			WSHLog "Failure", "Will not attempt to copy HOSTS file as we detected an unknown FQDN Domain name: " & sDomFQDN & ". |" & sBody
			sCopy = "No"
			Exit Function 
		End If

		If InStr(UCase(sDN), "CONTROLLERS") Then
			sSrvShare = sSrvShare & "DC\"
		ElseIf InStr(UCase(sDN), "OU=T0") Then
			sSrvShare = sSrvShare & "T0\"
		ElseIf InStr(UCase(sDN), "OU=T1") Then
			sSrvShare = sSrvShare & "T1\"
		ElseIf InStr(UCase(sDN), "OU=T2") Then
			sSrvShare = sSrvShare & "T1\"
		ElseIf InStr(UCase(sDN), "OU=CLIENT SERVICES") Then
			sSrvShare = sSrvShare & "T3\"
		Else
			If Not IsObject(DebugLog) Then Call CreateDebugLog("WriteLog")
			DebugLog.WriteLine(Now & "__ Will not attempt to move data, DN " & sDN & " is not accounted for in Domain: " & sDomFQDN & ".")
			WSHLog "CriticalFailure", "Will not attempt to move data, DN " & sDN & " is not accounted for in Domain: " & sDomFQDN & "."
			Exit Function
		End If

		If sCopy = "Yes" Then
			Set oHOSTS = oFSO.GetFile(HOSTS)
			vTimeThis = Now
			oFSO.CopyFile HOSTS, sSrvShare & sCN & ".txt", True
			If Err.Number = 0 Then
				sLenghtTM = DateDiffToWords(vTimeThis,Now)
				If Not IsObject(DebugLog) Then Call CreateDebugLog("WriteLog")
				sTicket = "True"
				DebugLog.WriteLine(Now & "__ Found non-default entry in HOSTS file: |" & sBody & " |Count of exclusions ran against: " & LCount & " ||Copied out to " & sSrvShare & sCN & ".txt. |Last modified: " & oHOSTS.DateLastModified & ".||" )
				Email sScript & " - " & "found host entry.", "Found non-default entry in HOSTS file: |" & sBody & " |Count of exclusions ran against: " & LCount & " ||Copied out to " & sSrvShare & sCN & ".txt. |Last modified: " & oHOSTS.DateLastModified & ".||" & sMsg
			Else
				iErrCode = Err.Number
				iErrDesc = CStr(Err.Number) & " " & Err.Description & "."
				If Not IsObject(DebugLog) Then Call CreateDebugLog("WriteLog")
				sTicket = "True"
				DebugLog.WriteLine(Now & "__ Failed to copy " & HOSTS & " to " & sSrvShare & ", Error # " & iErrDesc & " |Found file Last modified: " & oHOSTS.DateLastModified & ". |Found non-default entry in HOSTS file: ||" & sBody & " ||Count of exclusions ran against: " & LCount)
				WSHLog "Failure", "Failed to copy " & HOSTS & " to " & sSrvShare & ", Error # " & iErrDesc & " |Found file Last modified: " & oHOSTS.DateLastModified & ". |Found non-default entry in HOSTS file: ||" & sBody & " ||Count of exclusions ran against: " & LCount
			End If
		End If
	End If
	On Error GoTo 0
End Function

' Trim spaces, tabs function
Function LTrimEx(sLine)
   Dim re
   Set re = New RegExp
   re.Pattern = "^\s*"
   re.Multiline = False
   LTrimEx = re.Replace(sLine, "")
End Function

' Copy blat file to system to ensure email alerts are available
Function CopyCMTrace
	On Error Resume Next
	Dim fn, sCMTrace, vTimeThis, sLenghtTM, sDesc, iErrDesc : fn = "CMTrace.exe" : sCMTrace = sSystem32 & fn
	If Not oFSO.FileExists(sCMTrace) Then
		If oFSO.FileExists(sLib & fn) Then
			vTimeThis = Now
			oFSO.CopyFile sLib & fn, sSystem32 & fn, True
			If Err.Number = 0 Then
				sLenghtTM = DateDiffToWords(vTimeThis,Now)
				sDesc = "Copied " & fn & " successfully. Took: " & sLenghtTM & "."
				If Not IsObject(DebugLog) Then Call CreateDebugLog("WriteLog")
				DebugLog.WriteLine(Now & "__ " & sDesc)
				WSHLog "Success", sDesc
			Else
				iErrCode = Err.Number
				iErrDesc = CStr(Err.Number) & " " & Err.Description & "."
				oProcessEnv("SEE_MASK_NOZONECHECKS") = 1
				sDesc = "Could not copy " & fn & " from " & sLib & " to: " & sSystem32 & ", Error # " & iErrDesc & "."
				If Not IsObject(DebugLog) Then Call CreateDebugLog("WriteLog")
				DebugLog.WriteLine(Now & "__ " & sDesc)
				WSHLog "Failure", sDesc
				oProcessEnv.Remove("SEE_MASK_NOZONECHECKS")
			End If
		Else
			sDesc = fn & " not found, not in: " & sSystem32 & ", nor in: " & sLib & "."
			If Not IsObject(DebugLog) Then Call CreateDebugLog("WriteLog")
			DebugLog.WriteLine(Now & "__ " & sDesc)
			WSHLog "Failure", sDesc
		End If
	End If
	On Error GoTo 0
End Function

'--- Script Subs/Functions -------------------------------------------------------------------------------------------

' Get AD Site info
Function GetADSite
	On Error Resume Next
	Dim sNetlogon, sADSite
	sNetlogon = "HKLM\System\CurrentControlSet\Services\Netlogon\Parameters"
	'ADSite = GetRegData(sNetlogon & "\SiteName", "{default}") ' LEGACY may need will see what emails come back to determine
	sADSite = GetRegData(sNetlogon & "\DynamicSiteName", "{default}")
	If sADSite = "{default}" Then
		ADSite = "Could not read from registry."
	ElseIf sADSite = "" Then
		ADSite = "No value found in registry."
	Else
		ADSite = sADSite
	End If	
	sMsg = sMsg & "|AD Site: " & ADSite
	On Error GoTo 0
End Function

' Gets Manufacturer/Model info on the device
Function GetCMPDomain
	On Error Resume Next
	If sWMIFailed = "Failed" Then
		sMsg = sMsg & "|Domain or Workgroup: (WMI not available)." ' Do not remove this last & "." otherwise it wraps
	Else
		Dim DeviceInfo, oDomain
		Set DeviceInfo = oWMI.ExecQuery("SELECT Domain,DomainRole,PartOfDomain FROM Win32_ComputerSystem") ' Must be * becuase W2K does not have PartOfDomain Property, but you cannot have it fail connecting to the Win32_ComputerSystem Class
		If Err.Number = 0 Then
			For Each oDomain In DeviceInfo 
			    If NOT InStr(UCase(ProductName), "2000") > 0 Then
				    If oDomain.PartOfDomain = "True" Then 
						CMPDomain = "Computer Domain: " & oDomain.Domain
				    Else 
						CMPDomain = "Workgroup: " & oDomain.Domain
				    End If 
				Else
					CMPDomain = "Domain or Workgroup: " & oDomain.Domain
				End If
				If oDomain.DomainRole = 4 Or oDomain.DomainRole = 5 Then DC = "True"
			Next
'		Else
'			WSHLog "Failure", "Critical issue, could not connect to WMI, cimv2:Win32_ComputerSystem to obtain Manufacturer/Model information."
		End If
		sMsg = sMsg & " |" & CMPDomain & "." ' Do not remove this last & "." otherwise it wraps
		Set DeviceInfo = Nothing
	End If
	On Error GoTo 0
End Function

' Gets Manufacturer/Model info on the device
Function GetDeviceInfo
	On Error Resume Next
	If sWMIFailed = "Failed" Then
		sMsg = sMsg & "|Manufacturer: (WMI not available)  Model: (WMI not available)." ' Do not remove this last & "." otherwise it wraps
	Else
		Dim DeviceInfo, oField, count, sManuf, CheckNull, sModel
		Set DeviceInfo = oWMI.ExecQuery("SELECT Manufacturer, Model FROM Win32_ComputerSystem")
		If Err.Number = 0 Then
			For Each oField in DeviceInfo
			    sManuf = oField.Manufacturer
			    CheckNull = Right(sManuf, 1)
			    Do
					sManuf = Left(sManuf, Len(sManuf)- 1)
				    count = Len(sManuf)
					CheckNull = Right(sManuf, 1)
					If CheckNull <> " " Then CheckNull = True
			    Loop Until CheckNull = True
			    sManuf = Left(oField.Manufacturer, Len(sManuf)+1)
			    CheckNull = False
			    sModel = oField.Model
			    CheckNull = Right(sModel, 1)
			    Do
					sModel = Left(sModel, Len(sModel)- 1)
				    count = Len(sModel)
					CheckNull = Right(sModel, 1)
					If CheckNull <> " " Then CheckNull = True
			    Loop Until CheckNull = True
			    sModel = Left(oField.Model, Len(sModel)+1)
			Next
'		Else
'			WSHLog "Failure", "Critical issue, could not connect to WMI, cimv2:Win32_ComputerSystem to obtain Manufacturer/Model information."
		End If
		sMsg = sMsg & "|Manufacturer: " & sManuf & "  Model: " & sModel & "." ' Do not remove this last & "." otherwise it wraps
		Set DeviceInfo = Nothing
	End If
	On Error GoTo 0
End Function

' Get Network Interface
Function GetNetworkInterface
	On Error Resume Next
	If sWMIFailed = "Failed" Then
		sMsg = sMsg & "|Ethernet Adapter: (WMI not available) |IP address: (WMI not available) |Subnet Mask: (WMI not available)"
	Else
		Dim Adapters, Adapter, i, period, prevperiod, addressbyte, addressbytes(4)
		Dim subnetmaskbyte, subnetmaskbytes(4)
		Set Adapters = oWMI.ExecQuery("SELECT DefaultIPGateway, Description, IPAddress, IPSubnet FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled=TRUE")
		If Err.Number = 0 Then
			For Each Adapter In Adapters
				If Not IsNull(Adapter.DefaultIPGateway) Then
					If Not IsNull(Adapter.IPAddress) Then
						description = Adapter.Description
						address = Adapter.IPAddress(0)
						subnet = Adapter.IPSubnet(0)
						subnetmask = Adapter.IPSubnet(0)
						i = 0
						period = 1
						While period <> Len(address) + 2
							prevperiod = period
							period = InStr(period + 1, address, ".") + 1
							If period = 1 Then period = Len(address) + 2
							addressbyte = Mid(address, prevperiod, period-prevperiod - 1)
							addressbytes(i) = addressbyte
							i = i + 1
						Wend
						i = 0
						period = 1
						While period <> Len(subnet) + 2
							prevperiod = period
							period = Instr(period + 1, subnet, ".") + 1
							If period = 1 Then period = Len(subnet) + 2
							subnetmaskbyte = Mid(subnet, prevperiod, period-prevperiod - 1)
							subnetmaskbytes(i) = subnetmaskbyte
							i = i + 1
						Wend
						subnet = ""
						For i = 0 to 3
							subnet = subnet & (addressbytes(i) AND subnetmaskbytes(i)) & "."
						Next
						subnet = Left(subnet, Len(subnet)-1)
					End If
				End If
			Next
'		Else
'			WSHLog "Failure", "Critical issue, could not connect to WMI, cimv2:Win32_NetworkAdapterConfiguration to obtain Network Adapter Configuration."
		End If
		sMsg = sMsg & "|Ethernet Adapter: " & description & ".|IP address: " & address & "|Subnet Mask: " & subnetmask ' do not remove the dot in ".|IP address" otherwise it wraps
		Set Adapters = Nothing
	End If
	On Error GoTo 0
End Function

' Get Time Zone description
Function GetTZ
	On Error Resume Next
	Dim sTZ, sSTN
	If InStr(UCase(ProductName), "XP") Or InStr(UCase(ProductName), "2000") Or InStr(UCase(ProductName), "2003") Then
		sTZ = "HKLM\SYSTEM\CurrentControlSet\Control\TimeZoneInformation\StandardName"
'	ElseIf InStr(UCase(ProductName), "VISTA") Or InStr(UCase(ProductName), "7") Or InStr(UCase(ProductName), "2008") Then
'		sTZ = "HKLM\SYSTEM\CurrentControlSet\Control\TimeZoneInformation\TimeZoneKeyName"
	Else
'		TZ = "TZ function does not account for this OS"
		sTZ = "HKLM\SYSTEM\CurrentControlSet\Control\TimeZoneInformation\TimeZoneKeyName"
	End If
	If InStr(sTZ, "HKLM") Then
		sSTN = GetRegData(sTZ, "{default}")
		If sSTN = "{default}" Then
			TZ = "Could not read from registry."
		ElseIf sSTN = "" Then
			TZ = "No value found in registry."
		Else
			TZ = sSTN
		End If
	End If
	sMsg = sMsg & "|Time Zone: " & TZ & "." ' Do not remove this last & "." otherwise it wraps (do too some times zones ex. Malay Peninsula Standard Time)
	On Error GoTo 0
End Function

' Get OS Language we are dealing With
Function GetOSLocale
	On Error Resume Next
	If sWMIFailed = "Failed" Then
		sMsg = sMsg & "|System boot time: (WMI not available) "
		sMsg = sMsg & "|Locale: (WMI not available) "
	Else
		Dim OpSysSet, OpSys, dtmBootup, dtmLastBootupTime, dtmSystemUptime, sKeyPath, CTL, LocaleID
		Set OpSysSet = oWMI.ExecQuery("SELECT LastBootUpTime, OSLanguage FROM Win32_OperatingSystem WHERE Primary = True")
		If Err.Number = 0 Then
			For Each OpSys in OpSysSet
				dtmBootup = OpSys.LastBootUpTime 
				dtmLastBootupTime = WMIDateStringToDate(dtmBootup) 
				dtmSystemUptime = DateDiff("d", dtmLastBootupTime, Now)
				LBT = dtmLastBootupTime & " (" & dtmSystemUptime & " days)"
				iOSLang = OpSys.OSLanguage
			    sOSLangHex = Right("000" & Hex(iOSLang), 4)
			Next 
			sKeyPath = "HKLM\SOFTWARE\Classes\MIME\Database\Rfc1766\" & sOSLangHex
			sOSLanguage = GetRegData(sKeyPath, "{default}")
			CTL = Split(sOSLanguage, ";")'Vista and up
			If Left(CTL(1), 1) = "@" Then
				LocaleID = TranslateOSLocale(iOSLang)
				sOSLanguage = CTL(0) & ";" & LocaleID
			End If
		Else
'			WSHLog "Failure", "Critical issue, could not connect to WMI, cimv2:Win32_OperatingSystem to obtain OS Language."
		End If
		sMsg = sMsg & "|System boot time: " & LBT & ". |Locale: " & iOSLang & ", " & sOSLanguage & "." ' Do not remove this last & "." otherwise it wraps
		Set OpSysSet = Nothing
	End If
	On Error GoTo 0
End Function

' Function to convert UNC time to readable format 
Function WMIDateStringToDate(dtmBootup) 
	WMIDateStringToDate = CDate(Mid(dtmBootup, 5, 2) & "/" & Mid(dtmBootup, 7, 2) & "/" & Left(dtmBootup, 4) _ 
	& " " & Mid (dtmBootup, 9, 2) & ":" & Mid(dtmBootup, 11, 2) & ":" & Mid(dtmBootup, 13, 2))
End Function 

' Converts Locale ID to friendly name
Function TranslateOSLocale(LocaleID)
	Select Case LocaleID
		Case ("1025") : TranslateOSLocale = "Arabic"
		Case ("1046") : TranslateOSLocale = "Brazilian"
		Case ("2052") : TranslateOSLocale = "Chinese (Simplified)"
		Case ("1028") : TranslateOSLocale = "Chinese (Traditional)"
		Case ("3076") : TranslateOSLocale = "Chinese (Hong Kong)"
		Case ("1029") : TranslateOSLocale = "Czech"
		Case ("1030") : TranslateOSLocale = "Danish"
		Case ("1043") : TranslateOSLocale = "Dutch"
		Case ("1033") : TranslateOSLocale = "English"
		Case ("1035") : TranslateOSLocale = "Finnish"
		Case ("1036") : TranslateOSLocale = "French"
		Case ("1031") : TranslateOSLocale = "German"
		Case ("1032") : TranslateOSLocale = "Greek"
		Case ("1037") : TranslateOSLocale = "Hebrew"
		Case ("1038") : TranslateOSLocale = "Hungarian"
		Case ("1040") : TranslateOSLocale = "Italian"
		Case ("1041") : TranslateOSLocale = "Japanese"
		Case ("1042") : TranslateOSLocale = "Korean"
		Case ("1044") : TranslateOSLocale = "Norwegian"
		Case ("1045") : TranslateOSLocale = "Polish"
		Case ("2070") : TranslateOSLocale = "Portuguese"
		Case ("1049") : TranslateOSLocale = "Russian"
		Case ("3082") : TranslateOSLocale = "Spanish"
		Case ("1053") : TranslateOSLocale = "Swedish"
		Case ("1055") : TranslateOSLocale = "Turkish"
		Case Else : TranslateOSLocale = sOSLanguage
	End Select
End Function

' Basic check on the current health state of WMI (This version does not exit script if WMI found to be unhealthy)
Function WMIHealthCheck
	On Error Resume Next
	Dim sWinMgmt, WinMgmt, iAuto, sState, oWMIRoot, oCIMv2, oWin32Service
	sWinMgmt = "HKLM\SYSTEM\CurrentControlSet\Services\WinMgmt\Start"
	WinMgmt = GetRegData(sWinMgmt, "{default}")
	If WinMgmt = "{default}" Then
		sWMIMsgBody2 = "Check -WMIHealthCheck- function failed to read reg Key: " & sWinMgmt
		sWMIFailed = "Failed"
		Exit Function
	ElseIf Not WinMgmt = "2" Then
		If WinMgmt = "3" Then sState = "Manual"
		If WinMgmt = "4" Then sState = "Disabled"
		'If WMI Service StartMode is set to Disabled (#4) by someone/something, the below command will fix (No WMI to Check WMI, serious problem), cannot enable via registry, insufficent.
		iAuto = oShell.Run(sSystem32 & "sc.exe config winmgmt start= auto", 2, True)
		If iAuto = "" Then
			If Not oFSO.FileExists(sSystem32 & "sc.exe") Then
				sWMIMsgBody2 = "Found WMI Service startup type set to " & sState & ", tried setting it to Automatic, failed. SC.exe missing from system, could not start WMI."
				sWMIFailed = "Failed"
				Exit Function
			End If
		Else
			sCoreWMI = "Found WMI Service startup type set to " & sState & ", changed it to Automatic startup type."
'			sWMIMsgBody1 = "Found WMI Service startup type set to " & sState & ", changed it to Automatic startup type."
'			sWMIWarning = "Warning"
		End If
	End If
	sWMIMsgBody2 = Null
	Set oWMIRoot = GetObject("winmgmts:\\.\root\default")
	If Err.Number <> 0 Then
		sWMIMsgBody2 = "Unable to connect to WMI namespace \root\default. "
		sWMIFailed = "Failed"
	End If
	Err.Clear
	Set oCIMv2 = GetObject("winmgmts:\\.\root\cimv2")
	If Err.Number <> 0 Then
		If IsNull(sWMIMsgBody2) Then
			sWMIMsgBody2 = "Unable to connect to WMI namespace \root\cimv2. "
		Else
			sWMIMsgBody2 = sWMIMsgBody2 & "|Unable to connect to WMI namespace \root\cimv2. "
		End If
		sWMIFailed = "Failed"
	End If
	Err.Clear
	Set oWin32Service = GetObject("winmgmts:\\.\root\cimv2:Win32_Service")
	If Err.Number <> 0 Then 
		If IsNull(sWMIMsgBody2) Then
			sWMIMsgBody2 = "Unable to connect to WMI namespace \root\cimv2:Win32_Service. "
		Else
			sWMIMsgBody2 = sWMIMsgBody2 & "|Unable to connect to WMI namespace \root\cimv2:Win32_Service. "
		End If
		sWMIFailed = "Failed"
	End If
	Err.Clear
	Set oWMIRoot = Nothing
	Set oCIMv2 = Nothing
	Set oWin32Service = Nothing
	On Error GoTo 0
End Function

' Get IE info
Function GetIEInfo
	On Error Resume Next
	Dim sIE, IEver
	sIE = "HKLM\SOFTWARE\Microsoft\Internet Explorer\svcVersion"
	IEver = GetRegData(sIE, "{default}")
	If IEver = "{default}" Then
		sIE = "HKLM\SOFTWARE\Microsoft\Internet Explorer\Version"
		IEver = GetRegData(sIE, "{default}")
		If IEver = "{default}" Then
			sIEver = "Could not read from registry."
		ElseIf IEver = "" Then
			sIEver = "No value found in registry."
		Else
			sIEver = IEver
		End If
	ElseIf IEver = "" Then
		sIEver = "No value found in registry."
	Else
		sIEver = IEver
	End If
	sMsg = sMsg & "|IE Version: " & sIEver
	On Error GoTo 0
End Function

' Get a file's version (requested)
Function GetFileVer(File)
	On Error Resume Next
	If oFSO.FileExists(File) Then
		sFileVer = oFSO.GetFileVersion(File)
		If sFileVer = "" Or IsNull(sFileVer) Then
			sFileVer = "No version info."
		End If
	Else
		sFileVer = "File not found."
	End If
	On Error GoTo 0
End Function

' Get OS Install Date
Function GetInstallDate
	On Error Resume Next
	Dim sNT, sInstallDate, InstallDate
	sNT = "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\InstallDate"
	sInstallDate = GetRegData(sNT, "{default}")
	If sInstallDate = "{default}" Then
		InstallDate = "Could not read from registry."
	ElseIf sInstallDate = "" Then
		InstallDate = "No value found in registry."
	Else
		InstallDate = DateAdd("s", sInstallDate, DateSerial(1970, 1, 1))
		InstallDate = DateAdd("h", -4, InstallDate)
	End If	
	sMsg = sMsg & "|OS Install Date: " & InstallDate & " (EST). "
	On Error GoTo 0
End Function

' Get what OS, CSD version are we working with
Function GetOSInfo
	On Error Resume Next
	Dim sPN, sId, sCSDVer
	sPN = "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProductName"
	ProductName = GetRegData(sPN, "{default}")
	If ProductName = "{default}" Then
		iErrCode = "53"
		DebugLog.WriteLine(Now & "__ GetOSInfo function failed to read reg Key: " & sPN)
		WSHLog "CriticalFailure", "GetOSInfo function failed to read reg Key: " & sPN
	ElseIf ProductName = "" Then
		iErrCode = "53"
		DebugLog.WriteLine(Now & "__ GetOSInfo- function found a Null value in reg Value: " & sPN)
		WSHLog "CriticalFailure", "GetOSInfo- function found a Null value in reg Value: " & sPN
	End If
	If InStr(UCase(ProductName), "SERVER") Then
		IsServer = "True"	
		If Not oFSO.FileExists(oProcessEnv("SYSTEMROOT") & "\explorer.exe") Then
			IsServerCore = "True"
		End If
	ElseIf InStr(UCase(ProductName), "WINDOWS 10") Then
		sId = "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ReleaseId"
		CBVer = GetRegData(sId, "{default}")
		If CBVer = "{default}" Then
			iErrCode = "53"
			DebugLog.WriteLine(Now & "__ GetOSInfo function on Windows 10 failed to read reg Key: " & sId)
			WSHLog "CriticalFailure", "GetOSInfo function on Windows 10 failed to read reg Key: " & sId
		ElseIf ProductName = "" Then
			iErrCode = "53"
			DebugLog.WriteLine(Now & "__ GetOSInfo- function on Windows 10 found a Null value in reg Value: " & sId)
			WSHLog "CriticalFailure", "GetOSInfo- function on Windows 10 found a Null value in reg Value: " & sId
		End If
	End If
	sCSDVer = "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\CSDVersion"
	CSDver = GetRegData(sCSDVer, "{default}")
	If CSDver = "{default}" Then CSDver = "RTM"
	s64Bit = "0"
	If oFSO.FileExists(oProcessEnv("SYSTEMROOT") & "\SysWOW64\wscript.exe") Then
		s64Bit = "1"
	End If
	' Check if corp build
	sPBV = sEngKey & "Build\BuildVersion"
	sPTV = sEngKey & "Build\DeployTSVersion"
	PBV = GetRegData(sPBV, "{default}")
	PTV = GetRegData(sPTV, "{default}")
	If PBV = "{default}" OR PBV = "" Or IsEmpty(PBV) Or IsNull(PBV) Then PBV = "Non-Corp"
	If PTV = "{default}" Or PTV = "" Or IsEmpty(PTV) Or IsNull(PTV) Then PTV = "No value"
	If InStr(UCase(ProductName), "10") Then
		sMsg = sMsg & "|Hostname: " & sCN & "|OS: " & ProductName & ", CB: " & CBVer & "|BuildVer: " & PBV & "|DeployTSVer: " & PTV & "." ' Do not remove this last & "." otherwise it wraps
	Else
		sMsg = sMsg & "|Hostname: " & sCN & "|OS: " & ProductName & ", " & CSDver & "|BuildVer: " & PBV & "|DeployTSVer: " & PTV & "." ' Do not remove this last & "." otherwise it wraps
	End If
	On Error GoTo 0
End Function

' Read Registry Key/Values Function
Function GetRegData(sRegKey, vDefault)
	On Error Resume Next
	Dim vReturn
	vReturn = oShell.RegRead(sRegKey)
	If Err.Number <> 0 Then
		GetRegData = vDefault
		Err.Clear
	Else
		GetRegData = vReturn
	End If
	On Error GoTo 0
End Function

' Get ID of who is running the script, as well as who is logged on (if anyone) Function
Function GetWhoIsRunningScript
	On Error Resume Next
	If sWMIFailed = "Failed" Then
		sMsg = sMsg & "|Script was executed utilizing account: (WMI not available) "
		sMsg = sMsg & "|Following account(s) are logged on during execution of script: (WMI not available) "
	Else
		Dim cProcessList, oProcess, cProperties, sNameOfUser, sUserDomain
		Set cProcessList = oWMI.ExecQuery("SELECT CommandLine,Name FROM Win32_Process WHERE " & "Name = 'cscript.exe' or Name = 'wscript.exe'")
		For Each oProcess in cProcessList
			If InStr(oProcess.CommandLine, Wscript.ScriptFullName) Then
				cProperties = oProcess.GetOwner(sNameOfUser,sUserDomain)
			End If
		Next
		If IsObject(DebugLog) Then DebugLog.WriteLine(Now & "__ Script was executed utilizing account: " & sUserDomain & "\" & sNameOfUser)
		sMsg = sMsg & "|Script was executed utilizing account: " & sUserDomain & "\" & sNameOfUser & "."	
	
		Dim cCS, oCS, LoggedInUser
		Set cCS = oWMI.ExecQuery("SELECT UserName FROM Win32_ComputerSystem")
		LoggedInUser = "NOONE"
		For Each oCS in cCS
			LoggedInUser = oCS.UserName
		Next
		If IsNull(LoggedInUser) Then
			If IsObject(DebugLog) Then DebugLog.WriteLine(Now & "__ Script detected the following account(s) are logged on during start of installation: No Logon detected")
			sMsg = sMsg & "|Following account(s) are logged on during execution of script: No Logon detected"
		Else
			If IsObject(DebugLog) Then DebugLog.WriteLine(Now & "__ Script detected the following account(s) are logged on during start of installation: " & LoggedInUser)
			sMsg = sMsg & "|Following account(s) are logged on during execution of script: " & LoggedInUser
		End If
	End If
	On Error GoTo 0
End Function

' Creates Corporate Engineering debug log (or append to existing log if run before) Function
Function CreateDebugLog(sCondition)
	If sCondition = "WriteLog" Then
		Call CreateDebugLogNow
	Else
		If (sCoreBlat <> "" Or sCoreBlat2 <> "" Or sCoreWMI <> "" Or sCoreInfo <> "" Or sCoreInfo2 <> "" Or sCoreInfo3 <> "") Then
			Call CreateDebugLogNow
		End If
	End If
End Function

Sub CreateDebugLogNow
	On Error Resume Next
	Const ForReading = 1 : Const ForWriting = 2 : Const ForAppending = 8
	Dim iErrDesc
	If NOT oFSO.FileExists(sDebugLog) Then
		Set DebugLog = oFSO.OpenTextFile(sDebugLog, ForWriting, True)
		If Err.Number <> 0 Then
			iErrCode = Err.Number
			iErrDesc = CStr(Err.Number) & " " & Err.Description & "."
			Call GetWhoIsRunningScript
			WSHLog "CriticalFailure", "Attempt to create Debuglog: " &  sDebugLog & ", failed. Error code: " & iErrDesc
		End If
	Else ' Append to existing log
		Set DebugLog = oFSO.OpenTextFile(sDebugLog, ForAppending, True)
		If Err.Number <> 0 Then
			iErrCode = Err.Number
			iErrDesc = CStr(Err.Number) & " " & Err.Description & "."
			Call GetWhoIsRunningScript
			WSHLog "CriticalFailure", "Attempt to append to Debuglog: " &  sDebugLog & ", failed. Error code: " & iErrDesc
		Else
			DebugLog.WriteLine(" ")
		End If
	End If
	WSHLog "Information", "Log tracing commencing for " & DEPLOYNAME & SIDE & RELEASE
	DebugLog.WriteLine(Now & "__ Log tracing commencing for " & DEPLOYNAME & SIDE & RELEASE & " on " & oProcessEnv("COMPUTERNAME"))
	DebugLog.WriteLine(Now & "__ Script/Path utilized: " & Wscript.ScriptFullName)
	If sCoreBlat <> "" Then	DebugLog.WriteLine(sCoreBlat)
	If sCoreBlat2 <> "" Then DebugLog.WriteLine(sCoreBlat2)
	If sCoreWMI <> "" Then DebugLog.WriteLine(sCoreWMI)
	If sCoreInfo <> "" Then DebugLog.WriteLine(sCoreInfo)
	If sCoreInfo2 <> "" Then DebugLog.WriteLine(sCoreInfo2)
	If sCoreInfo3 <> "" Then DebugLog.WriteLine(sCoreInfo3)
	Call GetWhoIsRunningScript
	On Error GoTo 0
End Sub

' Creates Corporate Engineering Logs directory(s) for script, package installation, and custom logging if they do not exist
Function CreateLogDirs
	If Not oFSO.FolderExists(sLogDir) Then Call CreateLogDir(sLogDir)
	If Not oFSO.FolderExists(sScriptsDir) Then Call CreateLogDir(sScriptsDir)
	If Not oFSO.FolderExists(sEmailDir) Then Call CreateLogDir(sEmailDir)
End Function

' Create Log directory's requested 
Sub CreateLogDir(sDir)
	On Error Resume Next
	Dim iErrDesc
	oFSO.CreateFolder(sDir)
	If Err.Number = 0 Then
		WSHLog "Success", sDir & " directory Created."
		If sDir = sLogDir Then sCoreInfo = Now & "__ " & sLogDir & " directory Created."
		If sDir = sScriptsDir Then sCoreInfo2 = Now & "__ " & sScriptsDir & " directory Created."
		If sDir = sEmailDir Then sCoreInfo3 = Now & "__ " & sEmailDir & " directory Created."
	Else
		iErrCode = Err.Number
		iErrDesc = CStr(Err.Number) & " " & Err.Description & "."
		Call GetWhoIsRunningScript
		oProcessEnv("SEE_MASK_NOZONECHECKS") = 1
		WSHLog "CriticalFailure", "Could not create " & sDir & " directory, Error # " & iErrDesc
	End If
	On Error GoTo 0
End Sub

' Copy blat file to system to ensure email alerts are available
Function CopyBlat
	On Error Resume Next
	Dim fn, vTimeThis, sLenghtTM, iErrDesc : fn = "blat.exe"
	If Not oFSO.FileExists(sBlat) Then
		If oFSO.FileExists(sLib & fn) Then
			vTimeThis = Now
			oFSO.CopyFile sLib & fn, sSystem32 & fn, True
			If Err.Number = 0 Then
				sLenghtTM = DateDiffToWords(vTimeThis,Now)
				WSHLog "Success", "Copied " & fn & " successfully. Took: " & sLenghtTM & "."
				sCoreBlat2 = Now & "__ Copied " & fn & " successfully. Took: " & sLenghtTM & "."
				If sDebugBlat = "True" Then Email "Copied " & fn & " successfully", "Copied " & fn & " successfully. Took: " & sLenghtTM & "."
			Else
				iErrCode = Err.Number
				iErrDesc = CStr(Err.Number) & " " & Err.Description & "."
				sBlat = sLib & "blat.exe"
				oProcessEnv("SEE_MASK_NOZONECHECKS") = 1
				WSHLog "Failure", "Could not copy " & fn & " from " & sLib & " to: " & sSystem32 & ", Error # " & iErrDesc & ". Will continue with network copy... ||"
				oProcessEnv.Remove("SEE_MASK_NOZONECHECKS")
			End If
		Else
			sCoreBlat = Now & "__ Blat not found, not in: " & sSystem32 & ", nor in: " & sLib & " no email status will be available."
			WSHLog "Failure", "Blat not found, not in: " & sSystem32 & ", nor in: " & sLib & " no email status will be available."
		End If
	End If
	On Error GoTo 0
End Function

' Get AD domain Name
Function GetDomainName
	On Error Resume Next
	Dim Info
	Set Info = CreateObject("AdSystemInfo")
	If Err.Number <> 0 Then
		iErrCode = Err.Number	
		Call CreateLogDirs
		If Not IsObject(DebugLog) Then Call CreateDebugLog("WriteLog")
		WSHLog "CriticalFailure", "Failed to create object AdSystemInfo, error: " & iErrCode
	Else
		sDomFQDN = Info.DomainDNSName
		sDN = Info.ComputerName
	End If
	On Error GoTo 0
End Function

' WSH Application Event Log, logging Function
Function WSHLog(EventType, Desc)
	On Error Resume Next
	If EventType = "Information" Then oShell.LogEvent 4, sScript & Chr(13) & "------------------------------------------------------" & Chr(13) & Desc
	If EventType = "Success" Then oShell.LogEvent 0, sScript & Chr(13) & "------------------------------------------------------" & Chr(13) & Desc
	If EventType = "Warning" Then
		oShell.LogEvent 2, sScript & Chr(13) & "------------------------------------------------------" & Chr(13) & Desc
		WScript.Sleep 500 ': sTicket = "True"
		If sCoreBlat = "" Then Email EventType, Desc & "| |" & sMsg
	End If
	If EventType = "Failure" Then
		oShell.LogEvent 1, sScript & Chr(13) & "------------------------------------------------------" & Chr(13) & Desc
		WScript.Sleep 500
		If sCoreBlat = "" Then Email EventType, Desc & "| |" & sMsg
	End If
	If EventType = "CriticalFailure" Then
		oShell.LogEvent 1, sScript & Chr(13) &	"------------------------------------------------------" & Chr(13) & Desc & " Script exiting..."
		WScript.Sleep 500
		If Not(IsNull(iErrCode) Or IsEmpty(iErrCode)) Then
			If IsObject(DebugLog) Then DebugLog.WriteLine(Now & "__ Critical failure, exiting... Wrapper exit code : " & iErrCode)
			sPilot = "True" : sTicket = "True" ' Force attachment of debuglog since we have a critical failure
			Call Cleanup(sScript & " - " & EventType, Desc & "| |" & sMsg)
			WScript.Quit(iErrCode)
		Else
			If IsObject(DebugLog) Then DebugLog.WriteLine(Now & "__ Critical failure exiting... Wrapper exit code  : " & Err.Number)
			sPilot = "True" : sTicket = "True" ' Force attachment of debuglog since we have a critical failure
			Call Cleanup(sScript & " - " & EventType, Desc & "| |" & sMsg)
			WScript.Quit
		End If
	End If
	On Error GoTo 0
End Function

' EMail Results Function v2
Function Email(Subject, Body)
	On Error Resume Next
	Dim sTmpFile, sP1, sP2, iMail
	If Not(IsNull(sMailbox2) Or IsEmpty(sMailbox2)) Then
		sP1 = sMailbox1 & "," & sMailbox2
	Else
		sP1 = sMailbox1
	End If
	If Not(IsNull(sMailbox3) Or IsEmpty(sMailbox3)) Then sP1 = sP1 & "," & sMailbox3

	sTmpFile = sEmailDir & "\" & oFSO.GetTempName
	oFSO.CreateTextFile sTmpFile
	If Err.Number <> 0 Then
		sP2 = "-log " & Chr(34) & oProcessEnv("TEMP") & "\"
	Else
		oFSO.DeleteFile sTmpFile
		sP2 = "-log " & Chr(34) & sEmailDir & "\"
	End If

	Call Stamp
	If sTicket = "True" Then
		If Not(IsNull(sSD) Or IsEmpty(sSD)) Then sP1 =  sSD & "," & sP1
		If IsObject(DebugLog) Then
			iMail = oShell.Run(sBlat & " -body " & Chr(34) &_
			Body & Chr(34) & " -to " & sP1 & " -subject " & Chr(34) & Subject &_
			Chr(34) & " -server " & sRelayHost & " -f " & sFrom & sFQDN & " -attacht " & Chr(34) & sDebugLog & Chr(34) & " -debug " & sP2 & sScript & "_" & altDate & "-" & altTime & ".log" & Chr(34) & " -try " & sTry, 2, True)
		Else
			iMail = oShell.Run(sBlat & " -body " & Chr(34) &_
			Body & Chr(34) & " -to " & sP1 & " -subject " & Chr(34) & Subject &_
			Chr(34) & " -server " & sRelayHost & " -f " & sFrom & sFQDN & " -debug " & sP2 & sScript & "_" & altDate & "-" & altTime & ".log" & Chr(34) & " -try " & sTry, 2, True)
		End If
	ElseIf (sPilot = "True") And (IsObject(DebugLog)) Then
		iMail = oShell.Run(sBlat & " -body " & Chr(34) &_
		Body & Chr(34) & " -to " & sP1 & " -subject " & Chr(34) & Subject &_
		Chr(34) & " -server " & sRelayHost & " -f " & sCN & sFQDN & " -attacht " & Chr(34) & sDebugLog & Chr(34) & " -debug " & sP2 & sScript & "_" & altDate & "-" & altTime & ".log" & Chr(34) & " -try " & sTry, 2, True)
	Else
		iMail = oShell.Run(sBlat & " -body " & Chr(34) &_
		Body & Chr(34) & " -to " & sP1 & " -subject " & Chr(34) & Subject &_
		Chr(34) & " -server " & sRelayHost & " -f " & sCN & sFQDN & " -debug " & sP2 & sScript & "_" & altDate & "-" & altTime & ".log" & Chr(34) & " -try " & sTry, 2, True)
	End If
	On Error Goto 0
End Function

' Date/Time Stamping Function
Function Stamp
	On Error Resume Next
	Dim oSplit
	vDate = FormatDateTime(Now(), vbShortDate)
	altDate = Replace(Date, "/", "_")
	vTime = FormatDateTime(Now(), vbLongTime)
	altTime = Replace(Time, ":", ".")
	oSplit = Split(altTime)
	altTime = oSplit(0) & "." & oSplit(1)
	On Error GoTo 0
End Function

' Time into words Function
Function DateDiffToWords(d1, d2)
	Dim report, seconds
	report = ""
	seconds = abs(datediff("S", d1, d2))
	If seconds <= 0 Then
		report = "0 seconds"
	Else
		seconds = seconds mod (24*60*60)
		'divide by 3600 to get hours
		If seconds >= 3600 Then
			report = report & seconds\(3600) & " hour(s), "
		End If
		'use mod to get remaining seconds and divide to get minutes
		seconds = seconds mod (60*60)
		If seconds >= 60 Then
			report = report & seconds\(60) & " minute(s), "
		End If
		'use mod to get remaining seconds
		seconds = seconds Mod (60)
		report = report & seconds & " second(s)"
	End If
	DateDiffToWords = report
End Function

' Close up logs, objects, etc...
Function Cleanup(Subject, Body)
	' Close log(s)
	If IsObject(DebugLog) Then DebugLog.Close
	If (sPilot = "True" Or sTicket = "True") And (sCoreBlat = "") Then Email Subject, Body
	If oProcessEnv("SEE_MASK_NOZONECHECKS") = "1" Then oProcessEnv.Remove("SEE_MASK_NOZONECHECKS")

	'Clean Up
	If sWMIFailed <> "Failed" Then Set oWMI = Nothing
	Set oProcessEnv = Nothing
	Set oFSO = Nothing
	Set oShell = Nothing
End Function

' Must sign script

'' SIG '' Begin signature block
'' SIG '' MIInEwYJKoZIhvcNAQcCoIInBDCCJwACAQExDzANBglg
'' SIG '' hkgBZQMEAgEFADB3BgorBgEEAYI3AgEEoGkwZzAyBgor
'' SIG '' BgEEAYI3AgEeMCQCAQEEEE7wKRaZJ7VNj+Ws4Q8X66sC
'' SIG '' AQACAQACAQACAQACAQAwMTANBglghkgBZQMEAgEFAAQg
'' SIG '' pqpfjeUHSkozR4CZiCuL01sMCuh6y9ramCqKEQMkY/ig
'' SIG '' giDAMIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJ
'' SIG '' KoZIhvcNAQELBQAwTDEgMB4GA1UECxMXR2xvYmFsU2ln
'' SIG '' biBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNp
'' SIG '' Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDkwMzE4
'' SIG '' MTAwMDAwWhcNMjkwMzE4MTAwMDAwWjBMMSAwHgYDVQQL
'' SIG '' ExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMzETMBEGA1UE
'' SIG '' ChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2ln
'' SIG '' bjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
'' SIG '' AMwldpB5BngiFvXAg7aEyiie/QV2EcWtiHL8RgJDx7KK
'' SIG '' nQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X
'' SIG '' 17YUhhB5uzsTgHeMCOFJ0mpiLx9e+pZo34knlTifBtc+
'' SIG '' ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmmKPZpO/bLyCiR
'' SIG '' 5Z2KYVc3rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65T
'' SIG '' pjoWc4zdQQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjlOCZg
'' SIG '' dbKfd/+RFO+uIEn8rUAVSNECMWEZXriX7613t2Saer9f
'' SIG '' wRPvm2L7DWzgVGkWqQPabumDk3F2xmmFghcCAwEAAaNC
'' SIG '' MEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMB
'' SIG '' Af8wHQYDVR0OBBYEFI/wS3+oLkUkrk1Q+mOai97i3Ru8
'' SIG '' MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZU
'' SIG '' RUm7lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/
'' SIG '' c2dKg8dEe3jgr25sbwMpjjM5RcOO5LlXbKr8EpbsU8Yt
'' SIG '' 5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK6fBd
'' SIG '' RoyV3XpYKBovHd7NADdBj+1EbddTKJd+82cEHhXXipa0
'' SIG '' 095MJ6RMG3NzdvQXmcIfeg7jLQitChws/zyrVQ4PkX42
'' SIG '' 68NXSb7hLi18YIvDQVETI53O9zJrlAGomecsMx86OyXS
'' SIG '' hkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7r
'' SIG '' kpeDMdmztcpHWD9fMIIE8zCCA9ugAwIBAgITFgAAAT1N
'' SIG '' IZzxltY2ZwAAAAABPTANBgkqhkiG9w0BAQsFADBtMUMw
'' SIG '' QQYDVQQLEzpDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSBP
'' SIG '' PVRoZSBPcmNoYXJkIEVudGVycHJpc2VzIEluYyBDPVVT
'' SIG '' MSYwJAYDVQQDEx1UaGUgT3JjaGFyZCBJc3N1aW5nIENB
'' SIG '' IE5ZQyBQMjAeFw0yMTA0MjcxNzQ4MTFaFw0yNDA0MjYx
'' SIG '' NzQ4MTFaMHMxCzAJBgNVBAYTAlVTMREwDwYDVQQIEwhO
'' SIG '' ZXcgWW9yazERMA8GA1UEBxMITmV3IFlvcmsxHzAdBgNV
'' SIG '' BAoTFk9yY2hhcmQgRW50ZXJwcmlzZXMgTlkxHTAbBgNV
'' SIG '' BAMTFEluZm9TZWMgQ29kZSBTaWduaW5nMIIBIjANBgkq
'' SIG '' hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArVImrlWkcffd
'' SIG '' OBMi4d8F96Vnz8bQb9v9/rjwJoMuD+oOXi+hb4EeMw+Y
'' SIG '' rURoJ8rTbt5To3xkyWQ1IsL6e67TY6At20MDZvgmSX+g
'' SIG '' /+1N092heWkeMh7xZzjoBWKpIqZSXltFM/jpovOabT8x
'' SIG '' imhJRqJdJkfn03zNN1WP4iQZYsjePXyHP/F+mKEKs6MD
'' SIG '' SSDXkZq/CBtruAnuwnkaQ+KoSVonsbaDCmxObE6ffbnX
'' SIG '' 3II9ZzmUCHd3cgi0uR0pYCecExOps9hrfTw7lXL627aP
'' SIG '' TlObLe7FUil+RUBVgNrrQsMoIVUik8VIGHkBYnE3/1pB
'' SIG '' 7lWAP/sWEkIdy1w55JI+SQIDAQABo4IBhDCCAYAwPQYJ
'' SIG '' KwYBBAGCNxUHBDAwLgYmKwYBBAGCNxUIh4H0aIH0ojmD
'' SIG '' jY0xhpysNYXdy19Bg62cL4L7zX8CAWQCAQUwEwYDVR0l
'' SIG '' BAwwCgYIKwYBBQUHAwMwDgYDVR0PAQH/BAQDAgeAMAwG
'' SIG '' A1UdEwEB/wQCMAAwGwYJKwYBBAGCNxUKBA4wDDAKBggr
'' SIG '' BgEFBQcDAzAdBgNVHQ4EFgQUXWTTyzZ/wRD8KP2yf5jU
'' SIG '' NNHqQgMwHwYDVR0jBBgwFoAUy0ThBEh9b2D958+rUUOk
'' SIG '' yCmBzbcwOQYDVR0fBDIwMDAuoCygKoYoaHR0cDovL3Br
'' SIG '' aS50aGVvcmNoYXJkLmNvbS9pY2EtbnljLXAyLmNybDB0
'' SIG '' BggrBgEFBQcBAQRoMGYwLgYIKwYBBQUHMAGGImh0dHA6
'' SIG '' Ly9vY3NwLW55LnRoZW9yY2hhcmQuY29tL29jc3AwNAYI
'' SIG '' KwYBBQUHMAKGKGh0dHA6Ly9wa2kudGhlb3JjaGFyZC5j
'' SIG '' b20vaWNhLW55Yy1wMi5jcnQwDQYJKoZIhvcNAQELBQAD
'' SIG '' ggEBACcfJ+RCaJN23mIRVYedvv4x2SV2eHC8ir8JKL9P
'' SIG '' R6dO+LHlf8ABplUP9P3LofuACfljcKXe5EGJQkUiqAJ6
'' SIG '' BpOZxKZ0kkwz/jTgoRdTAdnYvO/8BMGpO1zypmd4imLP
'' SIG '' NrVM4vaUigvxoIQmDU31nIW24nst4IMuVwjd7BO49y+b
'' SIG '' dH4A0kWZrybJrnWPGIyP2ASZ9Bpx8H+Dkz3+Ynb8QCsl
'' SIG '' 2MzFKkgwHhfZQLzEee+o+hD4DSX9aUK6uMq/tiglCfzO
'' SIG '' Xqt9ezgOdBTkNsRjixcr3dGYD6AUHTzWO6Q4XSdzcskN
'' SIG '' 3wNWNqOUQEchWxCivT6Q+XdPETPpUBwxVE8Jd9IwggVH
'' SIG '' MIIEL6ADAgECAg0B8kBCQM79ItvpbHH8MA0GCSqGSIb3
'' SIG '' DQEBDAUAMEwxIDAeBgNVBAsTF0dsb2JhbFNpZ24gUm9v
'' SIG '' dCBDQSAtIFIzMRMwEQYDVQQKEwpHbG9iYWxTaWduMRMw
'' SIG '' EQYDVQQDEwpHbG9iYWxTaWduMB4XDTE5MDIyMDAwMDAw
'' SIG '' MFoXDTI5MDMxODEwMDAwMFowTDEgMB4GA1UECxMXR2xv
'' SIG '' YmFsU2lnbiBSb290IENBIC0gUjYxEzARBgNVBAoTCkds
'' SIG '' b2JhbFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wggIi
'' SIG '' MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCVB+hz
'' SIG '' ymb57BTKezz3DQjxtEULLIK0SMbrWzyug7hBkjMUpG9/
'' SIG '' 6SrMxrCIa8W2idHGsv8UzlEUIexK3RtaxtaH7k06FQbt
'' SIG '' ZGYLkoDKRN5zlE7zp4l/T3hjCMgSUG1CZi9NuXkoTVIa
'' SIG '' ihqAtxmBDn7EirxkTCEcQ2jXPTyKxbJm1ZCatzEGxb7i
'' SIG '' bTIGph75ueuqo7i/voJjUNDwGInf5A959eqiHyrScC57
'' SIG '' 57yTu21T4kh8jBAHOP9msndhfuDqjDyqtKT285VKEgdt
'' SIG '' /Yyyic/QoGF3yFh0sNQjOvddOsqi250J3l1ELZDxgc1X
'' SIG '' kvp+vFAEYzTfa5MYvms2sjnkrCQ2t/DvthwTV5O23rL4
'' SIG '' 4oW3c6K4NapF8uCdNqFvVIrxclZuLojFUUJEFZTuo8U4
'' SIG '' lptOTloLR/MGNkl3MLxxN+Wm7CEIdfzmYRY/d9XZkZeE
'' SIG '' CmzUAk10wBTt/Tn7g/JeFKEEsAvp/u6P4W4LsgizYWYJ
'' SIG '' arEGOmWWWcDwNf3J2iiNGhGHcIEKqJp1HZ46hgUAntuA
'' SIG '' 1iX53AWeJ1lMdjlb6vmlodiDD9H/3zAR+YXPM0j1ym1k
'' SIG '' FCx6WE/TSwhJxZVkGmMOeT31s4zKWK2cQkV5bg6HGVxU
'' SIG '' sWW2v4yb3BPpDW+4LtxnbsmLEbWEFIoAGXCDeZGXkdQa
'' SIG '' J783HjIH2BRjPChMrwIDAQABo4IBJjCCASIwDgYDVR0P
'' SIG '' AQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O
'' SIG '' BBYEFK5sBaOTE+Ki5+LXHNbH8H/IZ1OgMB8GA1UdIwQY
'' SIG '' MBaAFI/wS3+oLkUkrk1Q+mOai97i3Ru8MD4GCCsGAQUF
'' SIG '' BwEBBDIwMDAuBggrBgEFBQcwAYYiaHR0cDovL29jc3Ay
'' SIG '' Lmdsb2JhbHNpZ24uY29tL3Jvb3RyMzA2BgNVHR8ELzAt
'' SIG '' MCugKaAnhiVodHRwOi8vY3JsLmdsb2JhbHNpZ24uY29t
'' SIG '' L3Jvb3QtcjMuY3JsMEcGA1UdIARAMD4wPAYEVR0gADA0
'' SIG '' MDIGCCsGAQUFBwIBFiZodHRwczovL3d3dy5nbG9iYWxz
'' SIG '' aWduLmNvbS9yZXBvc2l0b3J5LzANBgkqhkiG9w0BAQwF
'' SIG '' AAOCAQEASaxexYPzWsthKk2XShUpn+QUkKoJ+cR6nzUY
'' SIG '' igozFW1yhyJOQT9tCp4YrtviX/yV0SyYFDuOwfA2WXnz
'' SIG '' jYHPdPYYpOThaM/vf2VZQunKVTm808Um7nE4+tchAw+3
'' SIG '' TtlbYGpDtH0J0GBh3artAF5OMh7gsmyePLLCu5jTkHZq
'' SIG '' aa0a3KiJ2lhP0sKLMkrOVPs46TsHC3UKEdsLfCUn8awm
'' SIG '' zxFT5tzG4mE1MvTO3YPjGTrrwmijcgDIJDxOuFM8sRer
'' SIG '' 5jUs+dNCKeZfYAOsQmGmsVdqM0LfNTGGyj43K9rE2iT1
'' SIG '' ThLytrm3R+q7IK1hFregM+Mtiae8szwBfyMagAk06TCC
'' SIG '' BlEwggQ5oAMCAQICEyYAAAACwtxZyWwYO0EAAAAAAAIw
'' SIG '' DQYJKoZIhvcNAQELBQAwYzFDMEEGA1UECxM6Q2VydGlm
'' SIG '' aWNhdGlvbiBBdXRob3JpdHkgTz1UaGUgT3JjaGFyZCBF
'' SIG '' bnRlcnByaXNlcyBJbmMgQz1VUzEcMBoGA1UEAxMTVGhl
'' SIG '' IE9yY2hhcmQgUm9vdCBDQTAeFw0yMDExMDkxODAxNTJa
'' SIG '' Fw0yNTExMDkxODExNTJaMG0xQzBBBgNVBAsTOkNlcnRp
'' SIG '' ZmljYXRpb24gQXV0aG9yaXR5IE89VGhlIE9yY2hhcmQg
'' SIG '' RW50ZXJwcmlzZXMgSW5jIEM9VVMxJjAkBgNVBAMTHVRo
'' SIG '' ZSBPcmNoYXJkIElzc3VpbmcgQ0EgTllDIFAyMIIBIjAN
'' SIG '' BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyvTk0r9E
'' SIG '' Fa/soDZ9GhGut4zVMNgYrmtk/3bEEIJG0/mvCOuiBe16
'' SIG '' jKeoOH5+4V1U2wEMrQpioVF0DFFvHbO41EdU7pyb9Nz4
'' SIG '' f5B3v5ikZnKnUdn1xp0seuEVVFDlbmgNwu1t8msLju3f
'' SIG '' jJSsnhzebgbOtLNMygvMNSWy7k08ablYcjdunr6B6iq5
'' SIG '' 8jMeL8GoKQMkIgX6/Mat/Ca0aK7t2pQ3dFpJiSgTwgZT
'' SIG '' K/Z8GTZ8LG2FmvrrnWg1ti/+jCxGNNOahhEnihDiaKKf
'' SIG '' pRmWFhnu6pW5QMEJNe7sAZYILuD4rF0VsQ6kEkH0H/Y2
'' SIG '' +JkquWBaP9AR1oV81/gTy+ae6QIDAQABo4IB8jCCAe4w
'' SIG '' EAYJKwYBBAGCNxUBBAMCAQAwHQYDVR0OBBYEFMtE4QRI
'' SIG '' fW9g/efPq1FDpMgpgc23MIHgBgNVHSAEgdgwgdUwgdIG
'' SIG '' DSsGAQQBg6EcAQEBAQAwgcAwgY0GCCsGAQUFBwICMIGA
'' SIG '' Hn4AKgAgAFIAZQBmAGUAcgAgAHQAbwAgAHQAaABlACAA
'' SIG '' YwBlAHIAdABpAGYAaQBjAGEAdABpAG8AbgAgAGEAdQB0
'' SIG '' AGgAbwByAGkAdAB5ACcAcwAgAHMAdABhAHQAZQBtAGUA
'' SIG '' bgB0ACAAZgBvAHIAIABkAGUAdABhAGkAbABzAC4wLgYI
'' SIG '' KwYBBQUHAgEWImh0dHA6Ly9wa2kudGhlb3JjaGFyZC5j
'' SIG '' b20vY3BzLnR4dAAwGQYJKwYBBAGCNxQCBAweCgBTAHUA
'' SIG '' YgBDAEEwCwYDVR0PBAQDAgGGMBIGA1UdEwEB/wQIMAYB
'' SIG '' Af8CAQAwHwYDVR0jBBgwFoAUZAjY9slFA9LEtOekeZIV
'' SIG '' VMsRQ3EwNwYDVR0fBDAwLjAsoCqgKIYmaHR0cDovL3Br
'' SIG '' aS50aGVvcmNoYXJkLmNvbS9vcmNoLXJjYS5jcmwwQgYI
'' SIG '' KwYBBQUHAQEENjA0MDIGCCsGAQUFBzAChiZodHRwOi8v
'' SIG '' cGtpLnRoZW9yY2hhcmQuY29tL29yY2gtcmNhLmNydDAN
'' SIG '' BgkqhkiG9w0BAQsFAAOCAgEAVPk49fHsUXNay3x2DN22
'' SIG '' OLyhVgolEvD9Fe1mitq753NzhAzNikq/W3Pky1617Yc+
'' SIG '' XXM3ZQ1yXP79QTtuiTYBnLTNPdXDvnnBI2moVj6VsG5B
'' SIG '' eAj8bJ3AuNiR3EviAmImqVUr5BEOJnr5mrFuj9hQU+0u
'' SIG '' GrCm9Mkd+2547kZaeUe0Oke3H+RQ4iCQFG/ulAlCYMRn
'' SIG '' Le0beiV0+M0lIQOPUhkUqF60G/BC7+hKeebltUHMdzlH
'' SIG '' 598BPvfNfwEmgSf4X0Hzng/xRF4ScFS94mAHvlJURT3Z
'' SIG '' 7bK89BfItft+zcyFzCDrPxH7MTe7OqbHMpP2w1vuQdbS
'' SIG '' 0NKfUXQmEtWMn90C2sb3i1YDORrxGLfTlHYbVTf7H0Y8
'' SIG '' t8dVC6Zs1NHPiy6DhzQEhVUZfHLcB4YCeRs1HsiwYqrh
'' SIG '' +2BJsrPjKAzBaDNWLw2YggqSDPqcOHgMLL797Gd9beVU
'' SIG '' ukTo6QOVVP4y9G/SzYX4r9CID1dB/zu0eo9HjzIdlzah
'' SIG '' 1Zh5gyri/taJearNGnTAS/HGPb7oqK9kCKOIsmiaXapZ
'' SIG '' XOxLHRrRxO8vLX1e2xP9pH566IR3rsYhzICkh3cS6TMv
'' SIG '' l0wFE4W5d2z6psIqy91D1MI8kzthulXf7k7vPi3kRWXf
'' SIG '' IlPgoUuDaXRitM/E2B7Uh67ApTmgJYPtVnpQWXw8J2oD
'' SIG '' uZQwggZZMIIEQaADAgECAg0B7BySQN79LkBdfEd0MA0G
'' SIG '' CSqGSIb3DQEBDAUAMEwxIDAeBgNVBAsTF0dsb2JhbFNp
'' SIG '' Z24gUm9vdCBDQSAtIFI2MRMwEQYDVQQKEwpHbG9iYWxT
'' SIG '' aWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTE4MDYy
'' SIG '' MDAwMDAwMFoXDTM0MTIxMDAwMDAwMFowWzELMAkGA1UE
'' SIG '' BhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2Ex
'' SIG '' MTAvBgNVBAMTKEdsb2JhbFNpZ24gVGltZXN0YW1waW5n
'' SIG '' IENBIC0gU0hBMzg0IC0gRzQwggIiMA0GCSqGSIb3DQEB
'' SIG '' AQUAA4ICDwAwggIKAoICAQDwAuIwI/rgG+GadLOvdYNf
'' SIG '' qUdSx2E6Y3w5I3ltdPwx5HQSGZb6zidiW64HiifuV6PE
'' SIG '' Ne2zNMeswwzrgGZt0ShKwSy7uXDycq6M95laXXauv0So
'' SIG '' fEEkjo+6xU//NkGrpy39eE5DiP6TGRfZ7jHPvIo7bmrE
'' SIG '' iPDul/bc8xigS5kcDoenJuGIyaDlmeKe9JxMP11b7Lbv
'' SIG '' 0mXPRQtUPbFUUweLmW64VJmKqDGSO/J6ffwOWN+BauGw
'' SIG '' bB5lgirUIceU/kKWO/ELsX9/RpgOhz16ZevRVqkuvftY
'' SIG '' PbWF+lOZTVt07XJLog2CNxkM0KvqWsHvD9WZuT/0TzXx
'' SIG '' nA/TNxNS2SU07Zbv+GfqCL6PSXr/kLHU9ykV1/kNXdaH
'' SIG '' Qx50xHAotIB7vSqbu4ThDqxvDbm19m1W/oodCT4kDmcm
'' SIG '' x/yyDaCUsLKUzHvmZ/6mWLLU2EESwVX9bpHFu7FMCEue
'' SIG '' 1EIGbxsY1TbqZK7O/fUF5uJm0A4FIayxEQYjGeT7BTRE
'' SIG '' 6giunUlnEYuC5a1ahqdm/TMDAd6ZJflxbumcXQJMYDzP
'' SIG '' Ao8B/XLukvGnEt5CEk3sqSbldwKsDlcMCdFhniaI/Miy
'' SIG '' Tdtk8EWfusE/VKPYdgKVbGqNyiJc9gwE4yn6S7Ac0zd0
'' SIG '' hNkdZqs0c48efXxeltY9GbCX6oxQkW2vV4Z+EDcdaxoU
'' SIG '' 3wIDAQABo4IBKTCCASUwDgYDVR0PAQH/BAQDAgGGMBIG
'' SIG '' A1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFOoWxmnn
'' SIG '' 48tXRTkzpPBAvtDDvWWWMB8GA1UdIwQYMBaAFK5sBaOT
'' SIG '' E+Ki5+LXHNbH8H/IZ1OgMD4GCCsGAQUFBwEBBDIwMDAu
'' SIG '' BggrBgEFBQcwAYYiaHR0cDovL29jc3AyLmdsb2JhbHNp
'' SIG '' Z24uY29tL3Jvb3RyNjA2BgNVHR8ELzAtMCugKaAnhiVo
'' SIG '' dHRwOi8vY3JsLmdsb2JhbHNpZ24uY29tL3Jvb3QtcjYu
'' SIG '' Y3JsMEcGA1UdIARAMD4wPAYEVR0gADA0MDIGCCsGAQUF
'' SIG '' BwIBFiZodHRwczovL3d3dy5nbG9iYWxzaWduLmNvbS9y
'' SIG '' ZXBvc2l0b3J5LzANBgkqhkiG9w0BAQwFAAOCAgEAf+KI
'' SIG '' 2VdnK0JfgacJC7rEuygYVtZMv9sbB3DG+wsJrQA6YDMf
'' SIG '' OcYWaxlASSUIHuSb99akDY8elvKGohfeQb9P4byrze7A
'' SIG '' I4zGhf5LFST5GETsH8KkrNCyz+zCVmUdvX/23oLIt59h
'' SIG '' 07VGSJiXAmd6FpVK22LG0LMCzDRIRVXd7OlKn14U7XIQ
'' SIG '' cXZw0g+W8+o3V5SRGK/cjZk4GVjCqaF+om4VJuq0+X8q
'' SIG '' 5+dIZGkv0pqhcvb3JEt0Wn1yhjWzAlcfi5z8u6xM3vre
'' SIG '' U0yD/RKxtklVT3WdrG9KyC5qucqIwxIwTrIIc59eodaZ
'' SIG '' zul9S5YszBZrGM3kWTeGCSziRdayzW6CdaXajR63Wy+I
'' SIG '' Lj198fKRMAWcznt8oMWsr1EG8BHHHTDFUVZg6HyVPSLj
'' SIG '' 1QokUyeXgPpIiScseeI85Zse46qEgok+wEr1If5iEO0d
'' SIG '' MPz2zOpIJ3yLdUJ/a8vzpWuVHwRYNAqJ7YJQ5NF7qMnm
'' SIG '' vkiqK1XZjbclIA4bUaDUY6qD6mxyYUrJ+kPExlfFnbY8
'' SIG '' sIuwuRwx773vFNgUQGwgHcIt6AvGjW2MtnHtUiH+Pvaf
'' SIG '' nzkarqzSL3ogsfSsqh3iLRSd+pZqHcY8yvPZHL9TTaRH
'' SIG '' WXyVxENB+SXiLBB+gfkNlKd98rUJ9dhgckBQlSDUQ0S+
'' SIG '' +qCV5yBZtnjGpGqqIpswggZlMIIETaADAgECAhABhNOo
'' SIG '' zjeB61f0/Yd7g66yMA0GCSqGSIb3DQEBCwUAMFsxCzAJ
'' SIG '' BgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52
'' SIG '' LXNhMTEwLwYDVQQDEyhHbG9iYWxTaWduIFRpbWVzdGFt
'' SIG '' cGluZyBDQSAtIFNIQTM4NCAtIEc0MB4XDTIxMDUyNzEw
'' SIG '' MDAxNloXDTMyMDYyODEwMDAxNVowYzELMAkGA1UEBhMC
'' SIG '' QkUxGTAXBgNVBAoMEEdsb2JhbFNpZ24gbnYtc2ExOTA3
'' SIG '' BgNVBAMMMEdsb2JhbHNpZ24gVFNBIGZvciBNUyBBdXRo
'' SIG '' ZW50aWNvZGUgQWR2YW5jZWQgLSBHNDCCAaIwDQYJKoZI
'' SIG '' hvcNAQEBBQADggGPADCCAYoCggGBAOKim7ZJ+zRIKCMH
'' SIG '' hv1SE026y6o14vlAHBt7acWYKszJXO8nxuy4JWXDPx1E
'' SIG '' 597hCO8EFwCVlwz9212DtIjroI6bT4O6+d9eGFRqAg4O
'' SIG '' 5lTwN6QenGcxBbU3cXx6ftiBZTPkmuqwMTfHZrSjugUn
'' SIG '' 6m5SgljZglYkjfnrsxT7ZACheyofep6oY5Hm2NEixj/S
'' SIG '' nTg/r5VpWye/6EAkmccf2XuSBQJ9KMY8Ofd6zfdlJqA3
'' SIG '' rzIFd5dq4RAbmIUshK3lJYZ8c57NiI1LKnqdD1l5vfLa
'' SIG '' Nn5mrC74u4iXyW158rPU1cwa9E+LRZV28oeVgI4oebr9
'' SIG '' xXCvvBoUApB8JlsRi131uuQRAsWBHGZoS95ozp0MiGGq
'' SIG '' tpQjneCkPEZdBFHbP1kL5+y+0tkTKkfvSxISbsg1z+4W
'' SIG '' MrbQX4W4T/J82AkrEl7Awu8TMXA2c9zWV1TTV2CeHBCV
'' SIG '' 8OaqLxCKG37JzY/OUEscJajAF2RRFQuMz9fJXUpsSXSu
'' SIG '' WvFqBnU+iTc7kQIDAQABo4IBmzCCAZcwDgYDVR0PAQH/
'' SIG '' BAQDAgeAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMB0G
'' SIG '' A1UdDgQWBBR1ryc/uNua7G8c7sNqZPa/hDWwzjBMBgNV
'' SIG '' HSAERTBDMEEGCSsGAQQBoDIBHjA0MDIGCCsGAQUFBwIB
'' SIG '' FiZodHRwczovL3d3dy5nbG9iYWxzaWduLmNvbS9yZXBv
'' SIG '' c2l0b3J5LzAJBgNVHRMEAjAAMIGQBggrBgEFBQcBAQSB
'' SIG '' gzCBgDA5BggrBgEFBQcwAYYtaHR0cDovL29jc3AuZ2xv
'' SIG '' YmFsc2lnbi5jb20vY2EvZ3N0c2FjYXNoYTM4NGc0MEMG
'' SIG '' CCsGAQUFBzAChjdodHRwOi8vc2VjdXJlLmdsb2JhbHNp
'' SIG '' Z24uY29tL2NhY2VydC9nc3RzYWNhc2hhMzg0ZzQuY3J0
'' SIG '' MB8GA1UdIwQYMBaAFOoWxmnn48tXRTkzpPBAvtDDvWWW
'' SIG '' MEEGA1UdHwQ6MDgwNqA0oDKGMGh0dHA6Ly9jcmwuZ2xv
'' SIG '' YmFsc2lnbi5jb20vY2EvZ3N0c2FjYXNoYTM4NGc0LmNy
'' SIG '' bDANBgkqhkiG9w0BAQsFAAOCAgEAOJO3fTWJNOoa1qp6
'' SIG '' zo2E2+E0t3Sl/9hdlDYlj9KAfqFlsZvPNVFd26BLbvch
'' SIG '' QC7sT28WQHIcdRswABc5j8gvpHHOJDMmkNXk/zm5Ye8L
'' SIG '' yjnzLV6NoP9O4VZkH9ScdgSkRFw9YoVwL/lOpPeGVtt6
'' SIG '' SSZDLQWb4sOJtzqhLScnGMZDi9xDobZyLT/ZxjSKAtNi
'' SIG '' OSnwfSjQqcNkikZts0McdIvduaYLIXsRpx9dotuM4FXT
'' SIG '' afp30V0UuZbskUUbG2x+QkAkpO1AxmX6QY9IMZzjuLMX
'' SIG '' V4J5yswewtBPTwUODXnXad2VoXFdip7nWsJPqAYPCIl7
'' SIG '' 21jIJX3/aLwoonCcuwy1U+iOBrGygoGHEqled0yTqxj4
'' SIG '' RFdYEcv2kxVJMbdTUCHa1fxgf90wxaxRRAtnpfrWdzSt
'' SIG '' Eh8o+4jaUZtEmt53Du4yEmBWDJGdWI+8mVfyvs25w3Mk
'' SIG '' Gdp3puTs8d5v4LyEHW/D8dvh1UJRhlESQiY+0+oT9Cic
'' SIG '' rU16t6K6FGo/QFVYToxlHLP2ddZ/rg+EgC++iHhcJx9H
'' SIG '' F8I95Gmey66e7wJoiDcQwmwmisiMZZBTTa5d2rhGENSQ
'' SIG '' Cor/9ChAgeBSyPIBZEgYhHhqIvrKnKoOHcWOcsM2Ihnr
'' SIG '' +JQfv8LFAVbppoDqAR0TNQfiuXQU/Zo4ngPSSfZM66G9
'' SIG '' HBTS45kxggWrMIIFpwIBATCBhDBtMUMwQQYDVQQLEzpD
'' SIG '' ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSBPPVRoZSBPcmNo
'' SIG '' YXJkIEVudGVycHJpc2VzIEluYyBDPVVTMSYwJAYDVQQD
'' SIG '' Ex1UaGUgT3JjaGFyZCBJc3N1aW5nIENBIE5ZQyBQMgIT
'' SIG '' FgAAAT1NIZzxltY2ZwAAAAABPTANBglghkgBZQMEAgEF
'' SIG '' AKCBhDAYBgorBgEEAYI3AgEMMQowCKACgAChAoAAMBkG
'' SIG '' CSqGSIb3DQEJAzEMBgorBgEEAYI3AgEEMBwGCisGAQQB
'' SIG '' gjcCAQsxDjAMBgorBgEEAYI3AgEVMC8GCSqGSIb3DQEJ
'' SIG '' BDEiBCAk2Fs2lq7oH5mEgT63N8YTps6m/LGWAaaZsngF
'' SIG '' UG02cTANBgkqhkiG9w0BAQEFAASCAQBUf7jGrjrqpYJx
'' SIG '' 3i3Uz8jWaQ18CnW8wFVraiNyaHQsA2dCLjvoeqnN1OZu
'' SIG '' exJuUSs6z+tpSxnVQKapfQig8qhESHn8QvmP/75TiDWL
'' SIG '' WB08IHoZoY5vE2dW3z1J/qMKiPxh6aijYS2GRbQtayCl
'' SIG '' AKHnaMGT+q+lK/c9yxjPqZ3Hg6J46Gn2gv8R85hNayM4
'' SIG '' 5QdyuHGuIaXMEXvLhRpjpgCvOgUUef6QWQEpBnBE3aUl
'' SIG '' abJjWlcux1slLXWMaRnBOJGTdMbGKqo2Gk5HTcJkIDGD
'' SIG '' jlTGE5aEAL0tQ7ruwyTfHoCvsfMXBiBVRqywP4PpRNJ8
'' SIG '' xgy7GjXkjAwkDSgeZAnmoYIDcDCCA2wGCSqGSIb3DQEJ
'' SIG '' BjGCA10wggNZAgEBMG8wWzELMAkGA1UEBhMCQkUxGTAX
'' SIG '' BgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExMTAvBgNVBAMT
'' SIG '' KEdsb2JhbFNpZ24gVGltZXN0YW1waW5nIENBIC0gU0hB
'' SIG '' Mzg0IC0gRzQCEAGE06jON4HrV/T9h3uDrrIwDQYJYIZI
'' SIG '' AWUDBAIBBQCgggE/MBgGCSqGSIb3DQEJAzELBgkqhkiG
'' SIG '' 9w0BBwEwHAYJKoZIhvcNAQkFMQ8XDTIxMDcxMjE5MDkx
'' SIG '' MVowLQYJKoZIhvcNAQk0MSAwHjANBglghkgBZQMEAgEF
'' SIG '' AKENBgkqhkiG9w0BAQsFADAvBgkqhkiG9w0BCQQxIgQg
'' SIG '' oewAff563bjd1pzrNlmZ6DBZknL/ZS+3hd5CleyTIw4w
'' SIG '' gaQGCyqGSIb3DQEJEAIMMYGUMIGRMIGOMIGLBBTdV7Wz
'' SIG '' hzyGGynGrsRzGvvojXXBSTBzMF+kXTBbMQswCQYDVQQG
'' SIG '' EwJCRTEZMBcGA1UEChMQR2xvYmFsU2lnbiBudi1zYTEx
'' SIG '' MC8GA1UEAxMoR2xvYmFsU2lnbiBUaW1lc3RhbXBpbmcg
'' SIG '' Q0EgLSBTSEEzODQgLSBHNAIQAYTTqM43getX9P2He4Ou
'' SIG '' sjANBgkqhkiG9w0BAQsFAASCAYCCe5JHfXl7OgYefO/W
'' SIG '' RojkqoadCDbRlbmsbJGDXvwq6XUzIbbL8C+3ISaeVCjB
'' SIG '' jClcytOu2kqS5QYVNC3GZHGk8knxskRs6Jq+oChyhiks
'' SIG '' bNzkCDv8Byq7/uO8LKqc0m6HPW/GNB1nb4rD6dihBFSx
'' SIG '' ce1yQQq+HNn1RKjN4YRw+v8r0O4b0Llw+FnpHJuNhJMg
'' SIG '' /WTbinFUdZCgtGL8xtZbTJCzfd5Y8mpNDwY13Pn0GRZG
'' SIG '' 6g/oQ73G4h3SF4J0cvIhjONwVNN/KVe8lZfocsflRCGa
'' SIG '' 04dfOLEHyDtdCQU7wazuJ2cIEMYv3aqITNI9HkkArCYs
'' SIG '' RFn75X2MONFN5P3HN6afaddTYWfIi2xMozvCG4ZtG9IG
'' SIG '' YGhx6UnUE8WIDZKAC7cXm249XoI17XYa/vj23MEw7Vlm
'' SIG '' ARKkwXIfzp+MG5+xy8k1wNZSJTatzlbf4WYiwhTHI4c8
'' SIG '' 5uPXHwB1yh2GRwY1y892iuTFtma8Vrnph6t2eimdMLEO
'' SIG '' nVpAMyEkYUk=
'' SIG '' End signature block
