'==========================================================================
'
' NAME: Script-Gather-DataCollect-M-R1.vbs
'
' AUTHOR:  Max Erenburg
' DATE  : 12/18/2018
'
' COMMENT: Collects build data and moves it off host to central location for review, build/deploy documentation.
' Update 05/11/2020 move to new hosts at both Datacenters and FQDN for the hostnames (added code to generate tickets as it@theorchard.com on failures detected as well)
' Update 06/25/2020 DEV version to allow testing and not generate tickets (adjust email function v2)
'==========================================================================

Option Explicit

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

Dim oShell, oFSO, oProcessEnv, sScript, iErrCode, sMsg
Dim 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
Dim sSkip, sDeployDir

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

Const DEPLOYNAME = "Gather-DataCollect"
Const SIDE = "-M"
Const RELEASE = "-R1-DEV"
sScript = "Script-" & DEPLOYNAME & SIDE & RELEASE

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 of installations leave as True
sPilot = "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"
sDeployDir = sLogDir & "\Deploy"

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

' 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

' 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 "Warning", sWMIMsgBody2
End If

' Determine if we have anything to do
Call Determine

If Not sSkip = "Yes" Then
	' Move setup folder to MDT server for use in documentation
	Call MoveData
	sPilot = "True"
End If

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

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

Function Determine
	On Error Resume Next 
	Dim sCount, sLT
	If NOT oFSO.FolderExists(sDeployDir) Then
		sSkip = "Yes"
		Exit Function
	Else		
		sLT = oProcessEnv("SystemDrive") & "\MININT\SCRIPTS\LiteTouch.wsf"
		If oFSO.FileExists(sLT) Then
			sSkip = "Yes"
			Exit Function
		Else
			If PBV = "Non-Corp" Then
				'sDeployDir = sLogDir & "\Deploy" ' for Debug un-remark
				sSkip = "Yes" ' remark for debug
				Exit Function
			ElseIf PTV = "No value" Then
				sSkip = "Yes"
				Exit Function
			Else
				If Not IsObject(DebugLog) Then Call CreateDebugLog("WriteLog")
				With oFSO.GetFolder(sDeployDir)
					sCount = .Files.Count
					If sCount > 0 Then ' SRV 7 + Sub Folder
						sSkip = "No"
						'DebugLog.WriteLine(Now & "__ Found " & sCount & " files exist in " & sDeployDir & ".")
					Else
						DebugLog.WriteLine(Now & "__ Found directory " & sDeployDir & " but with no files in it?")
						Email "Warning", "Found directory " & sDeployDir & " but with no files in it? " & sMsg
						sSkip = "Yes"
					End If
				End With
			End If
		End If
	End If
	On Error GoTo 0
End Function

