File: C:/Windows/OEM/Utility.vbs
Option Explicit
Const TemporaryFolder = 2
Const ForReading = 1
Const ERROR_NORESOURCEDRIVE = 7
Const ERROR_PROTOCOLVIOLATION = 4
Dim ERROR_FILE_NOT_FOUND : ERROR_FILE_NOT_FOUND = &H80070002&
Const KVP_REGISTRY_KEY_PATH = "SOFTWARE\Microsoft\Virtual Machine\Guest"
Const CURRENTVERSION_REGISTRY_KEY_PATH = "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion"
Const AZURE_PROVISIONING_KEY_PATH = "HKEY_LOCAL_MACHINE\SYSTEM\Setup\AzureProvisioning"
Dim WshShell : Set WshShell = CreateObject("WScript.Shell")
Function GetSystemRegistry(strValueName)
On Error Resume Next
Dim valueName : valueName = CURRENTVERSION_REGISTRY_KEY_PATH & "\" & strValueName
Dim strValue : strValue = WshShell.RegRead(valueName)
GetSystemRegistry = strValue
End Function
Function GetOSCurrentBuildNumber
GetOSCurrentBuildNumber = GetSystemRegistry("CurrentBuildNumber")
End Function
Function GetOSBuildLabEx
GetOSBuildLabEx = GetSystemRegistry("BuildLabEx")
End Function
Function GetOSProductName
GetOSProductName = GetSystemRegistry("ProductName")
End Function
Function GetOSCurrentVersion
GetOSCurrentVersion = GetSystemRegistry("CurrentVersion")
End Function
Function GetOSCurrentMajorVersionNumber
GetOSCurrentMajorVersionNumber = GetSystemRegistry("CurrentMajorVersionNumber")
If Err.Number <> 0 Then
Err.Clear
Dim Version : Version = GetOSCurrentVersion
If Err.Number = 0 Then
Dim arr : arr = Split(Version, ".")
GetOSCurrentMajorVersionNumber = arr(0)
End If
End If
End Function
Function GetOSCurrentMinorVersionNumber
GetOSCurrentMinorVersionNumber = GetSystemRegistry("CurrentMinorVersionNumber")
If Err.Number <> 0 Then
Err.Clear
Dim Version : Version = GetOSCurrentVersion
If Err.Number = 0 Then
Dim arr : arr = Split(Version, ".")
If UBound(arr) > 0 Then
GetOSCurrentMinorVersionNumber = arr(1)
End If
End If
End If
End Function
Function GetOSVersion
Dim majorVersion : majorVersion = GetOSCurrentMajorVersionNumber
Dim minorVersion : minorVersion = GetOSCurrentMinorVersionNumber
Dim buildNumber : buildNumber = GetOSCurrentBuildNumber
GetOSVersion = majorVersion & "." & minorVersion & "." & buildNumber
End Function
' execute the given command, collecting the results to an object
Function ExecuteWithResults(strCommand)
Dim oResults, oExec, exitLoop
Set oResults = new ExecResults
oResults.StdOut = ""
oResults.StdErr = ""
oResults.ExitCode = Null
exitLoop = False
Set oExec = WshShell.Exec(strCommand)
Do
oResults.StdOut = oResults.StdOut & oExec.StdOut.ReadAll()
oResults.StdErr = oResults.StdErr & oExec.StdErr.ReadAll()
WScript.Sleep 10
Loop While oExec.Status = 0 _
Or Not oExec.StdOut.AtEndOfStream _
Or Not oExec.StdErr.AtEndOfStream
oResults.ExitCode = oExec.ExitCode
Set ExecuteWithResults = oResults
End Function
Function ExecuteAndTraceWithResults(strCommand, tracer)
Set ExecuteAndTraceWithResults = ExecuteAndTraceWithResultsWithErrorSuppression(strCommand, tracer, False)
End Function
Function ExecuteAndTraceWithResultsWithErrorSuppression(strCommand, tracer, suppressError)
Dim oResults, commandElem, outputElem, errOutputElem, eventType, oTraceEvent
' log before executing command to capture command execution duration in wall time
Set oTraceEvent = tracer.CreateEvent("INFO")
Set commandElem = oTraceEvent.ownerDocument.CreateElement("ExecutingCommand")
commandElem.appendChild(oTraceEvent.ownerDocument.CreateTextNode(strCommand))
With oTraceEvent.appendChild(oTraceEvent.ownerDocument.CreateElement("ExecuteAndTraceWithResults"))
.appendChild(commandElem)
End With
tracer.TraceEvent oTraceEvent
Set oResults = ExecuteWithResults(strCommand)
Set ExecuteAndTraceWithResultsWithErrorSuppression = oResults
If oResults.ExitCode = 0 Or suppressError = True Then
eventType = "INFO"
Else
eventType = "ERROR"
End If
Set oTraceEvent = tracer.CreateEvent(eventType)
Set outputElem = oTraceEvent.ownerDocument.CreateElement("Output")
If Not IsNull(oResults.StdOut) Then outputElem.appendChild(oTraceEvent.ownerDocument.CreateTextNode(CStr(oResults.StdOut)))
Set errOutputElem = oTraceEvent.ownerDocument.CreateElement("ErrorOutput")
If Not IsNull(oResults.StdErr) Then errOutputElem.appendChild(oTraceEvent.ownerDocument.CreateTextNode(CStr(oResults.StdErr)))
With oTraceEvent.appendChild(oTraceEvent.ownerDocument.CreateElement("ExecuteAndTraceWithResults"))
.setAttribute "ExitCode", oResults.ExitCode
.appendChild(outputElem)
.appendChild(errOutputElem)
End With
tracer.TraceEvent oTraceEvent
End Function
Function GetWinPAVersion(WshShell, FSO)
Dim waGuestExePath
waGuestExePath = WshShell.ExpandEnvironmentStrings("%SystemRoot%")
waGuestExePath = FSO.BuildPath(waGuestExePath, "\OEM\WaGuest.exe")
If (FSO.FileExists(waGuestExePath)) Then
GetWinPAVersion = FSO.GetFileVersion(waGuestExePath)
Else
GetWinPAVersion = "0.0.0"
End If
End Function
Class ExecResults
Dim StdOut
Dim StdErr
Dim ExitCode
End Class
Function CreateTempFile(FSO)
Dim folder, file
Set folder = FSO.GetSpecialFolder(TemporaryFolder)
file = FSO.GetTempName
CreateTempFile = FSO.BuildPath(folder, file)
End Function
Private Function ReadTempFile(FSO, file)
Dim stream
Dim str
str = Null
Set stream = FSO.OpenTextFile(file, ForReading, False)
If Not stream.AtEndOfStream Then
str = stream.ReadAll()
End If
stream.Close
FSO.DeleteFile file
ReadTempFile = str
End Function
Function GetScriptObject(WScript, scriptPath, componentId)
Dim FSO, scriptDir
Set FSO = CreateObject("Scripting.FileSystemObject")
scriptDir = FSO.GetParentFolderName(WScript.ScriptFullName)
Set GetScriptObject = GetObject("script:" & FSO.BuildPath(scriptDir, scriptPath) & "#" & componentId)
End Function
Function TraceError(objTrace, message)
TraceError = TraceErrorAs("ERROR", objTrace, message, True)
End Function
Function TraceErrorWithoutClear(objTrace, message)
TraceErrorWithoutClear = TraceErrorAs("ERROR", objTrace, message, False)
End Function
Function TraceErrorAs(eventType, objTrace, message, clearError)
Dim oTraceEvent
TraceErrorAs = Err.number
If Err.number <> 0 Then
Set oTraceEvent = objTrace.CreateEvent(eventType)
With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("UnhandledError"))
With .appendChild(oTraceEvent.ownerDocument.createElement("Message"))
.text = message
End With
With .appendChild(oTraceEvent.ownerDocument.createElement("Number"))
.text = Err.number
End With
With .appendChild(oTraceEvent.ownerDocument.createElement("Description"))
.text = Err.Description
End With
With .appendChild(oTraceEvent.ownerDocument.createElement("Source"))
.text = Err.Source
End With
End With
objTrace.TraceEvent oTraceEvent
If clearError = True Then
Err.Clear
End If
End If
End Function
Sub LogDebug(objTrace, name, message)
Log objTrace, "DEBUG", name, message
End Sub
Sub LogInfo(objTrace, name, message)
Log objTrace, "INFO", name, message
End Sub
Sub LogWarn(objTrace, name, message)
Log objTrace, "WARN", name, message
End Sub
Sub LogError(objTrace, name, message)
Log objTrace, "ERROR", name, message
End Sub
Sub Log(objTrace, level, name, message)
Dim oTraceEvent : Set oTraceEvent = objTrace.CreateEvent(level)
With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement(name))
.text = message
End With
objTrace.TraceEvent oTraceEvent
End Sub
Function LeftPad(strText, intLen, chrPad)
'LeftPad( "1234", 7, "x" ) = "xxx1234"
'LeftPad( "1234", 3, "x" ) = "234"
LeftPad = Right( String( intLen, chrPad ) & strText, intLen )
End Function
' by first trying to get the drive letter by device path and then trying to get
' the drive letter by volume label (to support GPT)
Function GetResourceDrive(tracer)
Dim oResults, cachedDrive
cachedDrive = GetRegistryValue(tracer, AZURE_PROVISIONING_KEY_PATH, "ResourceDrive", "REG_SZ", True)
If IsNull(cachedDrive) Then
Set oResults = ExecuteAndTraceWithResults("%SystemRoot%\OEM\FindVolume.exe /path \device\Harddisk1\Partition1", tracer)
If oResults.ExitCode <> 0 Then
Set oResults = ExecuteAndTraceWithResults("%SystemRoot%\OEM\FindVolume.exe /label ""Temporary Storage"" ", tracer)
If oResults.ExitCode <> 0 Then
'unknown failure
Err.Raise vbObjectError + ERROR_NORESOURCEDRIVE, "Utility.vbs", "Failed to locate the resource drive as expected"
End If
End If
cachedDrive = Trim(Replace(oResults.StdOut, vbCrLf, ""))
SetRegistryValue tracer, AZURE_PROVISIONING_KEY_PATH, "ResourceDrive", "REG_SZ", cachedDrive, True
End If
GetResourceDrive = cachedDrive
End Function
Sub SetCacheValue(tracer, name, regType, value)
SetRegistryValue tracer, AZURE_PROVISIONING_KEY_PATH, name, regType, value, True
End Sub
Function GetCacheValue(tracer, name, regType)
GetCacheValue = GetRegistryValue(tracer, AZURE_PROVISIONING_KEY_PATH, name, regType, True)
End Function
' Get Kvp registry value
Function GetKvpRegistry(strValueName)
On Error Resume Next
Dim valueName : valueName = "HKEY_LOCAL_MACHINE\" & KVP_REGISTRY_KEY_PATH & "\" & strValueName
Dim strValue : strValue = WshShell.RegRead(valueName)
GetKvpRegistry = strValue
End Function
' Set Kvp registry
Sub SetKvpRegistry(strValueName, strValue, tracer)
On Error Resume Next
Dim valueName : valueName = "HKEY_LOCAL_MACHINE\" & KVP_REGISTRY_KEY_PATH & "\" & strValueName
WshShell.RegWrite valueName, strValue, "REG_SZ"
If TraceError(tracer, "SetKvpRegistry: Set registry " & strValueName & " failed. Registry value should be: " & strValue) = 0 Then
TraceKvpStatus tracer, strValueName, "INFO", strValue, "SetKvpRegistry"
End If
End Sub
' Trace Kvp status
Sub TraceKvpStatus(tracer, kvpRegistry, strEvent, strStatus, strElementName)
Dim oTraceEvent : Set oTraceEvent = tracer.CreateEvent(strEvent)
With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement(strElementName))
With .appendChild(oTraceEvent.ownerDocument.createElement(kvpRegistry))
.setAttribute "Message", strStatus
End With
End With
tracer.TraceEvent oTraceEvent
End Sub
Class HttpRequest
Public verb
Public url
Public headers
' request timeout values, in milliseconds
Public resolveTimeout
Public connectTimeout
Public sendTimeout
Public receiveTimeout
Private Sub Class_Initialize
verb = Null
url = Null
Set headers = Nothing
resolveTimeout = 0
connectTimeout = 10*1000
sendTimeout = 30*1000
receiveTimeout = 30*1000
End Sub
Private Sub Class_Terminate
End Sub
End Class
' Documentation for Msxml2.ServerXMLHTTP.3.0 timeouts: https://msdn.microsoft.com/en-us/library/ms760403(v=vs.85).aspx
'
' timeout argument values are in seconds
Function CreateHttpRequest(verb, url, headers, resolveTimeout, connectTimeout, sendTimeout, receiveTimeout, tracer)
Dim http
Set http = New HttpRequest
http.verb = verb
http.url = url
http.resolveTimeout = resolveTimeout*1000
http.connectTimeout = connectTimeout*1000
http.sendTimeout = sendTimeout*1000
http.receiveTimeout = receiveTimeout*1000
If Not (IsNull(headers) Or IsEmpty(headers) Or (headers Is Nothing)) Then
Set http.headers = headers
End If
Set oTraceEvent = tracer.CreateEvent("INFO")
With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("HttpRequest"))
.setAttribute "verb", verb
.setAttribute "url", url
End With
tracer.TraceEvent oTraceEvent
Set CreateHttpRequest = http
End Function
Function IsRetriableHr(hr)
' Client HTTP library error codes that should be retried.
Const ERROR_INTERNET_CONNECTION_ABORTED = &H80072EFE&
Const ERROR_TIMEOUT = &H800705B4&
Const ERROR_INTERNET_TIMEOUT = &H80072EE2&
Const ERROR_INTERNET_CANNOT_CONNECT = &H80072EFD&
Const ERROR_INTERNET_NAME_NOT_RESOLVED = &H80072EE7&
Const ERROR_INTERNET_CONNECTION_RESET = &H80032EFF&
Const ERROR_WINHTTP_INVALID_SERVER_RESPONSE = &H80072F78&
If hr >= 0 Then
IsRetriableHr = False 'SUCCESS HRESULTs do not need retrying
Else
Select Case hr
Case ERROR_INTERNET_CONNECTION_ABORTED, _
ERROR_TIMEOUT, _
ERROR_INTERNET_TIMEOUT, _
ERROR_INTERNET_CANNOT_CONNECT, _
ERROR_INTERNET_NAME_NOT_RESOLVED, _
ERROR_INTERNET_CONNECTION_RESET, _
ERROR_WINHTTP_INVALID_SERVER_RESPONSE
IsRetriableHr = True
Case Else
IsRetriableHr = False
End Select
End If
End Function
Sub TraceResponse(http, tracer, isXml)
Dim oTraceEvent
Set oTraceEvent = tracer.CreateEvent("INFO")
Dim httpResponse : Set httpResponse = oTraceEvent.ownerDocument.createElement("HttpResponse")
httpResponse.setAttribute "statusCode", http.status
If http.status = 200 Then
Dim responseBody
Set responseBody = oTraceEvent.ownerDocument.createElement("ResponseBody")
If isXml Then
Dim node, xml
Set xml = http.responseXml
If (Not xml Is Nothing) And (Not xml.documentElement Is Nothing) Then
Set node = xml.documentElement.cloneNode(true)
responseBody.appendChild(node)
End If
Else
responseBody.Text = http.responseText
End If
httpResponse.appendChild(responseBody)
End If
oTraceEvent.appendChild(httpResponse)
tracer.TraceEvent oTraceEvent
End Sub
Class RoleCertificate
Public name
Public tmpFile
Public thumbprint
Public storeName
Public storeLocation
Private Sub Class_Initialize
tmpFile = Null
thumbprint = Null
storeName = Null
storeLocation = Null
End Sub
Private Sub Class_Terminate
End Sub
End Class
Class OfflinedFeatures
Private Sub Class_Initialize
Tag = ""
Flags = 0
End Sub
Private Sub Class_Terminate
End Sub
Public Tag
Public Flags
End Class
Function BuildExecuteString(callerName, procName, procArgStr, isFunction, returnValueIsObj)
Dim executeString : executeString = procName & "(" & procArgStr & ")"
If isFunction = True Then
executeString = callerName & " = " & executeString
If returnValueIsObj = True Then
executeString = "Set " & executeString
End If
Else
executeString = "Call " & executeString
End If
BuildExecuteString = executeString
End Function
Function InstrumentProcedure(procName, procArgStr, isFunction, returnValueIsObj, kvpKeyName, tracer)
Dim offlinedFlags
Dim executeString, executeArgs
Set offlinedFlags = New OfflinedFeatures
executeArgs = "procName, procArgStr, isFunction, returnValueIsObj, kvpKeyName, tracer, 0, offlinedFlags"
executeString = BuildExecuteString("InstrumentProcedure", "InstrumentProcedureWithOfflinedFeatures", executeArgs, isFunction, returnValueIsObj)
Execute executeString
End Function
' Profiles a procedure's execution (subroutine or function), capturing its execution time and error code
' via the KVP channel under the specified registry KVP key name
' Value of the KVP entry is "Called=<call-time>;Returned=<return-time>;ErrorCode=<error-code>"
Function InstrumentProcedureWithOfflinedFeatures(procName, procArgStr, isFunction, returnValueIsObj, kvpKeyName, tracer, procFlag, offlinedFlags)
Dim procRef, executeString
Dim procErrorCode, procErrorMsg, procErrorSrc
Dim callTime, returnTime
Dim kvpValue, oTraceEvent
Dim isOfflined, origProcName
On Error Resume Next
origProcName = procName
isOfflined = (procFlag <> 0) And ((procFlag And offlinedFlags.Flags) = procFlag)
If isOfflined = True And isFunction = True Then
procName = procName & "Offlined"
End If
' Verify that the referred-to procedure exists
Set procRef = GetRef(procName)
If TraceError(tracer, "InstrumentProcedureWithOfflinedFeatures: Failed to obtain reference to procedure '" & procName & "'") <> 0 Then
Exit Function
End If
' Build-up execution string
executeString = BuildExecuteString("InstrumentProcedureWithOfflinedFeatures", procName, procArgStr, isFunction, returnValueIsObj)
' Capture current time in UTC before procedure is executed
callTime = tracer.GetCurrentTime()
procErrorCode = 0
If isFunction = True Or isOfflined <> True Then
Execute executeString
' Capture any error that occurs during execution so it can be returned to the caller
procErrorCode = Err.Number
End If
If isOfflined = True Then
Set oTraceEvent = tracer.CreateEvent("INFO")
With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("ProcedureOfflined"))
.setAttribute "Procedure", origProcName
.setAttribute "Flag", procFlag
End With
tracer.TraceEvent oTraceEvent
End If
If procErrorCode <> 0 Then
procErrorMsg = Err.Description
procErrorSrc = Err.Source
TraceError tracer, "InstrumentProcedureWithOfflinedFeatures: Failed to execute '" & executeString & "'. Will raise error to caller"
End If
' Capture current time in UTC now that procedure has returned
returnTime = tracer.GetCurrentTime()
' Generate and capture value in KVP channel
kvpValue = "Called=" & callTime & ";Returned=" & returnTime & ";ErrorCode=" & procErrorCode
SetKvpRegistry kvpKeyName, kvpValue, tracer
' If an error occurred during procedure execution, raise it for the caller
If procErrorCode <> 0 Then
Err.Raise procErrorCode, procErrorSrc, procErrorMsg
End If
End Function
' This function executes a RegWrite and sets the data of the specified key and value
' When the RegType is REG_MULTI_SZ, it uses REG ADD to set the value
' For REG_MULTI_SZ, the data input is an array of values
' For REG_DWORD and REG_QWORD, the data input is a long
' For all else the data input is a string (no support for BINARY yet)
Sub SetRegistryValue(objTrace, key, value, regType, data, suppressError)
On Error Resume Next
Dim oTraceEvent, registryValueString
Dim lError, traceCategory, displayString
Err.Clear
If regType = "REG_MULTI_SZ" Then
Dim strCommand, line, oResults, escapedData, strData
strData = Join(data, "\0")
escapedData = EscapeBatch(strData)
strCommand = "REG ADD " & QuoteString(key) _
& " /v " & QuoteString(value) _
& " /t " & regType _
& " /d " & QuoteString(escapedData) _
& " /f"
Set oResults = ExecuteAndTraceWithResultsWithErrorSuppression(strCommand, objTrace, suppressError)
lError = oResults.ExitCode
displayString = Join(data, "\0")
Else
WshShell.RegWrite key & "\" & value, data, regType
lError = Err.Number
displayString = data
End If
If suppressError = True Or lError = 0 Then
traceCategory = "INFO"
Else
traceCategory = "ERROR"
End If
registryValueString = "key: " & key & ", value: " & value & ", type: " & regType & ", data: " & displayString
Set oTraceEvent = objTrace.CreateEvent(traceCategory)
With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("SetRegistryValue"))
.Text = registryValueString
If lError <> 0 Then
.setAttribute "Error", lError
End If
End With
objTrace.TraceEvent oTraceEvent
End Sub
' This function executes a RegRead and returns the data of the specified key and value
' For REG_MULTI_SZ, the output is an array of values
' For REG_DWORD and REG_QWORD, the output is a long
' For all else the output is a string (no support for BINARY yet)
Function GetRegistryValue(objTrace, key, value, regType, suppressError)
On Error Resume Next
Dim oTraceEvent, registryValueString
Dim lError, traceCategory, displayString
Dim arr
GetRegistryValue = Null
Err.Clear
If regType = "REG_MULTI_SZ" Then
arr = WshShell.RegRead(key & "\" & value)
lError = Err.Number
If Not IsNull(arr) Then
displayString = Join(arr, "\0")
End If
GetRegistryValue = arr
Else
GetRegistryValue = WshShell.RegRead(key & "\" & value)
lError = Err.Number
displayString = CStr(GetRegistryValue)
End If
' Clear errors for non-existent registries
Err.Clear
If suppressError = True Or lError = 0 Then
traceCategory = "INFO"
Else
traceCategory = "ERROR"
End If
Set oTraceEvent = objTrace.CreateEvent(traceCategory)
With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("GetRegistryValue"))
If lError = ERROR_FILE_NOT_FOUND Then
.Text = "Failed to find registry value " & key & "\" & value
ElseIf lError <> 0 Then
.Text = "Failed to read registry value " & key & "\" & value
Else
registryValueString = "key: " & key & ", value: " & value & ", data: " & displayString
.Text = registryValueString
End If
End With
objTrace.TraceEvent oTraceEvent
End Function
' This function executes a RegDelete command for the specified registry key.
Sub DeleteRegistry(objTrace, registryPath, registryKeyName, suppressError)
Dim oTraceEvent, traceType
On Error Resume Next
If IsNull(registryKeyName) Or Len(registryKeyName) = 0 Then
WshShell.RegDelete registryPath & "\"
Else
WshShell.RegDelete registryPath & "\" & registryKeyName
End If
If Err.Number = 0 Then
Set oTraceEvent = objTrace.CreateEvent("INFO")
With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("DeleteRegistry"))
.Text = "path: " & registryPath & ", key name: " & registryKeyName
End With
objTrace.TraceEvent oTraceEvent
Else
If suppressError = True Then
traceType = "INFO"
Else
traceType = "ERROR"
End If
TraceErrorAs traceType, objTrace, "DeleteRegistry: Failed to delete key '" & registryPath & "\" & registryKeyName & "'.", True
End If
End Sub
Function EscapeBatch(str)
EscapeBatch = Replace(str, "%", "%%")
EscapeBatch = Replace(EscapeBatch, "^", "^^")
EscapeBatch = Replace(EscapeBatch, "&", "^&")
EscapeBatch = Replace(EscapeBatch, "<", "^<")
EscapeBatch = Replace(EscapeBatch, ">", "^>")
EscapeBatch = Replace(EscapeBatch, "|", "^|")
End Function
Function EscapeXml(str)
EscapeXml = Replace(str, "&", "&")
EscapeXml = Replace(EscapeXml, """", """)
EscapeXml = Replace(EscapeXml, "'", "'")
EscapeXml = Replace(EscapeXml, "<", "<")
EscapeXml = Replace(EscapeXml, ">", ">")
End Function
Function QuoteString(str)
QuoteString = """" & CStr(str) & """"
End Function
Function BoolToString(bool)
If bool = True Then
BoolToString = "True"
Else
BoolToString = "False"
End If
End Function
Function GetNumberOfLogicalProcessors
On Error Resume Next
GetNumberOfLogicalProcessors = WshShell.Environment("PROCESS").Item("NUMBER_OF_PROCESSORS")
End Function
Function IsValidFileName(str)
Dim oRegExp
If IsNull(str) Or IsEmpty(str) Then
IsValidFileName = False
Else
Set oRegExp = New RegExp
oRegExp.Pattern = "^[\x20\x21\x23\x24\x26-\x29\x2B-\x2E\x30-\x39\x3B\x3D\x40-\x5B\x5D-\x7B\x7D-\xFF]{1,255}$"
oRegExp.IgnoreCase = True
IsValidFileName = oRegExp.Test(str)
End If
End Function
' Writes networking data (ipconfig, route, arp) to log via paramterized Tracing object
Sub LogNetworkingData(tracer)
Dim configurationPass : configurationPass = Me.WScript.Arguments.Named("ConfigurationPass")
Dim kvp_cmd_ipconfig : kvp_cmd_ipconfig = configurationPass & "_PA_cmd_ipconfig"
Dim kvp_cmd_route : kvp_cmd_route = configurationPass & "_PA_cmd_route"
Dim kvp_cmd_arp : kvp_cmd_arp = configurationPass & "_PA_cmd_arp"
Dim kvp_cmd_sc_dhcp : kvp_cmd_sc_dhcp = configurationPass & "_PA_cmd_sc_dhcp"
ExecuteAndTraceWithResults "ipconfig.exe /all", tracer
SetKvpRegistry kvp_cmd_ipconfig, "[" & g_Trace.GetCurrentTime() & "] ipconfig.exe /all", g_Trace
ExecuteAndTraceWithResults "route.exe print", tracer
SetKvpRegistry kvp_cmd_route, "[" & g_Trace.GetCurrentTime() & "] route.exe print", g_Trace
ExecuteAndTraceWithResults "arp.exe /a", tracer
SetKvpRegistry kvp_cmd_arp, "[" & g_Trace.GetCurrentTime() & "] arp.exe /a", g_Trace
ExecuteAndTraceWithResults "sc.exe query dhcp", tracer
SetKvpRegistry kvp_cmd_sc_dhcp, "[" & g_Trace.GetCurrentTime() & "] sc.exe query dhcp", g_Trace
End Sub