'==========================================================================
'
' NAME: Run-CIS-CAT-x64-3.0.55-M-R1.vbs
'
' AUTHOR:  Max Erenburg
' DATE  : 5/10/2018
'
' COMMENT: This script will verify asset has the latest CIS-CAT bundle and execute it based on schedule.
' Update 05/24/2018 Added ability to suppress alerting on failure to reach CIS-CAT server (e.g. when on Wireless network)
' Update 05/25/2018 When having to change token only not CIS-CAT nor JRE, need to delete currently unzipped bundle in order for it to unzip the update bundle which just has an update field containing the new token.
' Update 05/30/2018 Added additonal check for token file change, code improvement.
' Update 07/05/2018 Added Bitlocker to Windows 10 benchmark profile
' Update 11/12/2018 New CIS-CAT bundle version .53, changed to supplying token on commandline (no more need for property file) and fixed DEV/QA bug where they where stamping registry affects those few asset's PROD scans. Update to JRE 1.8.0_192, new Windows 10 benchmarks (1607,1703 and 1709)
' Update 11/19/2018 Added CB version to output/debug, CIS-CAT made major change to Profile with Win10 CB 1709 benchmark, put in temp fix while we wait for them to reply back.
' Update 11/27/2018 CIS-CAT provided us a "tailored" benchmark profiles for Windows 10 CB 1709 for the shor-term.
' Update 02/04/2018 Run updated script to version 2.0.1 R1 for new CIS-CAT and JRE versions (new benchmark CIS_Microsoft_Windows_Server_2016_RTM_Release_1607_Benchmark_v1.1.0)
' Update 02/18/2018 Added update get OS function(gather build info) and additional debug of what argument/parameter was used.
' Update 06/30/2020 Added additional grainular checks for incomplete CIS-CAT extracts, additional debugging and code to generate ticket with SD system
'==========================================================================

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 oWMI, sWMIFailed, sWMIMsgBody2
Dim LBT, iOSLang, sOSLangHex, sOSLanguage
Dim TZ, description, address, subnet, subnetmask

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

' Packager's defined variable's
Const DEPLOYNAME = "CIS-CAT-x64-3.0.55"
Const SIDE = "-M"
Const RELEASE = "-R1"
sScript = "Run-" & DEPLOYNAME & SIDE & RELEASE

sDebug = "False" : sDebugBlat = "False"
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

sMailbox1 = "merenburg@theorchard.com" : sMailbox2 = "" : sMailbox3 = "bwilliams@theorchard.com" : sSD = "techsupport@theorchard.com"
sRelayHost = "smtp-relay.gmail.com"
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\"

Const CISCATVER = "3.0.55cust"
Const JREVER = "jre1.8.0_202"


' Initialize WMI connection to cimv2
On Error Resume Next
Set oWMI = GetObject("winmgmts:\\.\root\cimv2")
If Err.Number <> 0 Then
	iErrCode = Err.Number
	sWMIFailed = "Failed"
	sWMIMsgBody2 = Now & "__ Script was unable to successfully connect to cimv2, Error code: " & iErrCode & ", installations are dependent on WMI being healthy, cannot proceed."
End If
On Error GoTo 0

sMsg = "Scriptname: " & WScript.ScriptName
sMsg = sMsg & "|ScriptPath: " & WScript.ScriptFullName
Dim ENV : ENV = WScript.Arguments.Item(0)
sMsg = sMsg & "|Script argument specified: " & ENV

' 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 what OS, CSD version are we working with
Call GetOSInfo

' Get OS Install Date
Call GetInstallDate

' 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

' 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")

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

' Check if DC Function
Call IsDC

If s64Bit = "0" Then WSHLog "CriticalFailure", "This script does not support 32 bit OS."

' Check command line parameters
Call ParamCheck

' Setup CIS-CAT assessor environment
Dim CISCATURL, TOKEN, BUNDLE, CISCATAPIURL, sBN
Call Settings

' Copy CIS-CAT bundle local (first time or if there is a change)
Call CopyCISCAT

' Check if its time to run CIS-CAT scan and upload data based on schedule
Call CISCAT("Weekly") ' Weekly, Monthly

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
		Call Cleanup(sScript & "  Status", sMsg)
	Else
		Call Cleanup(sScript & "  Status", "Wrapper exit code  : " & Err.Number & "|" & sMsg)
	End If
	WScript.Quit
End If

' ------   Packager's defined Functions/Subs section    -------