' Move setup folder to MDT server for use in documentation
Function MoveData
	On Error Resume Next
	Dim sNYCSRV, sAVLSRV, sShare, sSrvShare
	sNYCSRV = "PROD-T1-BISSELL"
	sAVLSRV = "PROD-T1-HOOVER" ' sAVLSRV = "DRSTR17"
	sShare =  "BUILD_DATA$"
	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")
		DebugLog.WriteLine(Now & "__ Will not attempt to to move data, as we detected an unknown FQDN Domain name: " & sDomFQDN & ".")
		WSHLog "CriticalFailure", "Will not attempt to to move data, as we detected an unknown FQDN Domain name: " & sDomFQDN & "."
		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

	Dim sNetLoc, sADM, sADMTmp, sADMsms, sDEng, sDDeploy, sPanther, sUnGC, sEvtDir, sTemp, sTMPdeploy, sTMPsms
	Call Stamp : If Not IsObject(DebugLog) Then Call CreateDebugLog("WriteLog")
	sNetLoc = sSrvShare & oProcessEnv("COMPUTERNAME") & "_BV" & PBV & "_BTSV" & PTV & "_" & altDate & "-" & altTime : Call CR8FLD(sNetLoc)
	sADM = sNetLoc & "\ADM_Profile" : Call CR8FLD(sADM)
	sADMTmp = sNetLoc & "\ADM_Profile\Temp" : Call CR8FLD(sADMTmp)
	sADMsms = sADMTmp & "\SMSTSLog" : Call CR8FLD(sADMsms)
 	sDEng = sNetLoc & "\EngLogs" : Call CR8FLD(sDEng)
	sDDeploy =  sDEng & "\Deploy" : Call CR8FLD(sDDeploy)
	sPanther = sNetLoc & "\panther" : Call CR8FLD(sPanther)
	sUnGC = sPanther & "\UnattendGC" : Call CR8FLD(sUnGC)
 	sEvtDir = sDDeploy & "\winevt_logs" : Call CR8FLD(sEvtDir)
	sTemp = sNetLoc & "\System_Temp_Dir" : Call CR8FLD(sTemp)
	sTMPdeploy = sTemp & "\DeploymentLogs" : Call CR8FLD(sTMPdeploy)
	sTMPsms = sTemp & "\SMSTSLog" : Call CR8FLD(sTMPsms)

	Call CopyFile(oProcessEnv("SystemDrive") & "\Users\Administrator\AppData\Local\Temp\smsts.log", sADMTmp & "\smsts.log", "Yes")
	Call CopyFiles(oProcessEnv("SystemDrive") & "\Users\Administrator\AppData\Local\Temp\SMSTSLog\", sADMsms & "\", "Yes")
	Call CopyFile(oProcessEnv("SYSTEMROOT") & "\panther\setupact.log", sPanther & "\setupact.log", "No")
	Call CopyFile(oProcessEnv("SYSTEMROOT") & "\panther\setuperr.log", sPanther & "\setuperr.log", "No")
	Call CopyFile(oProcessEnv("SYSTEMROOT") & "\panther\unattend.xml", sPanther & "\unattend.xml", "Yes")
	Call CopyFiles(oProcessEnv("SYSTEMROOT") & "\panther\UnattendGC\", sUnGC & "\", "No")
	Call CopyFiles(oProcessEnv("SYSTEMROOT") & "\Temp\DeploymentLogs\", sTemp & "\DeploymentLogs" & "\", "Yes")
	Call CopyFiles(oProcessEnv("SYSTEMROOT") & "\Temp\SMSTSLog\", sTMPsms & "\", "Yes")
	Call CopyFile(oProcessEnv("SYSTEMROOT") & "\Temp\bcdtest.txt", sTemp & "\bcdtest.txt", "Yes")
	Call CopyFile(oProcessEnv("SYSTEMROOT") & "\Temp\Results.xml", sTemp & "\Results.xml", "Yes")

	' Copy Deployment script logs up to MDT
	'DebugLog.WriteLine(Now & "__ Proceeding to move last logs from root of " & sDeployDir)
	Call CopyFiles(sDeployDir & "\", sDDeploy & "\", "Yes")
	
	' Copy up all event logs to MDT - DO NOT DELETE these files
	Call CopyFiles(oProcessEnv("SYSTEMROOT") & "\System32\winevt\Logs\", sEvtDir & "\", "No")

	' Cleanup MDT bug
	Call DeleteFile(oProcessEnv("SYSTEMROOT") & "\authtest.txt")

	On Error GoTo 0
End Function

Function CR8FLD(sFolder)
	On Error Resume Next
	Dim iErrDesc
	If Not oFSO.FolderExists(sFolder) Then
		oFSO.CreateFolder(sFolder)
		If Err.Number <> 0 Then
			iErrCode = Err.Number
			iErrDesc = CStr(Err.Number) & " " & Err.Description & "."
			DebugLog.WriteLine(Now & "__ Failed to create directory " & sFolder & ", Error code: " & iErrDesc)
			WSHLog "CriticalFailure", "Failed to create directory " & sFolder & ", Error code: " & iErrDesc
		Else
			DebugLog.WriteLine(Now & "__ Created directory " & sFolder & ", successfully.")
		End If
	Else
		DebugLog.WriteLine(Now & "__ Found directory " & sFolder & " already exists?")
	End If
	On Error GoTo 0
End Function

'Copy flat file up to share
Function CopyFile(sSrcFile, sDestFile, sCleanup)
	On Error Resume Next
	Dim iErrDesc
    If oFSO.FileExists(sSrcFile) Then
        'WScript.Sleep 500
		oFSO.CopyFile sSrcFile, sDestFile, True
		If Err.Number <> 0 Then
			iErrCode = Err.Number
			iErrDesc = CStr(Err.Number) & " " & Err.Description & "."
			DebugLog.WriteLine(Now & "__ Failed to copy " & sSrcFile & " to " & sDestFile & ", Error code: " & iErrDesc)
			WSHLog "CriticalFailure", "Failed to copy " & sSrcFile & " to " & sDestFile & ", Error code: " & iErrDesc
		Else
			DebugLog.WriteLine(Now & "__ Copied " & sSrcFile & " to " & sDestFile & ", successfully.")
		End If
	Else
		DebugLog.WriteLine(Now & "__ File " & sSrcFile & " was not found, skipping copy.")
		Exit Function
	End If
	If UCase(sCleanup) = "YES" Then Call DeleteFile(sSrcFile)
	On Error GoTo 0
End Function

Function DeleteFile(sFile)
	On Error Resume Next
	Dim iErrDesc
    If oFSO.FileExists(sFile) Then
        WScript.Sleep 500
		oFSO.DeleteFile sFile, True
		If Err.Number <> 0 Then
			iErrCode = Err.Number
			iErrDesc = CStr(Err.Number) & " " & Err.Description & "."
			DebugLog.WriteLine(Now & "__ Failed to delete " & sFile & ", Error code: " & iErrDesc)
			WSHLog "CriticalFailure", "Failed to delete " & sFile & ", Error code: " & iErrDesc
		Else
			DebugLog.WriteLine(Now & "__ Deleted " & sFile & ", successfully.")
		End If
	Else
		DebugLog.WriteLine(Now & "__ File " & sFile & " was not found to delete?, skipping.")
	End If
	On Error GoTo 0
End Function

' Copy flat files up to share
Function CopyFiles(sSrcDir, sDestDir, sCleanup)
	On Error Resume Next
	Dim oFolder, cFileList, File, sFile, sDestDirQ, iErrDesc, cSubFolders, SubFolder, NewSrc, NewDest
	'Dim sDebug : If sDebug = "True" Then MsgBox "Source root we are working with: " & sSrcDir
	If Right(sSrcDir, 1) = "\" Then
		If Not oFSO.FolderExists(Left(sSrcDir, Len(sSrcDir) - 1)) Then
			DebugLog.WriteLine(Now & "__ Directory " & sSrcDir & " does not exist?")
			Exit Function
		End If
	Else
		If Not oFSO.FolderExists(sSrcDir) Then
			DebugLog.WriteLine(Now & "__ Directory " & sSrcDir & " does not exist?")
			Exit Function
		End If
	End If		
	Set oFolder = oFSO.GetFolder(sSrcDir)
	Set cFileList = oFolder.Files
	If cFileList.Count > 0 Then
		DebugLog.WriteLine(Now & "__ Found " & cFileList.Count & " file(s) to copy over.")
		For Each File In cFileList
			sFile = sSrcDir & File.Name
			sDestDirQ = Chr(34) & sDestDir & File.Name & Chr(34)
            If Not oFSO.FileExists(sDestDirQ) Then
                'WScript.Sleep 500
                DebugLog.WriteLine(Now & "__ About to start copy of " & sFile & " over to " & sDestDir) '####################################### DEBUG
				oFSO.CopyFile sFile, sDestDir, True
				If Err.Number <> 0 Then
					iErrCode = Err.Number
					iErrDesc = CStr(Err.Number) & " " & Err.Description & "."
					DebugLog.WriteLine(Now & "__ Failed to copy " & sFile & " to " & sDestDir & ", Error code: " & iErrDesc)
					WSHLog "CriticalFailure", "Failed to copy " & sFile & " to " & sDestDir & ", Error code: " & iErrDesc
				Else
					DebugLog.WriteLine(Now & "__ Copied " & sFile & " to " & sDestDir & ", successfully.")
				End If
			Else
				DebugLog.WriteLine(Now & "__ File " & File.Name & " already found exists in " & sDestDir & ", skipping")
			End If
		Next
	End If
	Set cFileList = Nothing

    Set cSubFolders = oFolder.SubFolders
	If cSubFolders.Count > 0 Then
        DebugLog.WriteLine(Now & "__ moving to subfolders: " & cSubFolders.Count) '####################################### DEBUG
        For Each SubFolder In cSubFolders
			NewSrc = sSrcDir & SubFolder.Name & "\"
			NewDest = sDestDir & SubFolder.Name & "\"
			If Not oFSO.FolderExists(Left(NewDest, Len(NewDest) - 1)) Then
				oFSO.CreateFolder(NewDest)
				If Err.Number <> 0 Then
					iErrCode = Err.Number
					iErrDesc = CStr(Err.Number) & " " & Err.Description & "."
					DebugLog.WriteLine(Now & "__ Failed to create directory " & NewDest & ", Error code: " & iErrDesc)
					WSHLog "CriticalFailure", "Failed to create directory " & NewDest & ", Error code: " & iErrDesc
				Else
					DebugLog.WriteLine(Now & "__ Created directory " & NewDest & ".")
				End If
			End If
			Call CopyFiles(NewSrc, NewDest, "No")
		Next
	End If
	Set cSubFolders = Nothing
	Set oFolder = Nothing
	On Error GoTo 0
	If UCase(sCleanup) = "YES" Then Call CleanupFiles(sSrcDir)
End Function

' Delete file and setup directory
Function CleanupFiles(sFolder)
	On Error Resume Next
	Dim oFile, oFolder, iErrDesc
	If Right(sFolder, 1) = "\" Then
		If Not oFSO.FolderExists(Left(sFolder, Len(sFolder) - 1)) Then
			DebugLog.WriteLine(Now & "__ Directory " & sFolder & " does not exist?")
			Exit Function
		End If
	Else
		If Not oFSO.FolderExists(sFolder) Then
			DebugLog.WriteLine(Now & "__ Directory " & sFolder & " does not exist?")
			Exit Function
		End If
	End If		
	With oFSO.GetFolder(sFolder)
		For Each oFile In .Files
			oFile.Delete
			If Err.Number <> 0 Then
				iErrCode = Err.Number
				iErrDesc = CStr(Err.Number) & " " & Err.Description & "."
				DebugLog.WriteLine(Now & "__ Failed to deleted file " & oFile.Name & ", Error code: " & iErrDesc)
				WSHLog "CriticalFailure", "Failed to deleted file " & oFile.Name & ", Error code: " & iErrDesc
'			Else
				'DebugLog.WriteLine(Now & "__ Deleted file " & oFile.Name & ".")
			End If
		Next
		If Err.Number = 0 Then
			DebugLog.WriteLine(Now & "__ Successfully purged all file(s) in " & sFolder & ".")
		End If

		For Each oFolder In .SubFolders
			CleanupFiles oFolder.Path
		Next
		Err.Clear
		' Checked every file and subfolder. If this folder is empty, remove it...
		If .Files.Count = 0 Then
			If .SubFolders.Count = 0 Then
				.Delete
				If Err.Number <> 0 Then
					iErrCode = Err.Number
					iErrDesc = CStr(Err.Number) & " " & Err.Description & "."
					DebugLog.WriteLine(Now & "__ Failed to deleted " & sFolder & ", Error code: " & iErrDesc)
					WSHLog "CriticalFailure", "Failed to delete " & sFolder & ", Error code: " & iErrDesc
				Else
					DebugLog.WriteLine(Now & "__ Deleted " & sFolder & ".")
				End If
			End If
		End If
	End With
	On Error GoTo 0
End Function


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


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

' 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

' 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

' 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 sScript & " - " & 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 sScript & " - " & 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 '' MIITbgYJKoZIhvcNAQcCoIITXzCCE1sCAQExCzAJBgUr
'' SIG '' DgMCGgUAMGcGCisGAQQBgjcCAQSgWTBXMDIGCisGAQQB
'' SIG '' gjcCAR4wJAIBAQQQTvApFpkntU2P5azhDxfrqwIBAAIB
'' SIG '' AAIBAAIBAAIBADAhMAkGBSsOAwIaBQAEFC47bKoKvqJW
'' SIG '' IZmpE/OWZ8/q0pjqoIIODDCCBBQwggL8oAMCAQICCwQA
'' 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 '' hkiG9w0BCQQxFgQUByxhZFYd78ViNEd0Sellyz59kAow
'' SIG '' DQYJKoZIhvcNAQEBBQAEggEANpmO+HQjnaIdp5jGcTB4
'' SIG '' RqzTlXi02QnrgdaGkxnd3Mxb1y6GeLmjYYjc9N4dEA0R
'' SIG '' 6kYvV/rFsihTCkMOcbBdcA7Dgmt6J05/lqaHj10LrVJq
'' SIG '' 65tdQCRbOGm8c9DU9f1eWZ3Cc31voYulS6LHrLCXj2cV
'' SIG '' HlZnqJKe6m/JmPOc1gS8ttKuHrrloJzPHHtfq3RaRKVO
'' SIG '' iAO97z5lLXsx5NkAInYQpzkXCcbnQRlOCmYnRk4jZitj
'' SIG '' CaERhOFmUw9WTgiAEldBe8t432yQamzelPdas7nPsuVX
'' SIG '' lImUZMGUfN5rRplhsP5Q+gLMjxBWj1XUmh3nNUdjNLc5
'' SIG '' HMjw4ztT7YnkGKGCAqIwggKeBgkqhkiG9w0BCQYxggKP
'' SIG '' MIICiwIBATBoMFIxCzAJBgNVBAYTAkJFMRkwFwYDVQQK
'' SIG '' ExBHbG9iYWxTaWduIG52LXNhMSgwJgYDVQQDEx9HbG9i
'' SIG '' YWxTaWduIFRpbWVzdGFtcGluZyBDQSAtIEcyAhIRIdaZ
'' SIG '' p2SXPvH4Qn7pGcxTQRQwCQYFKw4DAhoFAKCB/TAYBgkq
'' SIG '' hkiG9w0BCQMxCwYJKoZIhvcNAQcBMBwGCSqGSIb3DQEJ
'' SIG '' BTEPFw0yMDA3MDIyMDEwMjFaMCMGCSqGSIb3DQEJBDEW
'' SIG '' BBQHpZdsDNT8AzBcYZvnGpBCiJkC0jCBnQYLKoZIhvcN
'' SIG '' AQkQAgwxgY0wgYowgYcwgYQEFGO4L6th9YOQlpUFCwAk
'' SIG '' nFApM+x5MGwwVqRUMFIxCzAJBgNVBAYTAkJFMRkwFwYD
'' SIG '' VQQKExBHbG9iYWxTaWduIG52LXNhMSgwJgYDVQQDEx9H
'' SIG '' bG9iYWxTaWduIFRpbWVzdGFtcGluZyBDQSAtIEcyAhIR
'' SIG '' IdaZp2SXPvH4Qn7pGcxTQRQwDQYJKoZIhvcNAQEBBQAE
'' SIG '' ggEAXaHamnh96jMIQXUKkDKKHoHZnmK81OufKePEDUxJ
'' SIG '' cDbk3bspgMWBzox4dgGhMeaXAXq6Jhm+/9sTeNPVcErl
'' SIG '' cbHoDgmmL9pjhhFMV5xp0xCJDAIOhUCkewi9MGqDvcDa
'' SIG '' 79lstNGp1PVg+vHunJbw6po81WfsvJpjY1H7oEV0tQtI
'' SIG '' SELJC9kEpIMIl1A6spVySzdHUNuM9Twamx7N/pNVjG+B
'' SIG '' PGhRFDf0md3Ppm9p9DVqoe+JXQ9aqGgxxjC3jVPMlETg
'' SIG '' Nqsg0TeizALStdS8YnDqJRBzrYJ185HwtgpCdzJliUHN
'' SIG '' xKQnusClD9A5u1wjnbIe8nNrgXCLdAZ/lReGMQ==
'' SIG '' End signature block