' Execute CIS-CAT scan and upload data based on schedule
Function CISCAT(sInterval)
	On Error Resume Next 	
	Dim sLRM, LRMKey, sLRW, LRWKey, sRun, sFirst
	If (UCase(ENV) = "PROD") Then ' PROD ( For DEV & QA we dont limit how many times we can run a scan/export/)
		If UCase(sInterval) = "MONTHLY" Then
			sLRM = sEngKey & "Scripts\CC\LastRunMonth"
			LRMKey = GetRegData(sLRM, "{default}")
			If LRMKey = "{default}" Then 'Never ran before
				If Not IsObject(DebugLog) Then Call CreateDebugLog("WriteLog")
				sRun = "Yes"
				sFirst = "Yes"
			ElseIf CInt(LRMKey) <> Month(Date) Then
				sRun = "Yes"
			Else
				sRun = "No" 'Found already ran this Month
			End If
		ElseIf UCase(sInterval) = "WEEKLY" Then
			sLRW = sEngKey & "Scripts\CC\LastRunWeek"
			LRWKey  = GetRegData(sLRW, "{default}")
			If LRWKey = "{default}" Then 'Never ran before 
				If Not IsObject(DebugLog) Then Call CreateDebugLog("WriteLog")
				sRun = "Yes"
				sFirst = "Yes"
			ElseIf CInt(LRWKey) <> DatePart("ww",Date) Then
				sRun = "Yes"
			Else
				sRun = "No" 'Found already ran this week
				'If Not IsObject(DebugLog) Then Call CreateDebugLog("WriteLog") ' DEBUG
				'DebugLog.WriteLine(Now & "__ Found already ran this week. Error Code currently: " & Err.Number & " " & Err.Description) 'DEBUG
			End If
		Else
			WSHLog "CriticalFailure", "Unknown value specified for Interval to check if CIS-CAT is required to run. Value specified: " & sInterval & "."
		End If
	Else
		sRun = "Yes"
	End If

	If sRun = "Yes" Then
		Dim vCT, Profiles, Benchmark
		Call chkInternet(CISCATURL) 'See If we can reach CIS-CAT Dashboard server
		vCT = Now : Call Stamp
		If Not IsObject(DebugLog) Then Call CreateDebugLog("WriteLog")
		' Then which benchmark profile:
		' SET Profiles=xccdf_org.cisecurity.benchmarks_profile_Level_1
		' SET Profiles=xccdf_org.cisecurity.benchmarks_profile_Level_1__BitLocker
		' SET Profiles=xccdf_org.cisecurity.benchmarks_profile_Level_1_BitLocker ' NEW 1.4.0.1
		' SET Profiles=xccdf_org.cisecurity.benchmarks_profile_Level_1_Next_Generation_Windows_Security ' NEW 1.4.0.1
		' SET Profiles=xccdf_org.cisecurity.benchmarks_profile_Level_1_Bitlocker_Next_Generation_Windows_Security ' NEW 1.4.0.1
		' SET Profiles=xccdf_org.cisecurity.benchmarks_profile_Level_1_Bitlocker_Next_Generation_Windows_Security ' NEW 1.4.0.1
		' xccdf_org.cisecurity.benchmarks_profile_BitLocker ' Windows 10 1709 It is intended be an optional "add-on" to the Level 1 or Level 2 profiles.
		' BAD xccdf_org.cisecurity.benchmarks_profile_Level_1_Plus_Bitlocker ' Windows 10 CB 1709 tailoring
		' xccdf_org.cisecurity.benchmarks_profile_Next_Generation_Windows_Security ' Windows 10 1709 This profile is intended to be an optional "add-on" to the Level 1 or Level 2 profiles.
		' BAD xccdf_org.cisecurity.benchmarks_profile_Level_1_Plus_Bitlocker_Plus_NextGen ' Windows 10 CB 1709 tailoring
		' BAD xccdf_org.cisecurity.benchmarks_profile_Level_2_Plus_Bitlocker ' Windows 10 CB 1709 tailoring
		' BAD xccdf_org.cisecurity.benchmarks_profile_Level_2_Plus_Bitlocker_Plus_NextGen ' Windows 10 CB 1709 tailoring
		' SET Profiles=xccdf_org.cisecurity.benchmarks_profile_Level_1_-_Member_Server
		' SET Profiles=xccdf_org.cisecurity.benchmarks_profile_Level_1_-_Domain_Controller
		' SET Profiles=xccdf_org.cisecurity.benchmarks_profile_Level_2
		' SET Profiles=xccdf_org.cisecurity.benchmarks_profile_Level_2__BitLocker
		' SET Profiles=xccdf_org.cisecurity.benchmarks_profile_Level_2_BitLocker ' NEW 1.4.0.1
		' SET Profiles=xccdf_org.cisecurity.benchmarks_profile_Level_2_Next_Generation_Windows_Security ' NEW 1.4.0.1
		' SET Profiles=xccdf_org.cisecurity.benchmarks_profile_Level_2_Bitlocker_Next_Generation_Windows_Security ' NEW 1.4.0.1
		' SET Profiles=xccdf_org.cisecurity.benchmarks_profile_Level_2_-_Member_Server
		' SET Profiles=xccdf_org.cisecurity.benchmarks_profile_Level_2_-_Domain_Controller

		' figure out if Level 1 (T1 Server/T3 Clients) OR Level 2 (T2 jump/ T1 jump/ T0 Servers and DC's)
		If IsServer Then
			If DC = "True" Then
				Profiles = "xccdf_org.cisecurity.benchmarks_profile_Level_2_-_Domain_Controller" 'Level 2
			Else
				' If Jump Server then Level 2
				If InStr(UCase(sCN), "JUMP") Then
					Profiles = "xccdf_org.cisecurity.benchmarks_profile_Level_2_-_Member_Server" 'Level 2
				Else
					' Get Distigushed Name to figure out which Tier
					If InStr(UCase(sDN), "OU=T0") Then
						Profiles = "xccdf_org.cisecurity.benchmarks_profile_Level_2_-_Member_Server" 'Level 2
					ElseIf InStr(UCase(sDN), "OU=T1") Then
						Profiles = "xccdf_org.cisecurity.benchmarks_profile_Level_1_-_Member_Server" 'Level 1
					Else
						' Something is wrong this server was not found in either of the tiers...?
						iErrCode = "999"
						DebugLog.WriteLine(Now & "__ Something is wrong this server was not found in either of the tiers or some condition not accounted for. Check placment of this asset in AD.")
						WSHLog "CriticalFailure", "Something is wrong this server was not found in either of the tiers or some condition not accounted for. Check placment of this asset in AD."
					End If
				End If
			End If
		Else ' Client
			If InStr(UCase(ProductName), "7") Then
				Profiles = "xccdf_org.cisecurity.benchmarks_profile_Level_1" 'Level 1 = not for "The Orchard" Windows 7 becuase of OEM Pro
			ElseIf InStr(UCase(ProductName), "10") Then
				If CBVer = "1607" Then
					Profiles = "xccdf_org.cisecurity.benchmarks_profile_Level_1__BitLocker"
				ElseIf CBVer = "1703" Then
					Profiles = "xccdf_org.cisecurity.benchmarks_profile_Level_1__BitLocker"
				ElseIf CBVer = "1709" Then
					Profiles = "xccdf_org.cisecurity.benchmarks_profile_Level_1_BitLocker" ' "xccdf_org.cisecurity.benchmarks_profile_Level_1"
				Else
					Profiles = "xccdf_org.cisecurity.benchmarks_profile_Level_1_BitLocker" ' "xccdf_org.cisecurity.benchmarks_profile_Level_1"
				End If			
			Else
				DebugLog.WriteLine(Now & "__ Unknown OS version, script does not accounted for this: " & ProductName & ".")
				WSHLog "CriticalFailure", "Unknown OS version, script does not accounted for this: " & ProductName & "."
			End If
		End If
		DebugLog.WriteLine(Now & "__ Determined the CIS-CAT profile we will run against this asset will be: " & Profiles & ".")
		WSHLog "Information", "Determined the CIS-CAT profile we will run against this asset will be: " & Profiles & "."

		' Then which benchmark we will run the asset against
		If IsServer Then
			If InStr(UCase(ProductName), "2008 R2") Then
				'Benchmark = "CIS_Microsoft_Windows_Server_2008_R2_Benchmark_v3.0.1-xccdf.xml"
				Benchmark = "CIS_Microsoft_Windows_Server_2008_R2_Benchmark_v3.1.0-xccdf.xml"
			ElseIf InStr(UCase(ProductName), "2012 R2") Then
				'Benchmark = "CIS_Microsoft_Windows_Server_2012_R2_Benchmark_v2.2.1-xccdf.xml"
				Benchmark = "CIS_Microsoft_Windows_Server_2012_R2_Benchmark_v2.3.0-xccdf.xml"
			ElseIf InStr(UCase(ProductName), "2016") Then
				Benchmark = "CIS_Microsoft_Windows_Server_2016_RTM_Release_1607_Benchmark_v1.1.0-xccdf"
			Else
				iErrCode = "999"
				If Not IsObject(DebugLog) Then Call CreateDebugLog("WriteLog")
				DebugLog.WriteLine(Now & "__ Script is not accounted for this assets OS, which was found to be: " & ProductName & ".")
				WSHLog "CriticalFailure", "Script is not accounted for this assets OS, which was found to be: " & ProductName & "."
			End If

		Else ' Client
			If InStr(UCase(ProductName), "7") Then
				'Benchmark = "CIS_Microsoft_Windows_7_Benchmark_v3.0.1-xccdf.xml"
				Benchmark = "CIS_Microsoft_Windows_7_Workstation_Benchmark_v3.1.0-xccdf.xml"
			ElseIf InStr(UCase(ProductName), "10") Then
				If CBVer = "1607" Then
					Benchmark = "CIS_Microsoft_Windows_10_Enterprise_Release_1607_Benchmark_v1.2.0-xccdf.xml"
				ElseIf CBVer = "1703" Then
					Benchmark = "CIS_Microsoft_Windows_10_Enterprise_Release_1703_Benchmark_v1.3.0-xccdf.xml"
				ElseIf CBVer = "1709" Then
					'Benchmark = "CIS_Microsoft_Windows_10_Enterprise_Release_1709_Benchmark_v1.4.0-xccdf.xml" ' original
					Benchmark = "CIS_Microsoft_Windows_10_Enterprise_Release_1709_Benchmark_v1.4.0.1-xccdf.xml" ' Custom
				Else
					'Benchmark = "CIS_Microsoft_Windows_10_Enterprise_Release_1709_Benchmark_v1.4.0-xccdf.xml" ' original
					Benchmark = "CIS_Microsoft_Windows_10_Enterprise_Release_1709_Benchmark_v1.4.0.1-xccdf.xml" ' Custom; Run against the highest benchmark we have avaiable from CIS, send out warning though.
					'Email sScript & " Status", "Found Windows 10 CB version = " & CBVer & ", which is greater than the CIS benchmark we have. Will run against the highest version so we have something. " & sMsg
				End If
			Else
				iErrCode = "999"
				If Not IsObject(DebugLog) Then Call CreateDebugLog("WriteLog")
				DebugLog.WriteLine(Now & "__ Script is not accounted for this assets OS, which was found to be: " & ProductName & ".")
				WSHLog "CriticalFailure", "Script is not accounted for this assets OS, which was found to be: " & ProductName & "."
			End If
		End If
		DebugLog.WriteLine(Now & "__ Determined the CIS-CAT benchmark we will run against this asset will be: " & Benchmark & ".")
		WSHLog "Information", "Determined the CIS-CAT benchmark we will run against this asset will be: " & Benchmark & "."
		Err.Clear

		Call GetBundleName
		Call DeleteOldBundle(sBN, "True")
		Err.Clear

		Dim sUnzip, f, f2, fc, fc2, sURL
		If Not oFSO.FolderExists(oProcessEnv("TEMP") & "\" & sBN) Then
			sUnzip = "Yes"
			oFSO.CreateFolder(oProcessEnv("TEMP") & "\" & sBN)
			If Err.Number = 0 Then
				DebugLog.WriteLine(Now & "__ Created directory " & oProcessEnv("TEMP") & "\" & sBN & " in preparation to unzip bundle into it.")
				WSHLog "Information", "Created directory " & oProcessEnv("TEMP") & "\" & sBN & " in preparation to unzip bundle into it."
			Else
				DebugLog.WriteLine(Now & "__ Failed to created directory " & oProcessEnv("TEMP") & "\" & sBN & " in preparation to unzip bundle into it.")
				WSHLog "CriticalFailure", "Failed to created directory " & oProcessEnv("TEMP") & "\" & sBN & " in preparation to unzip bundle into it."
			End If				
		Else
			If Not oFSO.FolderExists(oProcessEnv("TEMP") & "\" & sBN & "\cis-cat-full") Then
				sUnzip = "Yes"
				DebugLog.WriteLine(Now & "__ Found " & oProcessEnv("TEMP") & "\" & sBN & "\cis-cat-full missing will unzip entire bundle.")
				WSHLog "Information", "Found " & oProcessEnv("TEMP") & "\" & sBN & "\cis-cat-full missing will unzip entire bundle."
			Else
				Set f = oFSO.GetFolder(oProcessEnv("TEMP") & "\" & sBN & "\cis-cat-full")
				Set fc = f.Files
				If fc.Count < 3 Then sUnzip = "Yes" ' Maintain for future CIS-CAT versions
			End If
			If Not oFSO.FolderExists(oProcessEnv("TEMP") & "\" & sBN & "\" & JREVER) Then
				sUnzip = "Yes"
				DebugLog.WriteLine(Now & "__ Found " & oProcessEnv("TEMP") & "\" & sBN & "\" & JREVER & " missing will unzip entire bundle.")
				WSHLog "Information", "Found " & oProcessEnv("TEMP") & "\" & sBN & "\" & JREVER & " missing will unzip entire bundle."
			Else
				Set f2 = oFSO.GetFolder(oProcessEnv("TEMP") & "\" & sBN & "\" & JREVER)
				Set fc2 = f2.Files
				If fc2.Count < 7 Then sUnzip = "Yes" ' Maintain for future JRE versions
			End If

'			Set f = oFSO.GetFolder(oProcessEnv("TEMP") & "\" & sBN & "\cis-cat-full")
'			Set fc = f.Files
'			If fc.Count < 3 Then ' Maintain for future CIS-CAT versions
'				sUnzip = "Yes"
'			Else
'				Set f2 = oFSO.GetFolder(oProcessEnv("TEMP") & "\" & sBN & "\" & JREVER)
'				Set fc2 = f2.Files
'				If fc2.Count < 7 Then ' Maintain for future JRE versions
'					sUnzip = "Yes"
'				Else
			If Not sUnzip = "Yes" Then
					sUnzip = "No"
					DebugLog.WriteLine(Now & "__ Found current CIS-CAT bundle to already be unzipped and ready for usage.")
					WSHLog "Information", "Found current CIS-CAT bundle to already be unzipped and ready for usage."
				'End If
			End If
		End If

		Dim sCMD, iStat, iErrDesc
		If sUnzip = "Yes" Then 'execute unzip.exe on cis-cat-dissolvable.zip
			'unzip.exe -o -qq cis-cat-dissolvable.zip 'sBundle = "cis-cat-3.0.45-Wintel_jre64.zip"
			sCMD = oProcessEnv("TEMP") & "\" & "unzip.exe -o -qq " & oProcessEnv("TEMP") & "\" & BUNDLE & " -d " & oProcessEnv("TEMP") & "\" & sBN
			iStat = oShell.Run("cmd /c " & sCMD, 0, True)
			If iStat = 0 Then
				DebugLog.WriteLine(Now & "__ Successfully unzipped " & BUNDLE & " to " & oProcessEnv("TEMP") & "\" & sBN & ".")
				WSHLog "Information", "Successfully unzipped " & BUNDLE & " to " & oProcessEnv("TEMP") & "\" & sBN & "."
			Else
				iErrCode = iStat
				iErrDesc = CStr(iStat) & " " & Err.Description & "."
				DebugLog.WriteLine(Now & "__ Failed to unzip " & BUNDLE & " to " & oProcessEnv("TEMP") & "\" & sBN & ". Result code: " & iErrDesc)
				WSHLog "CriticalFailure", "Failed to unzip " & BUNDLE & " to " & oProcessEnv("TEMP") & "\" & sBN & ". Result code: " & iErrDesc
			End If
		End If

		sCMD = oProcessEnv("TEMP") & "\" & sBN & "\" & JREVER & "\bin\java.exe -Xmx768M -jar " & oProcessEnv("TEMP") & "\" & sBN & "\cis-cat-full\CISCAT.jar -a -s -arf -n -u " & CISCATAPIURL & " -b " & oProcessEnv("TEMP") & "\" & sBN & "\cis-cat-full\benchmarks\" & Benchmark & " -p " & Profiles & " -D ciscat.post.parameter.ccpd.token=" & TOKEN
		DebugLog.WriteLine(Now & "__ Executing " & sCMD & ".")
		iStat = oShell.Run("cmd /c " & sCMD, 0, True)
		If iStat = 0 Then
			DebugLog.WriteLine(Now & "__ Execution completed, exit code: " & iStat & ", total execution time: " & DateDiffToWords(vCT,Now))
			If (UCase(ENV) = "PROD") Then ' PROD ( For DEV & QA we dont limit how many times we can run a scan/export/)
				Dim sSetDate, sSetTime, sCSD, sCST
				sSetDate = vDate : sSetTime = vTime : Call Stamp		
				sCSD = sEngKey & "Scripts\CC\SetDate"
				sCST = sEngKey & "Scripts\CC\SetTime"
				If sFirst = "Yes" Then
					Email sScript & " CIS-CAT exection time", "Execution completed, exit code: " & iStat & ", total execution time for CIS-CAT scan/export: " & DateDiffToWords(vCT,Now) & " " & sMsg
				End If
				oShell.RegWrite sCSD, sSetDate, "REG_SZ"
				If Err.Number = 0 Then
					DebugLog.WriteLine(Now & "__ Created reg key " & sCSD & " with value of " & sSetDate)
				Else
					iErrCode = Err.Number
					iErrDesc = CStr(Err.Number) & " " & Err.Description & "."
					Call RegAlert(sCSD, sSetDate, iErrDesc)
				End If
				oShell.RegWrite sCST, sSetTime, "REG_SZ"
				If Err.Number = 0 Then
					DebugLog.WriteLine(Now & "__ Created reg key " & sCST & " with value of " & sSetTime)
				Else
					iErrCode = Err.Number
					iErrDesc = CStr(Err.Number) & " " & Err.Description & "."
					Call RegAlert(sCST, sSetDate, iErrDesc)
				End If
				If UCase(sInterval) = "MONTHLY" Then
					oShell.RegWrite sLRM, Month(Date), "REG_SZ"
					If Err.Number = 0 Then
						DebugLog.WriteLine(Now & "__ Created reg key " & sLRM & " with value of " & Month(Date))
					Else
						iErrCode = Err.Number
						iErrDesc = CStr(Err.Number) & " " & Err.Description & "."
						Call RegAlert(sLRM, Month(Date), iErrDesc)
					End If
				ElseIf UCase(sInterval) = "WEEKLY" Then
					oShell.RegWrite sLRW, DatePart("ww",Date), "REG_SZ"
					If Err.Number = 0 Then
						DebugLog.WriteLine(Now & "__ Created reg key " & sLRW & " with value of " & DatePart("ww",Date))
					Else
						iErrCode = Err.Number
						iErrDesc = CStr(Err.Number) & " " & Err.Description & "."
						Call RegAlert(sLRW, Month(Date), iErrDesc)
					End If
				End If
			End If
		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 "Warning", "Execution of " & sCMD & ", FAILED. Result code: " & iErrDesc
		End If
		iStat = Null
	End If
	On Error GoTo 0
End Function

' zip file containing CIS-CAT assessor package and x64 JRE 8
Function GetBundleName
	On Error Resume Next
	Dim oBundle, iErrDesc
	Set oBundle = oFSO.GetFile(oProcessEnv("TEMP") & "\" & BUNDLE)
	If Err.Number <> 0 Then
		iErrCode = Err.Number
		iErrDesc = CStr(Err.Number) & " " & Err.Description & "."
		DebugLog.WriteLine(Now & "__ Failed to find expected cis-cat source bundle " & BUNDLE & " to unzip at " & oProcessEnv("TEMP") & ". Result code: " & iErrDesc)
		WSHLog "CriticalFailure", "Failed to find expected cis-cat source bundle " & BUNDLE & " to unzip at " & oProcessEnv("TEMP") & ". Result code: " & iErrDesc
	End If
	sBN = oFSO.GetBaseName(oBundle)
	On Error GoTo 0
End Function 

' zip file containing CIS-CAT assessor package and x64 JRE 8 and folder with expanded content
Function DeleteOldBundle(sBundleFN, sPurge)
	On Error Resume Next
	Dim oFolder, cFolders, sFolder, iErrDesc, cFiles, sFile
	Set oFolder = oFSO.GetFolder(oProcessEnv("TEMP"))
	Set cFolders = oFolder.SubFolders
	For Each sFolder In cFolders
		If sFolder.Name = sBundleFN Then
			' Skip as this is the current one, will verify it has not be messed with later.
		ElseIf InStr(UCase(sFolder.Name), "CIS-CAT") Then
			If Not IsObject(DebugLog) Then Call CreateDebugLog("WriteLog")
			DebugLog.WriteLine(Now & "__ Found old bundle directory " & sFolder & ", proceeding to delete it and any of its content.") : Err.Clear
			oFSO.DeleteFolder sFolder, True ' Delete this old folder
			If Err.Number = 0 Then
				DebugLog.WriteLine(Now & "__ Successfully deleted this old bundle and any of its content.")
			Else
				iErrCode = Err.Number
				iErrDesc = CStr(Err.Number) & " " & Err.Description & "."
				If Not IsObject(DebugLog) Then Call CreateDebugLog("WriteLog")
				DebugLog.WriteLine(Now & "__ Failed to delete old bundle directory " & sFolder & ". Result code: " & iErrDesc)
				WSHLog "Warning", "Failed to delete old bundle directory " & sFolder & ". Result code: " & iErrDesc
			End If
		End If
	Next
	Err.Clear
	If sPurge = "True" Then
		Set cFiles = oFolder.Files
		For Each sFile In cFiles
			If UCase(sFile.Name) = UCase(sBundleFN) & ".ZIP" Then
				' Skip as this is the current zipped bundle
			ElseIf InStr(UCase(sFile.Name), "CIS-CAT") Then
				If Not IsObject(DebugLog) Then Call CreateDebugLog("WriteLog")
				DebugLog.WriteLine(Now & "__ Found old zip bundle " & sFile.Name & ", proceeding to delete it.")
				oFSO.DeleteFile sFile.Path, True ' Delete this old zip bundle
				If Err.Number = 0 Then
					DebugLog.WriteLine(Now & "__ Successfully deleted this old zip bundle.")
				Else
					iErrCode = Err.Number
					iErrDesc = CStr(Err.Number) & " " & Err.Description & "."
					If Not IsObject(DebugLog) Then Call CreateDebugLog("WriteLog")
					DebugLog.WriteLine(Now & "__ Failed to delete old zip bundle " & sFile.Name & ". Result code: " & iErrDesc)
					WSHLog "Warning", "Failed to delete old zip bundle " & sFile.Name & ". Result code: " & iErrDesc
				End If
			ElseIf sFile.Name = "cis-cat-3.0.47-Wintel_jre64.zip" Then
				If Not IsObject(DebugLog) Then Call CreateDebugLog("WriteLog")
				DebugLog.WriteLine(Now & "__ Found original old zip bundle " & sFile.Name & ", proceeding to delete it.")
				oFSO.DeleteFile sFile.Path, True ' Delete this original old zip bundle
				If Err.Number = 0 Then
					DebugLog.WriteLine(Now & "__ Successfully deleted this original old zip bundle.")
				Else
					iErrCode = Err.Number
					iErrDesc = CStr(Err.Number) & " " & Err.Description & "."
					If Not IsObject(DebugLog) Then Call CreateDebugLog("WriteLog")
					DebugLog.WriteLine(Now & "__ Failed to delete original old zip bundle " & sFile.Name & ". Result code: " & iErrDesc)
					WSHLog "Warning", "Failed to delete original old zip bundle " & sFile.Name & ". Result code: " & iErrDesc
				End If
			End If
		Next
	End If
	On Error GoTo 0
End Function

' Verify Internet connectivity to API Site
Function chkInternet(sHREF)
	On Error Resume Next
	Dim oXMLHTTP, iErrDesc, sDebugResponse
	sDebugResponse = "False"
	Set oXMLHTTP = CreateObject("msxml2.xmlhttp.6.0")
	If Err.Number <> 0 Then
		iErrCode = Err.Number
		iErrDesc = CStr(Err.Number) & " " & Err.Description & "."
		If Not IsObject(DebugLog) Then Call CreateDebugLog("WriteLog")
		DebugLog.WriteLine(Now & "__ Failed to initialize xmlhttp, but will continue.. Result code: " & iErrDesc)
		WSHLog "Warning", "Failed to initialize xmlhttp, but will continue. Result code: " & iErrDesc
	Else
		oXMLHTTP.Open "GET", sHREF, False
		oXMLHTTP.setRequestHeader "Content-type:", "text/xml"
		oXMLHTTP.setRequestHeader "Translate:", "f"
		oXMLHTTP.Send
		If Err.Number = 0 Then
			iStatus = oXMLHTTP.statustext 'iStatus = "Service Unavailable" for debug
			' check status  "Http/1.1 Service Unavailable" / "Bad Request" / "Forbidden" / "OK"
			If UCase(iStatus) <> "OK" Then
				If Not IsObject(DebugLog) Then Call CreateDebugLog("WriteLog")
				DebugLog.WriteLine(Now & "__ Response from " & sHREF & " = " & iStatus & " .")
				WSHLog "CriticalFailure", "Response from " & sHREF & " = " & iStatus & " . Exiting script..."
			Else
				If IsObject(DebugLog) Then DebugLog.WriteLine(Now & "__ Response from " & sHREF & " = " & iStatus & " .")
			End If
		Else
			iErrCode = Err.Number
			' do not use iStatus check here!
			If sDebugResponse = "True" Or IsServer = "True" Then
				If Not IsObject(DebugLog) Then Call CreateDebugLog("WriteLog")
				DebugLog.WriteLine(Now & "__ Failed to reach site " & sHREF & " . Exiting script...")
				WSHLog "CriticalFailure", "Failed to reach site " & sHREF & " . Exiting script..."
			ElseIf sDebugResponse = "True" Or InStr(address, "10.70.") Or InStr(address, "192.168.32.") Or InStr(address, "10.30.") Then
				If Not IsObject(DebugLog) Then Call CreateDebugLog("WriteLog") ' New
				DebugLog.WriteLine(Now & "__ Failed to reach site " & sHREF & " . Exiting script...") ' New
				WSHLog "CriticalFailure", "Failed to reach site " & sHREF & " . Exiting script..."	' New
			Else
				If IsObject(DebugLog) Then DebugLog.WriteLine(Now & "__ Failed to reach site " & sHREF & " . Exiting script...")
				If IsObject(DebugLog) Then DebugLog.WriteLine(Now & "__ Critical failure, exiting... Wrapper exit code : " & iErrCode)
				Call Cleanup(sScript & " - CriticalFailure", "Failed to reach site " & sHREF & " . Exiting script...| |" & sMsg)
				WScript.Quit(iErrCode)
			End If
		End If
	End If
	Set oXMLHTTP = Nothing
	On Error GoTo 0
End Function

Sub RegAlert(sRegPath, sValue, iErrDesc)
	DebugLog.WriteLine(Now & "__ Failed to create reg key " & sRegPath & " with value of " & sValue & ", Error code: " & iErrDesc)
	WSHLog "CriticalFailure", "Failed to create reg key " & sRegPath & " with value of " & sValue & ", Error code: " & iErrDesc
End Sub 

' Copy CIS-CAT bundle local (first time or if there is a change)
Function CopyCISCAT
	Dim sNLCS, sZip
	If IsServer = "True" Then
		If DC = "True" Then
			sNLCS = "\\" & sDomFQDN & "\netlogon\DC\CIS-CAT\" & CISCATVER & "\"
		Else ' All servers are x64
			sNLCS = "\\" & sDomFQDN & "\netlogon\Servers\CIS-CAT\" & CISCATVER & "\"
		End If
	Else ' Clients
		sNLCS = "\\" & sDomFQDN & "\netlogon\Clients\CIS-CAT\" & CISCATVER & "\"
	End If
	sZip = "unzip.exe"

	Call CheckFile(sNLCS, oProcessEnv("TEMP") & "\", sZip)
	Call CheckFile(sNLCS, oProcessEnv("TEMP") & "\", BUNDLE)
End Function

' Verify file has not change; if so then re-copy
Sub CheckFile(sSrcDir, sDestDir, sFile)
	On Error Resume Next
	Dim sCopy, sDebugFC, oDestFile, oDFVP, oDFVS, oDFVD, oSrcFile, oSFVP, oSFVS, oSFVD, sAltered, sReadOnly, vCT, iErrDesc
	sCopy = "0"
	If (UCase(ENV) = "PROD") Then
		sDebugFC = "False"
	Else ' DEV or QA
		sDebugFC = "True"
	End If
	If oFSO.FileExists(sDestDir & sFile) Then
		Set oDestFile = oFSO.GetFile(sDestDir & sFile)
		oDFVS = oDestFile.Size
		oDFVD = oDestFile.DateLastModified
		Set oSrcFile = oFSO.GetFile(sSrcDir & sFile)	
		oSFVS = oSrcFile.Size
		oSFVD = oSrcFile.DateLastModified
		If Not oDFVS = oSFVS Then
			sCopy = "1" ' Need new copy
			sAltered = "1" ' Found file size altered
		End If
		If Not oDFVD = oSFVD Then
			sCopy = "1" ' Need new Copy
			If sAltered = "1" Then
				sAltered = "3" ' Found file date modified & file size altered
			Else
				sAltered = "2" ' Found file date modified
			End If
		End If
	Else
		sCopy = "1" ' File does not exist on device, copy.
	End If

	If sCopy = "1" Then
		If oFSO.FileExists(sDestDir & sFile) Then
			Const ReadOnly = 1
			If oDestFile.Attributes AND ReadOnly Then ' Found to be marked as read-only
	    		oDestFile.Attributes = oDestFile.Attributes XOR ReadOnly
				sReadOnly = "True"
			End If
		End If
		vCT = Now
		Err.Clear
		oFSO.CopyFile sSrcDir & sFile, sDestDir & sFile, True
		If Err.Number <> 0 Then
			iErrCode = Err.Number
			iErrDesc = CStr(Err.Number) & " " & Err.Description & "."
			If sReadOnly = "True" Then
				If Not IsObject(DebugLog) Then Call CreateDebugLog("WriteLog")
				DebugLog.WriteLine(Now & "__ Could not copy: " & sSrcDir & sFile & " to: " & sDestDir & sFile & ",  Error # " & iErrDesc & ", Found file ReadOnly.")
				WSHLog "CriticalFailure", "Could not copy: " & sSrcDir & sFile & " to: " & sDestDir & sFile & ",  Error # " & iErrDesc & ", Found file ReadOnly."
			Else
				If Not IsObject(DebugLog) Then Call CreateDebugLog("WriteLog")
				DebugLog.WriteLine(Now & "__ Could not copy: " & sSrcDir & sFile & " to: " & sDestDir & sFile & ",  Error # " & iErrDesc & ".")
				WSHLog "CriticalFailure", "Could not copy: " & sSrcDir & sFile & " to: " & sDestDir & sFile & ",  Error # " & iErrDesc & "."
			End If
		Else
			If sAltered = "1" Then
				If Not IsObject(DebugLog) Then Call CreateDebugLog("WriteLog")
				If sReadOnly = "True" Then
					DebugLog.WriteLine(Now & "__ Found file " & sFile & " ReadOnly and file size altered from original. ||Local file specs:| Size: " & oDFVS & ", Date: " & oDFVD & ". |DC file specs:| Size: " & oSFVS & ", Date: " & oSFVD & ". ||Re-copied source file from: " & sSrcDir & " to: " & sDestDir & " ||Took: " & DateDiffToWords(vCT,Now) & ".")
					WSHLog "Information", "Found file " & sFile & " ReadOnly and file size altered from original. ||Local file specs:| Size: " & oDFVS & ", Date: " & oDFVD & ". |DC file specs:| Size: " & oSFVS & ", Date: " & oSFVD & ". ||Re-copied source file from: " & sSrcDir & " to: " & sDestDir & " ||Took: " & DateDiffToWords(vCT,Now) & "."
				Else
					DebugLog.WriteLine(Now & "__ Found file " & sFile & " file size altered from original. ||Local file specs:| Size: " & oDFVS & ", Date: " & oDFVD & ". |DC file specs:| Size: " & oSFVS & ", Date: " & oSFVD & ". ||Re-copied source file from: " & sSrcDir & " to: " & sDestDir & " ||Took: " & DateDiffToWords(vCT,Now) & ".")
					WSHLog "Information", "Found file " & sFile & " file size altered from original. ||Local file specs:| Size: " & oDFVS & ", Date: " & oDFVD & ". |DC file specs:| Size: " & oSFVS & ", Date: " & oSFVD & ". ||Re-copied source file from: " & sSrcDir & " to: " & sDestDir & " ||Took: " & DateDiffToWords(vCT,Now) & "."
				End If
				sPilot = "True"
			ElseIf sAltered = "2" Then
				If Not IsObject(DebugLog) Then Call CreateDebugLog("WriteLog")
				If sReadOnly = "True" Then
					DebugLog.WriteLine(Now & "__ Found file " & sFile & " ReadOnly and file date modified. ||Local file specs:| Size: " & oDFVS & ", Date: " & oDFVD & ". |DC file specs:| Size: " & oSFVS & ", Date: " & oSFVD & ". ||Re-copied source file from: " & sSrcDir & " to: " & sDestDir & " ||Took: " & DateDiffToWords(vCT,Now) & ".")
					WSHLog "Information", "Found file " & sFile & " ReadOnly and file date modified. ||Local file specs:| Size: " & oDFVS & ", Date: " & oDFVD & ". |DC file specs:| Size: " & oSFVS & ", Date: " & oSFVD & ". ||Re-copied source file from: " & sSrcDir & " to: " & sDestDir & " ||Took: " & DateDiffToWords(vCT,Now) & "."
				Else
					DebugLog.WriteLine(Now & "__ Found file " & sFile & " file date modified. ||Local file specs:| Size: " & oDFVS & ", Date: " & oDFVD & ". |DC file specs:| Size: " & oSFVS & ", Date: " & oSFVD & ". ||Re-copied source file from: " & sSrcDir & " to: " & sDestDir & " ||Took: " & DateDiffToWords(vCT,Now) & ".")
					WSHLog "Information", "Found file " & sFile & " file date modified. ||Local file specs:| Size: " & oDFVS & ", Date: " & oDFVD & ". |DC file specs:| Size: " & oSFVS & ", Date: " & oSFVD & ". ||Re-copied source file from: " & sSrcDir & " to: " & sDestDir & " ||Took: " & DateDiffToWords(vCT,Now) & "."
				End If
				sPilot = "True"
			ElseIf sAltered = "3" Then
				If Not IsObject(DebugLog) Then Call CreateDebugLog("WriteLog")
				If sReadOnly = "True" Then
					DebugLog.WriteLine(Now & "__ Found file " & sFile & " ReadOnly and file date modified and file size altered from original. ||Local file specs:| Size: " & oDFVS & ", Date: " & oDFVD & ". | DC file specs:| Size: " & oSFVS & ", Date: " & oSFVD & ". ||Re-copied source file from: " & sSrcDir & " to: " & sDestDir & " ||Took: " & DateDiffToWords(vCT,Now) & ".")
					WSHLog "Information", "Found file " & sFile & " file date modified and file size altered from original. ||Local file specs:| Size: " & oDFVS & ", Date: " & oDFVD & ". |DC file specs:| Size: " & oSFVS & ", Date: " & oSFVD & ". ||Re-copied source file from: " & sSrcDir & " to: " & sDestDir & " ||Took: " & DateDiffToWords(vCT,Now) & "."
				Else
					DebugLog.WriteLine(Now & "__ Found file " & sFile & " ReadOnly and file date modified and file size altered from original. ||Local file specs:| Size: " & oDFVS & ", Date: " & oDFVD & ". | DC file specs:| Size: " & oSFVS & ", Date: " & oSFVD & ". ||Re-copied source file from: " & sSrcDir & " to: " & sDestDir & " ||Took: " & DateDiffToWords(vCT,Now) & ".")
					WSHLog "Information", "Found file " & sFile & " file date modified and file size altered from original. ||Local file specs:| Size: " & oDFVS & ", Date: " & oDFVD & ". |DC file specs:| Size: " & oSFVS & ", Date: " & oSFVD & ". ||Re-copied source file from: " & sSrcDir & " to: " & sDestDir & " ||Took: " & DateDiffToWords(vCT,Now) & "."
				End If
				sPilot = "True"
			ElseIf sDebugFC = "True" Then
				If Not IsObject(DebugLog) Then Call CreateDebugLog("WriteLog")
				DebugLog.WriteLine(Now & "__ Found file " & sFile & " missing from device. ||Copied source file from: " & sSrcDir & " to: " & sDestDir & " ||Took: " & DateDiffToWords(vCT,Now) & ".")
				WSHLog "Information", "Found file " & sFile & " missing from device. ||Copied source file from: " & sSrcDir & " to: " & sDestDir & " ||Took: " & DateDiffToWords(vCT,Now) & "."
				sPilot = "True"
			End If
			If sFile = BUNDLE Then
				Call DeleteOldBundle("CIS-CAT-PURGE-ALL", "False")
			End If
		End If
		If oFSO.FolderExists(oProcessEnv("TEMP") & "\CIS") Then ' Cleanup legacy job
			oFSO.DeleteFolder oProcessEnv("TEMP") & "\CIS", True
			If Err.Number <> 0 Then
				iErrCode = Err.Number
				iErrDesc = CStr(Err.Number) & " " & Err.Description & "."
				If Not IsObject(DebugLog) Then Call CreateDebugLog("WriteLog")
				WSHLog "CriticalFailure", "Attempt to create Debuglog: " &  sDebugLog & ", failed. Error code: " & iErrDesc
			Else
				If IsObject(DebugLog) Then DebugLog.WriteLine(Now & "__ Found directory " & oProcessEnv("TEMP") & "\CIS, deleted it successfully.")
			End If
		End If
	Else
		If sDebug = "True" Then
			Email "File update not required", "File: " & sFile & " matches. ||Local file specs:| Size: " & oDFVS & ", Date: " & oDFVD & ". |DC file specs:| Size: " & oSFVS & ", Date: " & oSFVD & ".||" & sMsg
		End If
	End If
	On Error GoTo 0
End Sub

' Setup CIS-CAT assessor environment
Function Settings
	If UCase(ENV) = "DEV" Then
		CISCATURL = "https://ciscat-dashboard.dev.theorchard.io/CCPD/"
		TOKEN = "27l93r1fidunhl4t201b4tabkbltq8a7"
	ElseIf UCase(ENV) = "QA" Then
		CISCATURL = "https://qa-ciscat.theorchard.io/CCPD/"
		TOKEN = "18cbqm1vv8edb8eb7oc6191q54r8mm90"
	ElseIf UCase(ENV) = "PROD" Then
		CISCATURL = "https://ciscat.theorchard.io/CCPD/"
		TOKEN = "2mocf2e1hu5pbjnc00q7scjettvo37tv"
	Else
		iErrCode = "999"
		If Not IsObject(DebugLog) Then Call CreateDebugLog("WriteLog")
		DebugLog.WriteLine(Now & "__ Unknown argument specified: " & ENV & ".")
		WSHLog "CriticalFailure", "Unknown argument specified: " & ENV & "."
	End If
	BUNDLE = "cis-cat-" & CISCATVER & "-Wintel_" & JREVER & ".zip"
	CISCATAPIURL = CISCATURL & "api/reports/upload"
End Function

' Command line Parameters check
Function ParamCheck
	Dim sIssue, sTxt
	If Not(InStr(Ucase(WScript.FullName), "CSCRIPT")) <> 0 Then
		sIssue = "Yes"
		sTxt = "Script must be run with cscript."
	ElseIf WScript.Arguments.Count = 0 Then
		sIssue = "Yes"
		sTxt = "No arguments supplied."
	ElseIf  WScript.Arguments.Count > 1 Then
		sIssue = "Yes"
		sTxt = "Too many arguments supplied."
	End If
	If sIssue = "Yes" Then
		iErrCode = "999"
		If Not IsObject(DebugLog) Then Call CreateDebugLog("WriteLog")
		DebugLog.WriteLine(Now & "__ " & sTxt)
		WSHLog "CriticalFailure", sTxt
	End If
End Function

' ------   Wrapper 3.0.6 Functions/Subs section    -------

' 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

' 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

' Check if DC Function 
Function IsDC
	On Error Resume Next
	Dim DeviceInfo, oDomain
	Set DeviceInfo = oWMI.ExecQuery("SELECT DomainRole FROM Win32_ComputerSystem")
	If Err.Number = 0 Then
		For Each oDomain In DeviceInfo 
			If oDomain.DomainRole = 4 Or oDomain.DomainRole = 5 Then DC = "True"
		Next
	Else
		WSHLog "CriticalFailure", "Critical issue, could not connect to WMI, cimv2:Win32_ComputerSystem to obtain DomainRole information."
	End If
	Set DeviceInfo = Nothing
	On Error GoTo 0
End Function

' Read Registry Key/Values
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
		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
		sTicket = "True"
		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(iMSIVal) Or IsEmpty(iMSIVal)) Or iMSIVal = 0 Or iMSIVal = 1030) Then
			If IsObject(DebugLog) Then DebugLog.WriteLine(Now & "__ Critical failure, exiting... Wrapper exit code: " & iMSIVal)
			sPilot = "True" : sTicket = "True" ' Force attachment of debuglog since we have a critical failure
			Call Cleanup(sScript & " - " & EventType, Desc & "| |" & sMsg)
			WScript.Quit(iMSIVal)
		ElseIf 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 '' MIITbgYJKoZIhvcNAQcCoIITXzCCE1sCAQExCzAJBgUr
'' SIG '' DgMCGgUAMGcGCisGAQQBgjcCAQSgWTBXMDIGCisGAQQB
'' SIG '' gjcCAR4wJAIBAQQQTvApFpkntU2P5azhDxfrqwIBAAIB
'' SIG '' AAIBAAIBAAIBADAhMAkGBSsOAwIaBQAEFKNtoSL2wfEX
'' SIG '' MxpfnKcV6G0A+qOuoIIODDCCBBQwggL8oAMCAQICCwQA
'' SIG '' AAAAAS9O4VLXMA0GCSqGSIb3DQEBBQUAMFcxCzAJBgNV
'' SIG '' BAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNh
'' SIG '' MRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9i
'' SIG '' YWxTaWduIFJvb3QgQ0EwHhcNMTEwNDEzMTAwMDAwWhcN
'' SIG '' MjgwMTI4MTIwMDAwWjBSMQswCQYDVQQGEwJCRTEZMBcG
'' SIG '' A1UEChMQR2xvYmFsU2lnbiBudi1zYTEoMCYGA1UEAxMf
'' SIG '' R2xvYmFsU2lnbiBUaW1lc3RhbXBpbmcgQ0EgLSBHMjCC
'' SIG '' ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJTv
'' SIG '' Zfi1V5+gUw00BusJH7dHGGrL8Fvk/yelNNH3iRq/nrHN
'' SIG '' EkFuZtSBoIWLZFpGL5mgjXex4rxc3SLXamfQu+jKdN6L
'' SIG '' Tw2wUuWQW+tHDvHnn5wLkGU+F5YwRXJtOaEXNsq5oIwb
'' SIG '' TwgZ9oExrWEWpGLmtECew/z7lfb7tS6VgZjg78Xr2AJZ
'' SIG '' eHf3quNSa1CRKcX8982TZdJgYSLyBvsy3RZR+g79ijDw
'' SIG '' Fwmnu/MErquQ52zfeqn078RiJ19vmW04dKoRi9rfxxRM
'' SIG '' 6YWy7MJ9SiaP51a6puDPklOAdPQD7GiyYLyEIACDG6Hu
'' SIG '' tHQFwSmOYtBHsfrwU8wY+S47+XB+tCUCAwEAAaOB5TCB
'' SIG '' 4jAOBgNVHQ8BAf8EBAMCAQYwEgYDVR0TAQH/BAgwBgEB
'' SIG '' /wIBADAdBgNVHQ4EFgQURtg+/9zjvv+D5vSFm7DdatYU
'' SIG '' qcEwRwYDVR0gBEAwPjA8BgRVHSAAMDQwMgYIKwYBBQUH
'' SIG '' AgEWJmh0dHBzOi8vd3d3Lmdsb2JhbHNpZ24uY29tL3Jl
'' SIG '' cG9zaXRvcnkvMDMGA1UdHwQsMCowKKAmoCSGImh0dHA6
'' SIG '' Ly9jcmwuZ2xvYmFsc2lnbi5uZXQvcm9vdC5jcmwwHwYD
'' SIG '' VR0jBBgwFoAUYHtmGkUNl8qJUC99BM00qP/8/UswDQYJ
'' SIG '' KoZIhvcNAQEFBQADggEBAE5eVpAeRrTZSTHzuxc5KBvC
'' SIG '' Ft39QdwJBQSbb7KimtaZLkCZAFW16j+lIHbThjTUF8xV
'' SIG '' OseC7u+ourzYBp8VUN/NFntSOgLXGRr9r/B4XOBLxRjf
'' SIG '' OiQe2qy4qVgEAgcw27ASXv4xvvAESPTwcPg6XlaDzz37
'' SIG '' Dbz0xe2XnbnU26UnhOM4m4unNYZEIKQ7baRqC6GD/Sjr
'' SIG '' 2u8o9syIXfsKOwCr4CHr4i81bA+ONEWX66L3mTM1fsua
'' SIG '' irtFTec/n8LZivplsm7HfmX/6JLhLDGi97AnNkiPJm87
'' SIG '' 7k12H3nD5X+WNbwtDswBsI5//1GAgKeS1LNERmSMh08W
'' SIG '' YwcxS2Ow3/MwggSfMIIDh6ADAgECAhIRIdaZp2SXPvH4
'' SIG '' Qn7pGcxTQRQwDQYJKoZIhvcNAQEFBQAwUjELMAkGA1UE
'' SIG '' BhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2Ex
'' SIG '' KDAmBgNVBAMTH0dsb2JhbFNpZ24gVGltZXN0YW1waW5n
'' SIG '' IENBIC0gRzIwHhcNMTYwNTI0MDAwMDAwWhcNMjcwNjI0
'' SIG '' MDAwMDAwWjBgMQswCQYDVQQGEwJTRzEfMB0GA1UEChMW
'' SIG '' R01PIEdsb2JhbFNpZ24gUHRlIEx0ZDEwMC4GA1UEAxMn
'' SIG '' R2xvYmFsU2lnbiBUU0EgZm9yIE1TIEF1dGhlbnRpY29k
'' SIG '' ZSAtIEcyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
'' SIG '' CgKCAQEAsBeuotO2BDBWHlgPse1VpNZUy9j2czrsXV6r
'' SIG '' Jf02pfqEw2FAxUa1WVI7QqIuXxNiEKlb5nPWkiWxfSPj
'' SIG '' BrOHOg5D8NcAiVOiETFSKG5dQHI88gl3p0mSl9RskKB2
'' SIG '' p/243LOd8gdgLE9YmABr0xVU4Prd/4AsXximmP/Uq+yh
'' SIG '' RVmyLm9iXeDZGayLV5yoJivZF6UQ0kcIGnAsM4t/aIAq
'' SIG '' taFda92NAgIpA6p8N7u7KU49U5OzpvqP0liTFUy5LauA
'' SIG '' o6Ml+6/3CGSwekQPXBDXX2E3qk5r09JTJZ2Cc/os+XKw
'' SIG '' qRk5KlD6qdA8OsroW+/1X1H0+QrZlzXeaoXmIwRCrwID
'' SIG '' AQABo4IBXzCCAVswDgYDVR0PAQH/BAQDAgeAMEwGA1Ud
'' SIG '' IARFMEMwQQYJKwYBBAGgMgEeMDQwMgYIKwYBBQUHAgEW
'' SIG '' Jmh0dHBzOi8vd3d3Lmdsb2JhbHNpZ24uY29tL3JlcG9z
'' SIG '' aXRvcnkvMAkGA1UdEwQCMAAwFgYDVR0lAQH/BAwwCgYI
'' SIG '' KwYBBQUHAwgwQgYDVR0fBDswOTA3oDWgM4YxaHR0cDov
'' SIG '' L2NybC5nbG9iYWxzaWduLmNvbS9ncy9nc3RpbWVzdGFt
'' SIG '' cGluZ2cyLmNybDBUBggrBgEFBQcBAQRIMEYwRAYIKwYB
'' SIG '' BQUHMAKGOGh0dHA6Ly9zZWN1cmUuZ2xvYmFsc2lnbi5j
'' SIG '' b20vY2FjZXJ0L2dzdGltZXN0YW1waW5nZzIuY3J0MB0G
'' SIG '' A1UdDgQWBBTUooRKOFoYf7pPMFC9ndV6h9YJ9zAfBgNV
'' SIG '' HSMEGDAWgBRG2D7/3OO+/4Pm9IWbsN1q1hSpwTANBgkq
'' SIG '' hkiG9w0BAQUFAAOCAQEAj6kakW0EpjcgDoOW3iPTa24f
'' SIG '' bt1kPWghIrX4RzZpjuGlRcckoiK3KQnMVFquxrzNY46z
'' SIG '' PVBI5bTMrs2SjZ4oixNKEaq9o+/Tsjb8tKFyv22XY3mM
'' SIG '' RLxwL37zvN2CU6sa9uv6HJe8tjecpBwwvKu8LUc235Ig
'' SIG '' A+hxxlj2dQWaNPALWVqCRDSqgOQvhPZHXZbJtsrKnbem
'' SIG '' uuRQ09Q3uLogDtDTkipbxFm7oW3bPM5EncE4Kq3jjb3N
'' SIG '' CXcaEL5nCgI2ZIi5sxsm7ueeYMRGqLxhM2zPTrmcuWrw
'' SIG '' nzf+tT1PmtNN/94gjk6Xpv2fCbxNyhh2ybBNhVDygNId
'' SIG '' BvVYBAexGDCCBU0wggQ1oAMCAQICEAPq4x/DNeCiI9mC
'' SIG '' 5DlK/ZUwDQYJKoZIhvcNAQELBQAwcjELMAkGA1UEBhMC
'' SIG '' VVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UE
'' SIG '' CxMQd3d3LmRpZ2ljZXJ0LmNvbTExMC8GA1UEAxMoRGln
'' SIG '' aUNlcnQgU0hBMiBBc3N1cmVkIElEIENvZGUgU2lnbmlu
'' SIG '' ZyBDQTAeFw0xODAzMjIwMDAwMDBaFw0yMTAzMjUxMjAw
'' SIG '' MDBaMIGJMQswCQYDVQQGEwJVUzERMA8GA1UECBMITmV3
'' SIG '' IFlvcmsxETAPBgNVBAcTCE5ldyBZb3JrMSkwJwYDVQQK
'' SIG '' EyBUaGUgT3JjaGFyZCBFbnRlcnByaXNlcyBOWSwgSW5j
'' SIG '' LjEpMCcGA1UEAxMgVGhlIE9yY2hhcmQgRW50ZXJwcmlz
'' SIG '' ZXMgTlksIEluYy4wggEiMA0GCSqGSIb3DQEBAQUAA4IB
'' SIG '' DwAwggEKAoIBAQC+uBrLcB6HSH12Fw3iQk0wnrBMR/Xm
'' SIG '' yH+oInoXTnQhhGhTle6PWioUUp4b7K6v1o5t/7oqqeU1
'' SIG '' TlZhFrXw20wGa0X5B2U07eeRyB9jWMyeDalbWPazUlfo
'' SIG '' gmtiGnHUTbj1+MtjtnIb2eVv7umcNoi7qhPzJvVMDIyC
'' SIG '' J4OYi6pIfV+nVjuGizGK3Ep43fj8eM1rpvpF4qxsPt/8
'' SIG '' mGgcbZVKVPERkezu8PhnqsQq6BKp6ncq+BbKaolzwRcV
'' SIG '' i7ZZzmpsnRFKU6jE06s0ptBmUCl/7WY69qMdO0Tu4RNY
'' SIG '' ItuihrFaWL2WLdjPANvTFG2xL2DgIz4LEWgSUVOu4aSw
'' SIG '' g39XAgMBAAGjggHFMIIBwTAfBgNVHSMEGDAWgBRaxLl7
'' SIG '' KgqjpepxA8Bg+S32ZXUOWDAdBgNVHQ4EFgQUFWb1jhPM
'' SIG '' z9PmvFrOw3FSTHHXyswwDgYDVR0PAQH/BAQDAgeAMBMG
'' SIG '' A1UdJQQMMAoGCCsGAQUFBwMDMHcGA1UdHwRwMG4wNaAz
'' SIG '' oDGGL2h0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9zaGEy
'' SIG '' LWFzc3VyZWQtY3MtZzEuY3JsMDWgM6Axhi9odHRwOi8v
'' SIG '' Y3JsNC5kaWdpY2VydC5jb20vc2hhMi1hc3N1cmVkLWNz
'' SIG '' LWcxLmNybDBMBgNVHSAERTBDMDcGCWCGSAGG/WwDATAq
'' SIG '' MCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2Vy
'' SIG '' dC5jb20vQ1BTMAgGBmeBDAEEATCBhAYIKwYBBQUHAQEE
'' SIG '' eDB2MCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdp
'' SIG '' Y2VydC5jb20wTgYIKwYBBQUHMAKGQmh0dHA6Ly9jYWNl
'' SIG '' cnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFNIQTJBc3N1
'' SIG '' cmVkSURDb2RlU2lnbmluZ0NBLmNydDAMBgNVHRMBAf8E
'' SIG '' AjAAMA0GCSqGSIb3DQEBCwUAA4IBAQAgdQ4jSO4z+O79
'' SIG '' 4AlCpzGIOmn8XT2WTDPXg5b5lPg3Z22YMQ5JHmRzWXax
'' SIG '' mxFAhD8kCSPGhL+MfIJMZt9hTbdM8WUinqKLNvbVDiIK
'' SIG '' O1H9Vnwz5VJ03qGRExixZOiULeeNDmj6kh4KcqFtzio0
'' SIG '' M/4GARMYiwyBg1CNlD59Jvz3RzFZugm3K+yXU1JlznMJ
'' SIG '' 8QoY0MWHsiHV/nJssNnMWCpvR7S0wC5pSn3DXeS7XVma
'' SIG '' SAc3xavwCg5sJG3LS2LKwx12ksbj+mfz+t2RqQIE5iFz
'' SIG '' 81EVhK7qbF8cbRKhgtcqbCjqr3dsj4lfMpe/+OcXR7DI
'' SIG '' wWGGyquVUv0vqiaTph2zMYIEzjCCBMoCAQEwgYYwcjEL
'' SIG '' MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IElu
'' SIG '' YzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTExMC8G
'' SIG '' A1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElEIENv
'' SIG '' ZGUgU2lnbmluZyBDQQIQA+rjH8M14KIj2YLkOUr9lTAJ
'' SIG '' BgUrDgMCGgUAoHgwGAYKKwYBBAGCNwIBDDEKMAigAoAA
'' SIG '' oQKAADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAc
'' SIG '' BgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAjBgkq
'' SIG '' hkiG9w0BCQQxFgQUB7XUuC9EsYEgt0m3wfWpuZNhepUw
'' SIG '' DQYJKoZIhvcNAQEBBQAEggEAPrmVMAsxtBg8sQ6DwIDL
'' SIG '' vjHxvTbdCho/MnGi6eJP+zTEKjCNxz8g7o1v5qvvvZjq
'' SIG '' aswp6vsTJiyyppB3yWAZCqkNVtQuAT9RUy/Gna9l4VTX
'' SIG '' ODBxBvSl4FBkJDTVvZ2H7B5DtdCnTcCqD5tKA8K3dZZj
'' SIG '' 9xj+sCwTRjiY2uUS4AlB/YsCb9RF0BviFD2QPo1HEMG8
'' SIG '' IwaCOVtxDxFtS+bYI/CQGs2UZlR+TwndQBxYiD9Mgw5p
'' SIG '' Zbcq2tKfv844sii2hSSHM3nhoktzf7kgSyvQLcKH4Ek2
'' SIG '' h2TonLEq4IuBSff2qez2N9jSSnjy4WHa0ztBo07l4Co8
'' SIG '' dekWU6ZFzsjJxaGCAqIwggKeBgkqhkiG9w0BCQYxggKP
'' SIG '' MIICiwIBATBoMFIxCzAJBgNVBAYTAkJFMRkwFwYDVQQK
'' SIG '' ExBHbG9iYWxTaWduIG52LXNhMSgwJgYDVQQDEx9HbG9i
'' SIG '' YWxTaWduIFRpbWVzdGFtcGluZyBDQSAtIEcyAhIRIdaZ
'' SIG '' p2SXPvH4Qn7pGcxTQRQwCQYFKw4DAhoFAKCB/TAYBgkq
'' SIG '' hkiG9w0BCQMxCwYJKoZIhvcNAQcBMBwGCSqGSIb3DQEJ
'' SIG '' BTEPFw0yMDA2MzAyMTM3MzJaMCMGCSqGSIb3DQEJBDEW
'' SIG '' BBSvI/nDD3t5CjiEkKkfyHMgIPQoNDCBnQYLKoZIhvcN
'' SIG '' AQkQAgwxgY0wgYowgYcwgYQEFGO4L6th9YOQlpUFCwAk
'' SIG '' nFApM+x5MGwwVqRUMFIxCzAJBgNVBAYTAkJFMRkwFwYD
'' SIG '' VQQKExBHbG9iYWxTaWduIG52LXNhMSgwJgYDVQQDEx9H
'' SIG '' bG9iYWxTaWduIFRpbWVzdGFtcGluZyBDQSAtIEcyAhIR
'' SIG '' IdaZp2SXPvH4Qn7pGcxTQRQwDQYJKoZIhvcNAQEBBQAE
'' SIG '' ggEANqZYuS7+gpRbFTuuD+hPdol9Mzhg9XtOT9eRfCTa
'' SIG '' 5SbcNVinD8BP1T9ttyNidQeM2+UaTY2SbeXnD6DtheIj
'' SIG '' 2hoLJ7cnbHyb+h+Zd5jJbf69qbq4KZ9MZT25+TS7qvGK
'' SIG '' JJQTWc+Du3GEvyLfXBIQBNiStLzqHxM81EPhACKeyUha
'' SIG '' Uqrv0AkU042QCsH3oL+XogEXrcRaVMRNjGHOPlaTPWeU
'' SIG '' wM6VCEF1dWXbx7qLWfOfpyJRTnXzL895rxBDLi7a48JH
'' SIG '' NCXdtLKWIC6EMUX1TO2SnQtlmXZNcfkT3mSDm3Ubymvp
'' SIG '' LUYSvJ3TmNuedlWj/95wszPIl5/2ftdKc/TzJA==
'' SIG '' End signature block
