Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ' // ***************************************************************************
- ' //
- ' // Copyright (c) Microsoft Corporation. All rights reserved.
- ' //
- ' // Microsoft Deployment Toolkit Solution Accelerator
- ' //
- ' // File: ZTIUtility.vbs
- ' //
- ' // Version: 6.3.8443.1000
- ' //
- ' // Purpose: Common Libraries for Microsoft Deployment Toolkit
- ' //
- ' // ***************************************************************************
- Option Explicit
- ' Public constants
- Public Const ForReading = 1
- Public Const ForWriting = 2
- Public Const ForAppending = 8
- Public Const Success = 0
- Public Const Failure = 1
- Public Const LogTypeInfo = 1
- Public Const LogTypeWarning = 2
- Public Const LogTypeError = 3
- Public Const LogTypeVerbose = 4
- Public Const LogTypeDeprecated = 5
- Public Const TextCompare = 1
- Public Const adOpenStatic = 3
- Public Const adLockReadOnly = 1
- Public Const adLockOptimistic = 3
- Public Const Version = "6.3.8443.1000"
- ' Global variables
- Dim oShell, oEnv, oNetwork, oFSO, objWMI, oDrive
- Dim oUtility, oLogging, oEnvironment
- Dim oStrings
- Dim oFileHandling
- ' Initialization code
- On Error Resume Next
- Set oUtility = New Utility
- oUtility.PrepareEnvironment
- function PrnErrValue ( iError )
- PrnErrValue = oLogging.FormatError ( iError )
- end function
- Sub ProcessResults(iRc)
- ProcessResults = oLogging.ProcessResults ( iRc )
- End Sub
- function RunNewInstance
- Dim oScriptClass
- RunNewInstance = oUtility.RunNewInstanceEx ( oUtility.ScriptName, "oScriptClass", "oScriptClass.Main" )
- end function
- Function TestAndLog ( iRc , sMessage)
- TestAndLog = oLogging.TRACEEX(iRc, "", sMessage, FALSE)
- End function
- Function TestAndFail ( iRc, iError, sMessage)
- TestAndFail = oLogging.TRACEEX(iRc, iError, sMessage, TRUE)
- End function
- '//---------------------------------------------------------------------------
- '// Function: ConvertBooleanToString()
- '// Purpose: Perform a Cstr operation manually to prevent localization
- '// from converting True/False to non-english values.
- '//---------------------------------------------------------------------------
- Function ConvertBooleanToString(bValue)
- ConvertBooleanToString = oUtility.ConvertBooleanToString(bValue)
- End Function
- ' Public classes
- ' //////////////////////////////////////////////////////
- class Logging
- ' //
- ' // Logging is a public class used for trace logging within the BDD/MDT scripting Environment
- ' //
- ' // Assumes: oUtility, oEnvironment, oFSO - Must be initialized and active.
- ' //
- ' *** Public variables ***
- Public LogFile
- Public MasterLogFile
- Public Component
- Public Debug
- Public NetworkLogging
- ' *** Private variables ***
- ' *** Constructor and destructor ***
- Private Sub Class_Initialize
- ' Set file names and paths
- Component = oUtility.ScriptName
- LogFile = Component & ".log"
- MasterLogFile = "BDD.log"
- NetworkLogging = ""
- ' Set debug to false, allow PrepareEnvironment to override
- Debug = False
- End Sub
- ' *** Public methods ***
- ' //
- ' // Standard MDT logging routine, used for most logging operations
- ' //
- ' // Standard Error Types
- ' // Public Const LogTypeInfo = 1 ' Informational Message
- ' // Public Const LogTypeWarning = 2 ' Warning Message
- ' // Public Const LogTypeError = 3 ' Error Message
- ' // Public Const LogTypeVerbose = 4 ' Verbose Messages only logged when Debug has been set.
- ' // Public Const LogTypeDeprecated = 5 ' Informational Message that is elevated to Error when Debug is set.
- ' //
- Public Function CreateEntry(sLogMsg, iType)
- Dim sTime, sDate, sTempMsg, oLog, bConsole
- ' Each of the operations below has the potential to cause a runtime error.
- ' However, we must not stop operation if there is a failure, so allways continue.
- On Error Resume Next
- ' Special Handling for Debug vs. Non-Debug messages
- If not Debug then
- If iType = LogTypeVerbose Then
- Exit Function ' Verbose Messages are only displayed when Debug = True
- Elseif iType = LogTypeDeprecated Then
- iType = LogTypeInfo ' Deprecated messages are normally Info messages
- End if
- Else ' Debug = True
- If iType = LogTypeVerbose then
- iType = LogTypeInfo
- Elseif iType = LogTypeDeprecated Then
- iType = LogTypeError
- End if
- End if
- ' Suppress messages containing password
- If Instr(1, sLogMsg, "password", 1) > 0 then
- sLogMsg = "<Message containing password has been suppressed>"
- End if
- ' Populate the variables to log
- sTime = Right("0" & Hour(Now), 2) & ":" & Right("0" & Minute(Now), 2) & ":" & Right("0" & Second(Now), 2) & ".000+000"
- sDate = Right("0"& Month(Now), 2) & "-" & Right("0" & Day(Now), 2) & "-" & Year(Now)
- sTempMsg = "<![LOG[" & sLogMsg & "]LOG]!><time=""" & sTime & """ date=""" & sDate & """ component=""" & Component & """ context="""" type=""" & iType & """ thread="""" file=""" & oUtility.ScriptName & """>"
- ' Make sure the LogPath directory exists
- oUtility.VerifyPathExistsEx LogPath, False
- ' If debug, echo the message
- bConsole = InStr(1,Wscript.FullName,"CSCRIPT.EXE", vbTextCompare ) <> 0
- If bConsole = True then
- Wscript.echo sLogMsg
- End if
- ' Create the log entry
- Set oLog = oFSO.OpenTextFile(LogPath & "\" & LogFile, ForAppending, True)
- oLog.WriteLine sTempMsg
- oLog.Close
- ' Create the master log entry
- Set oLog = oFSO.OpenTextFile(LogPath & "\" & MasterLogFile, ForAppending, True)
- oLog.WriteLine sTempMsg
- oLog.Close
- ' Write to a network Share Entry
- If NetworkLogging <> "" then
- Set oLog = oFSO.OpenTextFile(NetworkLogging & "\" & MasterLogFile, ForAppending, True)
- oLog.WriteLine sTempMsg
- oLog.Close
- End if
- On error goto 0
- End Function
- ' //
- ' // Standard MDT Event Messaging routine, used To send event status messages to a networked log file.
- ' //
- ' // Standard Error Types
- ' // Public Const LogTypeInfo = 1 ' Informational Message
- ' // Public Const LogTypeWarning = 2 ' Warning Message
- ' // Public Const LogTypeError = 3 ' Error Message
- ' // Public Const LogTypeVerbose = 4 ' Verbose Messages only logged when Debug has been set.
- ' //
- Function CreateEvent(iEventID, iType, sMessage, arrParms)
- Dim sEventFile
- Dim fptr
- Dim sLine
- Dim iMOMType
- Dim sDomain
- Dim sComputer
- Dim sPackage
- Dim sAdvert
- Dim i
- Dim sCurrentStep
- Dim sTotalSteps
- Dim sScript
- Dim oService
- Dim sID
- Dim oResult
- On Error Resume Next
- ' Log the message specified
- CreateEntry sMessage, iType
- ' Get some information from the task sequence environment for use below (if needed)
- sCurrentStep = oEnvironment.Item("_SMSTSNextInstructionPointer")
- If sCurrentStep = "" then
- sCurrentStep = "0"
- End if
- sTotalSteps = oEnvironment.Item("_SMSTSInstructionTableSize")
- If sTotalSteps = "" then
- sTotalSteps = "0"
- End if
- ' Send events to the event share if specified
- If oEnvironment.Item("EventShare") <> "" then
- ' Make sure the path is accessible
- oUtility.ValidateConnection oEnvironment.Item("EventShare")
- ' Create a unique file name on the share.
- sEventFile = oEnvironment.Item("EventShare") & "\" & oUtility.ComputerName & "_" & oFSO.GetTempName
- Set fptr = oFSO.CreateTextFile(sEventFile, True)
- If Err then
- CreateEntry "Unable to create event file " & sEventFile & ": " & Err.Description & " (" & Err.Number & ")", LogTypeError
- Exit function
- End if
- ' Build the first line to write
- Select Case iType
- Case LogTypeInfo
- iMOMType = 4
- Case LogTypeWarning
- iMOMType = 2
- Case LogTypeError
- iMOMType = 1
- End Select
- sDomain = oEnvironment.Item("JoinDomain")
- sComputer = oUtility.ComputerName
- If oEnvironment.Item("_SMSTSAdvertID") <> "" then
- sAdvert = oEnvironment.Item("_SMSTSAdvertId")
- sPackage = oEnvironment.Item("_SMSTSPackageID")
- ElseIf oEnvironment.Item("OSDADVERTID") = "" then
- sAdvert = "OSD00000"
- sPackage = "OSD00000"
- Else
- sAdvert = oEnvironment.Item("OSDADVERTID")
- sPackage = oEnvironment.Item("OSDPACKAGEID")
- End if
- ' Write out the first line (common content)
- sLine = CStr(iEventID) & "," & CStr(iMOMType) & "," & sDomain & "," & sComputer & "," & sPackage & "," & sAdvert & "," & sCurrentStep & "," & sTotalSteps & "," & oEnvironment.Item("DeploymentMethod")
- fptr.WriteLine sLine
- If Err then
- CreateEntry "Unable to write event file " & sEventFile & ": " & Err.Description & " (" & Err.Number & ")", LogTypeError
- Exit function
- End if
- ' Write out the second line (insertion strings)
- fptr.WriteLine Join(arrParms, ",")
- If Err then
- CreateEntry "Unable to write event file " & sEventFile & ": " & Err.Description & " (" & Err.Number & ")", LogTypeError
- Exit function
- End if
- ' Write out the third line (message)
- fptr.WriteLine sMessage
- If Err then
- CreateEntry "Unable to write event file " & sEventFile & ": " & Err.Description & " (" & Err.Number & ")", LogTypeError
- Exit function
- End if
- ' Close the file
- fptr.Close
- Set fptr = Nothing
- CreateEntry "Event " & CStr(iEventID) & " sent: " & sMessage, LogTypeInfo
- End if
- ' Send events to the event service if specified
- If oEnvironment.Item("EventService") <> "" then
- ' Create a web service object
- Set oService = Nothing
- Err.Clear
- Set oService = new WebService
- If Err then
- ' Load ZTIDataAccess.vbs and try again
- sScript = oFSO.OpenTextFile(oEnv("ScriptRoot") & "\ZTIDataAccess.vbs", 1, false).ReadAll
- ExecuteGlobal sScript
- Set oService = new WebService
- End if
- If oService is Nothing then
- oLogging.CreateEntry "Unable to create WebService class", LogTypeWarning
- Exit Function
- End if
- ' Build the parameters to pass to the web service
- sService = "PostEvent"
- sID = oEnvironment.Item("UUID") & "," & Join(oEnvironment.ListItem("MacAddress").Keys, ",")
- sLine = "uniqueID=" & oEnvironment.Item("LTIGUID") & "&computerName=" & oUtility.ComputerName & "&messageID=" & CStr(iEventID) & "&severity=" & CStr(iType) & "&stepName=" & oEnvironment.Item("_SMSTSCurrentActionName") & "¤tStep=" & sCurrentStep & "&totalSteps=" & sTotalSteps & "&id=" & sID & "&message=" & sMessage
- sLine = sLine & "&dartIP=" & oEnvironment.Item("DartIP001") & "&dartPort=" & oEnvironment.Item("DartPort001") & "&dartTicket=" & oEnvironment.Item("DartTicket") & "&vmHost=" & oEnvironment.Item("VMHost") & "&vmName=" & oEnvironment.Item("VMName")
- ' Call the web service
- oService.WebService = oEnvironment.Item("EventService") & "/MDTMonitorEvent/PostEvent?" & sLine
- oService.Method = "GET"
- oService.Quiet = true
- Set oResult = oService.Query
- ' Remember the returned GUID value
- If oEnvironment.Item("LTIGUID") <> oResult.DocumentElement.Text then
- oEnvironment.Item("LTIGUID") = oResult.DocumentElement.Text
- End if
- CreateEntry "Event " & CStr(iEventID) & " sent: " & sMessage, LogTypeInfo
- End if
- End Function
- Function GetDiscoveryArray
- Dim sLine
- Dim dicMac
- Dim arrMac
- Dim i
- ' Add the local entries
- sLine = oEnvironment.Item("PHASE") & "," & oEnvironment.Item("AssetTag") & "," & oEnvironment.Item("UUID")
- Set dicMac = oEnvironment.ListItem("MacAddress")
- arrMac = dicMac.Keys
- For i = 0 to 4
- If i > UBound(arrMac) then
- sLine = sLine & ","
- Else
- sLine = sLine & "," & arrMac(i)
- End if
- Next
- ' Add the user data entries (which might not be available yet)
- sLine = oEnvironment.Substitute(sLine & "," & oEnvironment.Item("SLShare") & "," & oEnvironment.Item("UDShare") & "," & oEnvironment.Item("UDDir"))
- ' Split it into an array and return it
- GetDiscoveryArray = Split(sLine,",")
- End Function
- Public Function CopyLog()
- Dim oFile
- Dim iRetVal, fptr1, fptr2, sLine, sNewLogFolderName, sLogFile
- Dim sComputer
- Dim sLog
- Dim sBootDrive
- On Error Resume Next
- ' Figure out where to copy the local logfile to
- If oEnvironment.Item("SLShare") = "" then
- oLogging.CreateEntry "Unable to copy log to the network as no SLShare value was specified.", LogTypeInfo
- Exit Function
- End if
- ' Make sure the path is accessible
- oUtility.ValidateConnection oEnvironment.Item("SLShare")
- oUtility.VerifyPathExists oEnvironment.Item("SLShare")
- If not oFSO.FolderExists(oEnvironment.Item("SLShare")) then
- oLogging.CreateEntry "An invalid SLShare value of " & oEnvironment.Item("SLShare") & " was specified.", LogTypeWarning
- Exit Function
- End if
- ' Figure out the computer name
- sComputer = oUtility.ComputerName
- sBootDrive = oUtility.GetOSTargetDriveLetterEx(false)
- if sBootDrive = "" then
- oLogging.CreateEntry "Destination Logical Drive was not specificed, defaulting to #:\", LogTypeInfo
- sBootDrive = "#:" ' Unknown Boot Drive
- End if
- ' Construct the new folder name
- sNewLogFolderName = oEnvironment.Item("SLShare") & "\" & sComputer
- oUtility.VerifyPathExists sNewLogFolderName
- ' Copy all the main logs (except BDD.LOG, which we'll merge later)
- For each oFile in oFSO.GetFolder(oLogging.LogPath).Files
- If UCase(oFile.Name) <> "BDD.LOG" and (Right(UCase(oFile.Name), 4) = ".LOG" or Right(UCase(oFile.Name), 4) = ".XML") then
- oLogging.CreateEntry "Copying " & oLogging.LogPath & "\" & oFile.Name & " to " & sNewLogFolderName & "\" & oFile.Name, LogTypeInfo
- oFSO.CopyFile oLogging.LogPath & "\" & oFile.Name, sNewLogFolderName & "\", True
- End if
- Next
- ' Copy any exceptions we can find
- For each sLog in Array("SMSTS.LOG", "Debug\Netsetup.log", "wpeinit.log", "Debug\DCPROMO.LOG", "Debug\DCPROMOUI.LOG", "OSDSetupWizard.log")
- If oFSO.FileExists(oEnvironment.Item("SMSTSLogPath_Cache") & "\" & sLog) then
- oLogging.CreateEntry "Copying " & oEnvironment.Item("SMSTSLogPath_Cache") & "\" & sLog & " to " & sNewLogFolderName & "\" & sLog, LogTypeInfo
- oFSO.CopyFile oEnvironment.Item("SMSTSLogPath_Cache") & "\" & sLog, sNewLogFolderName & "\", True
- ElseIf oFSO.FileExists(oEnvironment.Item("_SMSTSLogPath") & "\" & sLog) then
- oLogging.CreateEntry "Copying " & oEnvironment.Item("_SMSTSLogPath") & "\" & sLog & " to " & sNewLogFolderName & "\" & sLog, LogTypeInfo
- oFSO.CopyFile oEnvironment.Item("_SMSTSLogPath") & "\" & sLog, sNewLogFolderName & "\", True
- ElseIf oFSO.FileExists(oEnv("TEMP") & "\" & sLog) then
- oLogging.CreateEntry "Copying " & oEnv("TEMP") & "\" & sLog & " to " & sNewLogFolderName & "\" & sLog, LogTypeInfo
- oFSO.CopyFile oEnv("TEMP") & "\" & sLog, sNewLogFolderName & "\", True
- ElseIf oFSO.FileExists(oEnv("SystemRoot") & "\" & sLog) then
- oLogging.CreateEntry "Copying " & oENV("SystemRoot") & "\" & sLog & " to " & sNewLogFolderName & "\", LogTypeInfo
- oFSO.CopyFile oENV("SystemRoot") & "\" & sLog, sNewLogFolderName & "\", True
- ElseIf oFSO.FileExists(oEnv("SystemRoot") & "\System32\" & sLog) then
- oLogging.CreateEntry "Copying " & oENV("SystemRoot") & "\System32\" & sLog & " to " & sNewLogFolderName & "\", LogTypeInfo
- oFSO.CopyFile oENV("SystemRoot") & "\System32\" & sLog, sNewLogFolderName & "\", True
- End if
- Next
- ' Copy the Panther Logs
- If oFSO.FileExists(oENV("SystemRoot") & "\Panther\setupact.log") Then
- oUtility.VerifyPathExists sNewLogFolderName & "\Panther"
- OLogging.CreateEntry "Copying " & oENV("SystemRoot") & "\Panther\setupact.log to " & sNewLogFolderName & "\Panther", LogTypeInfo
- oFSO.CopyFile oENV("SystemRoot") & "\Panther\setupact.log", sNewLogFolderName & "\Panther\", True
- End If
- If oFSO.FileExists(oENV("SystemRoot") & "\Panther\setuperr.log") Then
- oUtility.VerifyPathExists sNewLogFolderName & "\Panther"
- OLogging.CreateEntry "Copying " & oENV("SystemRoot") & "\Panther\setuperr.log to " & sNewLogFolderName & "\Panther", LogTypeInfo
- oFSO.CopyFile oENV("SystemRoot") & "\Panther\setuperr.log", sNewLogFolderName & "\Panther\", True
- End If
- If oFSO.FileExists(oENV("SystemRoot") & "\Panther\cbs_unattend.log") Then
- oUtility.VerifyPathExists sNewLogFolderName & "\Panther"
- OLogging.CreateEntry "Copying " & oENV("SystemRoot") & "\Panther\cbs_unattend.log to " & sNewLogFolderName & "\Panther", LogTypeInfo
- oFSO.CopyFile oENV("SystemRoot") & "\Panther\cbs_unattend.log", sNewLogFolderName & "\Panther\", True
- End If
- If oFSO.FileExists(oENV("SystemRoot") & "\Panther\UnattendGC\setupact.log") Then
- oUtility.VerifyPathExists sNewLogFolderName & "\Panther\UnattendGC"
- OLogging.CreateEntry "Copying " & oENV("SystemRoot") & "\Panther\UnattendGC\setupact.log to " & sNewLogFolderName & "\Panther\UnattendGC", LogTypeInfo
- oFSO.CopyFile oENV("SystemRoot") & "\Panther\UnattendGC\setupact.log", sNewLogFolderName & "\Panther\UnattendGC\", True
- End If
- If oFSO.FileExists(oENV("SystemRoot") & "\Panther\UnattendGC\setuperr.log") Then
- oUtility.VerifyPathExists sNewLogFolderName & "\Panther\UnattendGC"
- OLogging.CreateEntry "Copying " & oENV("SystemRoot") & "\Panther\UnattendGC\setuperr.log to " & sNewLogFolderName & "\Panther\UnattendGC", LogTypeInfo
- oFSO.CopyFile oENV("SystemRoot") & "\Panther\UnattendGC\setuperr.log", sNewLogFolderName & "\Panther\UnattendGC\", True
- End If
- If oFSO.FileExists(sBootDrive & "\$WINDOWS.~BT\Sources\Panther\setupact.log") Then
- oUtility.VerifyPathExists sNewLogFolderName & "\Panther"
- OLogging.CreateEntry "Copying " & sBootDrive & "\$WINDOWS.~BT\Sources\Panther\setupact.log to " & sNewLogFolderName & "\Panther", LogTypeInfo
- oFSO.CopyFile sBootDrive & "\$WINDOWS.~BT\Sources\Panther\setupact.log", sNewLogFolderName & "\Panther\", True
- End If
- If oFSO.FileExists(sBootDrive & "\$WINDOWS.~BT\Sources\Panther\setuperr.log") Then
- oUtility.VerifyPathExists sNewLogFolderName & "\Panther"
- OLogging.CreateEntry "Copying " & sBootDrive & "\$WINDOWS.~BT\Sources\Panther\setuperr.log to " & sNewLogFolderName & "\Panther", LogTypeInfo
- oFSO.CopyFile sBootDrive & "\$WINDOWS.~BT\Sources\Panther\setuperr.log", sNewLogFolderName & "\Panther\", True
- End If
- If oFSO.FileExists(sBootDrive & "\$WINDOWS.~BT\Sources\Panther\cbs_unattend.log") Then
- oUtility.VerifyPathExists sNewLogFolderName & "\Panther"
- OLogging.CreateEntry "Copying " & sBootDrive & "\$WINDOWS.~BT\Sources\Panther\cbs_unattend.log to " & sNewLogFolderName & "\Panther", LogTypeInfo
- oFSO.CopyFile sBootDrive & "\$WINDOWS.~BT\Sources\Panther\cbs_unattend.log", sNewLogFolderName & "\Panther\", True
- End If
- If oFSO.FileExists(sBootDrive & "\$WINDOWS.~BT\Sources\Panther\UnattendGC\setupact.log") Then
- oUtility.VerifyPathExists sNewLogFolderName & "\Panther\UnattendGC"
- OLogging.CreateEntry "Copying " & sBootDrive & "\$WINDOWS.~BT\Sources\Panther\UnattendGC\setupact.log to " & sNewLogFolderName & "\Panther\UnattendGC", LogTypeInfo
- oFSO.CopyFile sBootDrive & "\$WINDOWS.~BT\Sources\Panther\UnattendGC\setupact.log", sNewLogFolderName & "\Panther\UnattendGC\", True
- End If
- If oFSO.FileExists(sBootDrive & "\$WINDOWS.~BT\Sources\Panther\UnattendGC\setuperr.log") Then
- oUtility.VerifyPathExists sNewLogFolderName & "\Panther\UnattendGC"
- OLogging.CreateEntry "Copying " & sBootDrive & "\$WINDOWS.~BT\Sources\Panther\UnattendGC\setuperr.log to " & sNewLogFolderName & "\Panther\UnattendGC", LogTypeInfo
- oFSO.CopyFile sBootDrive & "\$WINDOWS.~BT\Sources\Panther\UnattendGC\setuperr.log", sNewLogFolderName & "\Panther\UnattendGC\", True
- End If
- ' Make sure we have a local log file; it might not exist if the disk isn't yet writable.
- sLogFile = LogPath & "\" & MasterLogFile
- If not oFSO.FileExists(sLogFile) then
- oLogging.CreateEntry "Master log file " & sLogFile & " was not found, unable to copy to " & sNewLogFolderName & "\BDD.LOG", LogTypeInfo
- Exit Function
- End if
- ' Copy the file contents to the end of the network file. (It might already exist from a previous action, so append to it.)
- oLogging.CreateEntry "Copying log " & sLogFile & " contents to " & sNewLogFolderName & "\BDD.LOG", LogTypeInfo
- Set fptr1 = oFSO.OpenTextFile(sLogFile, ForReading, True)
- If Err then
- oLogging.CreateEntry "Unable to open " & sLogFile & " for reading: " & Err.Description & " (" & Err.Number & ")", LogTypeInfo
- Err.Clear
- Exit Function
- End if
- Set fptr2 = oFSO.OpenTextFile(sNewLogFolderName & "\BDD.LOG", ForAppending, True)
- If Err then
- oLogging.CreateEntry "Unable to open " & sNewLogFolderName & "\BDD.LOG for appending: " & Err.Description & " (" & Err.Number & ")", LogTypeInfo
- Err.Clear
- Exit Function
- End if
- Do while Not fptr1.AtEndOfStream
- sLine = fptr1.readline
- fptr2.writeline sLine
- Loop
- fptr1.Close
- fptr2.Close
- Err.Clear
- On Error Goto 0
- End Function
- Public Function ReportProgress(sMsg, iPercent)
- Dim iMaxPercent
- Dim oProgress
- Dim uStep
- Dim uMaxStep
- CreateEntry "Update progress [ " & iPercent & " ] : " & sMsg , LogTypeVerbose
- ' Try to create the progress UI object
- On Error Resume Next
- Set oProgress = CreateObject("Microsoft.SMS.TSProgressUI")
- If Err then
- Err.Clear
- ' Record the progress in the registry
- oShell.RegWrite "HKLM\Software\Microsoft\Deployment 4\ProgressPercent", iPercent, "REG_DWORD"
- oShell.RegWrite "HKLM\Software\Microsoft\Deployment 4\ProgressText", sMsg, "REG_SZ"
- on error goto 0
- Exit Function
- End if
- On Error Goto 0
- ' Update the progress
- On Error Resume Next
- iMaxPercent = 100
- uStep = CLng(oEnvironment.Item("_SMSTSNextInstructionPointer"))
- uMaxStep = CLng(oEnvironment.Item("_SMSTSInstructionTableSize"))
- Call oProgress.ShowActionProgress(oEnvironment.Item("_SMSTSOrgName"), oEnvironment.Item("_SMSTSPackageName"), oEnvironment.Item("_SMSTSCustomProgressDialogMessage"), oEnvironment.Item("_SMSTSCurrentActionName"), (uStep), (uMaxStep), sMsg, (iPercent), (iMaxPercent))
- If Err then
- CreateEntry "Unable to update progress: " & Err.Description & " (" & Err.Number & ")", LogTypeInfo
- ReportProgress = Failure
- Err.Clear
- Exit Function
- End if
- On Error Goto 0
- ' Dispose of the object
- Set oProgress = Nothing
- End Function
- Property Get LogPath
- Dim iRetVal
- LogPath = oUtility.LogPath
- 'Preserve the existing logpath before creating the new logpath
- If Ucase(oUtility.ScriptName) = "ZTIDISKPART" and Left(LogPath,2)<> "X:" Then
- oUtility.VerifyPathExistsEx "X:\MININT\SMSOSD\OSDLOGS", FALSE
- LogPath = "X:\MININT\SMSOSD\OSDLOGS"
- End If
- If oEnvironment.Item("LogPath") <> "" AND oEnvironment.Item("LogPath") <> LogPath And Ucase(oUtility.ScriptName) <> "LTICLEANUP" Then
- On Error Resume Next
- iRetVal = oShell.Run("xcopy """ & oEnvironment.Item("LogPath") & """ """ & LogPath & """ /D /s /e /h /y /c",0, true)
- oEnvironment.Item("LogPath") = LogPath
- on Error goto 0
- End If
- If oEnvironment.Item("LogPath") = "" And Ucase(oUtility.ScriptName) <> "LTICLEANUP" Then
- oEnvironment.Item("LogPath") = LogPath
- End If
- End Property
- Function ReportFailure ( sMessage, iError )
- CreateEvent 41002, LogTypeError, oEnvironment.Substitute( "FAILURE ( " & FormatError(iError) & " ): " & sMessage ), Array(iError)
- ' It is possible that we are are not running in the Wscript Host ( HTML Page ).
- on error resume next
- WScript.Quit iError
- on error goto 0
- End function
- ' //
- ' // Perform an inline check of the condition and write out the message
- ' // iRC can be either SUCCESS (0), FAILURE(not 0) as defined above.
- ' // or iRC can be Boolean either TRUE or FALSE
- ' //
- ' // Anything other than Success or Failure will log a Warning or Error.
- ' //
- Function TRACEEX( iRc, iError, sMessage, bFatal)
- TRACEEX = iRc
- If Err then
- ' Error
- TRACEEX = Err.Number
- sMessage = sMessage & " - " & Err.Description
- CreateEntry oEnvironment.Substitute( "FAILURE (Err): " & FormatError(TRACEEX) & ": " & sMessage ), LogTypeWarning
- If bFatal then
- ' Fatial Error
- ReportFailure sMessage, iError
- End if
- Elseif (VarType(iRC) = vbInteger) or (VarType(iRC) = vbLong) or (VarType(iRC) = vbBoolean) then
- ' iRC is either a Variant Integer (Either SUCCESS or FAILURE), or a Variant Bool (Either True or False)
- If ( (iRC = Success or iRC = 3010) and ((VarType(iRC) = vbInteger) or (VarType(iRC) = vbLong)) ) or ( iRC = TRUE and VarType(iRC) = vbBoolean ) then
- CreateEntry oEnvironment.Substitute( "SUCCESS: " & FormatError(iRC) & ": " & sMessage ), LogTypeVerbose
- ElseIf bFatal then
- ' Fatial Error
- ReportFailure FormatError(iRC) & ": " & sMessage, iError
- Else
- CreateEntry oEnvironment.Substitute( "FAILURE: " & FormatError(iRC) & ": " & sMessage ), LogTypeWarning
- End if
- Elseif (VarType(iRC) <> vbEmpty) and (VarType(iRC) <> vbNull ) then
- CreateEntry oEnvironment.Substitute( "UNKNOWN: " & TypeName(iRc) & " = " & iRc & " : " & FormatError(iError) & ": " & sMessage ), LogTypeWarning
- End if
- End function
- Function ProcessResults( iRc )
- Dim iMainRc
- Dim sError
- Dim sMainRc
- iMainRc = iRc
- sMainRc = FormatError ( iMainRc )
- If Err then
- iMainRc = Err.Number
- sError = Err.Description
- sMainRc = FormatError ( iMainRc )
- CreateEvent 41002, LogTypeError, "ZTI ERROR - Unhandled error returned by " & oUtility.ScriptName & ": " & sError & " (" & sMainRc & ")", Array(iMainRc)
- ElseIf iRc <> Success then
- CreateEvent 41002, LogTypeError, "ZTI ERROR - Non-zero return code by " & oUtility.ScriptName & ", rc = " & sMainRc, Array(iMainRc)
- Else
- CreateEvent 41001, LogTypeInfo, oUtility.ScriptName & " processing completed successfully.", Array()
- End if
- WScript.Quit iMainRc
- End function
- Function FormatError( iError )
- ' Error messages above 0x1000000 are most likely Hex values, print both Hex and Decimal
- If not isNumeric( iError ) then
- FormatError = ""
- ElseIf Abs(iError) >= &H1000000 then
- FormatError = cstr(iError) & " 0x" & right( "00000000" & hex ( iError ), 8 )
- Else
- FormatError = cstr(iError)
- End if
- End function
- End Class
- ' //////////////////////////////////////////////////////
- Class Environment
- ' *** Public variables ***
- Public PersistFile
- ' *** Private variables ***
- Private oVariables
- Private dLastModified
- Private dLastSize
- Private osdV4
- ' *** Constructor and destructor ***
- Private Sub Class_Initialize
- PersistFile = "VARIABLES.DAT"
- On Error Resume Next
- Err.Clear
- Set oVariables = oUtility.CreateXMLDOMObject
- If Err then
- ' Unable to create XML object
- Err.Clear
- End if
- On Error Goto 0
- dLastModified = 0
- dLastSize = 0
- ' Create SMSv4 Task Sequence environment
- On Error Resume Next
- Err.Clear
- Set osdV4 = CreateObject("Microsoft.SMS.TSEnvironment")
- If Err then
- Set osdV4 = Nothing
- Err.Clear
- End if
- On Error Goto 0
- Err.Clear
- End Sub
- ' *** Private methods ***
- Function GetOSDV4(sVariable)
- GetOSDV4 = ""
- On Error Resume Next
- If osdV4 is Nothing then
- Exit Function
- Else
- GetOSDV4 = osdV4(sVariable)
- If Err then
- ' oLogging.CreateEntry "WARNING - Unable to get SMSv4 Task Sequencer environment: " & Err.Description & " (" & Err.Number & ")", LogTypeWarning
- End if
- End if
- On Error Goto 0
- Err.Clear
- End Function
- Function SetOSDV4(sVariable, sNew)
- On Error Resume Next
- If osdV4 is Nothing then
- SetOSDV4 = False
- Exit Function
- Else
- osdV4(sVariable) = sNew
- If Err then
- ' oLogging.CreateEntry "WARNING - Unable to get SMSv4 Task Sequencer environment: " & Err.Description & " (" & Err.Number & ")", LogTypeWarning
- SetOSDV4 = False
- End if
- End if
- On Error Goto 0
- Err.Clear
- SetOSDV4 = True
- End Function
- Property Get VariablesDat
- Dim sVariablesFile
- ' If necessary, load the XML file
- sVariablesFile = PersistPath & "\" & PersistFile
- If oFSO.FileExists(sVariablesFile) then
- If (oFSO.GetFile(sVariablesFile).DateLastModified <> dLastModified) or (oFSO.GetFile(sVariablesFile).Size <> dLastSize) then
- On Error Resume Next
- Do
- oVariables.Load sVariablesFile
- dLastModified = oFSO.GetFile(sVariablesFile).DateLastModified
- dLastSize = oFSO.GetFile(sVariablesFile).Size
- Loop While oVariables.DocumentElement is Nothing
- On Error Goto 0
- End if
- ElseIf dLastModified = 0 then
- oVariables.LoadXml "<?xml version=""1.0"" ?><MediaVarList Version=""4.00.5345.0000""></MediaVarList>"
- dLastModified = Now ' The file hasn't been saved yet, but we don't want to reset this
- End if
- ' Set the return value to the XML document
- Set VariablesDat = oVariables
- End Property
- Function GetDAT(sVariable)
- Dim sLockFile
- Dim oNode
- Dim fLock
- GetDAT = ""
- If Ucase(oUtility.ScriptName) <> "LTICLEANUP" Then
- sLockFile = PersistPath & "\" & PersistFile & ".LOCK"
- On error resume next
- Set fLock = nothing
- Set fLock = oFSO.CreateTextFile(sLockFile, 2, true)
- Do while fLock is nothing
- dLastModified = 0 ' FORCE a rescan.
- ' ologging.CreateEntry sLockFile & " is locked by another process, Wait!", LogTypeVerbose
- oUtility.SafeSleep 10
- Set fLock = oFSO.CreateTextFile( sLockFile, 2, true)
- Loop
- On error goto 0
- End if
- On Error Resume Next
- Set oNode = Nothing
- Set oNode = VariablesDat.DocumentElement.SelectSingleNode("//var[@name='" & UCase(sVariable) & "']")
- On Error Goto 0
- If not (oNode is Nothing) then
- GetDAT = oNode.Text
- End if
- End Function
- Function SetDAT(sVariable, sNew)
- Dim sVariablesFile
- Dim sLockFile
- Dim oNode, oCDATA, oVD
- Dim fLock
- If osdv4 is Nothing OR oEnvironment.Item("_SMSTSStandAloneMode") = "true" then
- If oFSO.FolderExists(PersistPath) then
- sVariablesFile = PersistPath & "\" & PersistFile
- If Ucase(oUtility.ScriptName) <> "LTICLEANUP" Then
- sLockFile = PersistPath & "\" & PersistFile & ".LOCK"
- On error resume next
- Set fLock = nothing
- Set fLock = oFSO.CreateTextFile(sLockFile, 2, true)
- Do while fLock is nothing
- dLastModified = 0 ' FORCE a rescan.
- ' ologging.CreateEntry sLockFile & " is locked by another process, Wait!", LogTypeVerbose
- oUtility.SafeSleep 10
- Set fLock = oFSO.CreateTextFile(sLockFile, 2, true)
- Loop
- On error goto 0
- End if
- Set oVD = VariablesDat
- ' See if the variable is already defined. If not, append a new node
- Set oNode = oVD.DocumentElement.SelectSingleNode("//var[@name='" & UCase(sVariable) & "']")
- If oNode is Nothing then
- Set oNode = oVD.CreateElement("var")
- oVD.DocumentElement.appendChild oNode
- Else
- If oNode.Text = sNew then
- ' oLogging.CreateEntry "Not changing variable " & sVariable & " because the value was not changed.", LogTypeInfo
- SetDAT = True
- Exit Function
- End if
- End if
- ' Set the name of the node
- oNode.SetAttribute "name", UCase(sVariable)
- ' Set the value of the node
- Set oCDATA = oVD.createCDATASection(sNew)
- If oNode.hasChildNodes then
- oNode.removeChild(oNode.childNodes.item(0))
- End if
- oNode.appendChild(oCDATA)
- ' Save the updated XML file
- On Error Resume Next
- oVD.Save sVariablesFile
- dLastModified = oFSO.GetFile(sVariablesFile).DateLastModified
- dLastSize = oFSO.GetFile(sVariablesFile).Size
- If Err then
- oLogging.CreateEntry "WARNING - Unable to persist items to " & sVariablesFile & ": " & Err.Description & " (" & Err.Number & ")", LogTypeWarning
- SetDat = False
- Err.Clear
- End if
- On Error Goto 0
- Else
- SetDat=False
- End if
- Else
- SetDat = False
- End If
- SetDat = True
- End Function
- Function ObfuscateEncode(sVariable, sNew)
- Select Case Ucase(sVariable)
- Case "USERID", "USERPASSWORD", "USERDOMAIN", "DOMAINADMIN", "DOMAINADMINPASSWORD", "DOMAINADMINDOMAIN", _
- "ADMINPASSWORD", "BDEPIN", "TPMOWNERPASSWORD", "USERNAME", "USERPASSWORD", "PRODUCTKEY", "OSDJOINACCOUNT",_
- "SAFEMODEADMINPASSWORD","OSDJOINPASSWORD"
- ObfuscateEncode = oStrings.Base64Encode(sNew)
- Case Else
- ObfuscateEncode = sNew
- End Select
- End Function
- Function ObfuscateDecode(sVariable, sCurrent)
- Select Case Ucase(sVariable)
- Case "USERID", "USERPASSWORD", "USERDOMAIN", "DOMAINADMIN", "DOMAINADMINPASSWORD", "DOMAINADMINDOMAIN", _
- "ADMINPASSWORD", "BDEPIN", "TPMOWNERPASSWORD", "USERNAME", "USERPASSWORD", "PRODUCTKEY", "OSDJOINACCOUNT",_
- "SAFEMODEADMINPASSWORD","OSDJOINPASSWORD"
- ObfuscateDecode = oStrings.Base64Decode(sCurrent)
- ' If the variable wasn't a valid base64 string, an empty string will be returned. Instead of
- ' passing that back, return the current value. (The Base64Decode method should log a warning.)
- If ObfuscateDecode = "" and sCurrent <> "" then
- ObfuscateDecode = sCurrent
- End if
- Case Else
- ObfuscateDecode = sCurrent
- End Select
- End Function
- ' *** Public methods ***
- Public Property Get Exists(sVariable)
- If Item(sVariable) <> "" then
- Exists = True
- Else
- Exists = False
- End if
- End Property
- Public Property Get Item(sVariable)
- Dim sOriginal
- Dim bSync
- ' First try TS environment, then (for Lite Touch only) try the XML file
- Item = GetOSDV4(sVariable)
- If Item = "" and GetOSDV4("DeploymentMethod") <> "SCCM" then
- ' No value retrieved from the task sequence, try the XML file
- Item = GetDat(sVariable)
- If Item <> "" then
- bSync = true
- End if
- End if
- ' Decode and sync if not blank
- If Item <> "" then
- ' Decode the variable
- sOriginal = Item
- Item = ObfuscateDecode(sVariable, sOriginal)
- ' Try to set the value in the task sequence environment (sync)
- If bSync then
- SetOSDV4 sVariable, sOriginal
- End if
- End if
- End Property
- Public Property Let Item(sVariable, sNew)
- Dim sEncoded
- ' Encode as required
- sEncoded = ObfuscateEncode(sVariable, sNew)
- ' Save to all available environments
- If SetOSDV4(sVariable, sEncoded) or SetDat(sVariable, sEncoded) Then
- oLogging.CreateEntry "Property " & sVariable & " is now = " & sNew, LogTypeInfo
- End If
- ' For completeness, set the variable in the process's environment as well
- oEnv(sVariable) = sNew
- End Property
- Public Property Get ListItem(sVariable)
- Dim i
- Dim sPadded
- Set ListItem = CreateObject("Scripting.Dictionary")
- For i = 1 to 999
- sPadded = sVariable & Right("000" & CStr(i), 3)
- If Item(sPadded) <> "" then
- If not ListItem.Exists(Item(sPadded)) then
- ListItem.Add Item(sPadded), ""
- End if
- ElseIf Item(sVariable & CStr(i)) <> "" then
- If not ListItem.Exists(Item(sVariable & CStr(i))) then
- ListItem.Add Item(sVariable & CStr(i)), ""
- End if
- Else
- Exit For ' Exit on first "not found" entry
- End if
- Next
- End Property
- Public Sub SetListItemEx (sVariable, sNew)
- Dim sElement
- Dim i
- Dim sPadded
- i = 0
- For each sElement in sNew
- i = i + 1
- sPadded = sVariable & Right("000" & CStr(i), 3)
- Item(sPadded) = sElement
- Next
- ' Blank out the next in case there was something there
- sPadded = sVariable & Right("000" & CStr(i+1), 3)
- If Exists(sPadded) then
- Item(sPadded) = ""
- End if
- ' Blank out the non-list item if it was there
- If exists(sVariable) then
- Item(sVariable) = ""
- End if
- End sub
- Public Property Set ListItem(sVariable, sNew)
- SetListItemEx sVariable, sNew
- End Property
- Public Property Let ListItem(sVariable, sNew)
- SetListItemEx sVariable, sNew
- End Property
- Public Property Get IndirectItem( sVariable )
- IndirectItem = oEnvironment.Item(oEnvironment.Item(sVariable))
- End Property
- Public Property Let IndirectItem( sVariable, sNew )
- If oEnvironment.Item(sVariable) = "" then
- oLogging.CreateEntry "Invalid MDT Indirect Variable pointer: " & sVariable, LogTypeWarning
- Else
- oEnvironment.Item(oEnvironment.Item(sVariable)) = sNew
- End if
- End Property
- Function Substitute(sVal)
- Dim sReplace, iPos, iEnd, sEval
- ' Substitute the appropriate values
- iPos = Instr(sVal, "%")
- While iPos > 0
- ' Find ending "%"
- iEnd = Instr(iPos+1, sVal, "%")
- If iEnd > 0 then
- sEval = Mid(sVal, iPos+1, iEnd - iPos - 1)
- sReplace = ""
- If oEnvironment.ListItem(sEval).Count > 0 then
- For each sReplace in oEnvironment.ListItem(sEval).Keys
- Exit For ' Grab the first value
- Next
- ElseIf oEnvironment.Item(sEval) <> "" then
- sReplace = oEnvironment.Item(sEval)
- End if
- If sReplace <> "" then
- If iPos = 1 then
- sVal = CStr(sReplace) & Mid(sVal, iEnd + 1)
- ElseIf iEnd = Len(sVal) then
- sVal = Left(sVal, iPos - 1) & CStr(sReplace)
- Else
- sVal = Left(sVal, iPos - 1) & CStr(sReplace) & Mid(sVal, iEnd + 1)
- End if
- iPos = Instr(sVal, "%")
- Else
- iPos = iEnd
- End if
- Else
- iPos = iEnd
- End if
- WEnd
- ' Expand any environment variables
- sVal = oShell.ExpandEnvironmentStrings(sVal)
- ' Finally, look for evaluate blocks
- iPos = Instr(sVal, "#")
- While iPos > 0
- ' Find ending "#"
- iEnd = Instr(iPos+1, sVal, "#")
- If iEnd > 0 then
- sEval = Mid(sVal, iPos+1, iEnd - iPos - 1)
- sReplace = empty
- On Error Resume Next
- sReplace = Eval(sEval)
- On Error Goto 0
- If not isEmpty(sReplace) then
- If iPos = 1 then
- sVal = sReplace & Mid(sVal, iEnd + 1)
- ElseIf iEnd = Len(sVal) then
- sVal = Left(sVal, iPos - 1) & sReplace
- Else
- sVal = Left(sVal, iPos - 1) & sReplace & Mid(sVal, iEnd + 1)
- End if
- iPos = Instr(sVal, "#")
- Else
- iPos = iEnd
- End if
- Else
- iPos = iEnd
- End if
- WEnd
- Substitute = Trim(sVal)
- End Function
- Public Property Get PersistPath
- Dim oOrigPersistFile
- Dim oNewPersistFile
- PersistPath = oUtility.LogPath
- If oEnv("SystemDrive") = "X:" then
- If oFSO.FileExists("X:\minint\smsosd\osdlogs\variables.dat") Then
- Set oOrigPersistFile = oFSO.GetFile("X:\minint\smsosd\osdlogs\variables.dat")
- If oFSO.FileExists(PersistPath & "\VARIABLES.DAT") Then
- Set oNewPersistFile = oFSO.GetFile(PersistPath & "\VARIABLES.DAT")
- If oOrigPersistFile.Size > oNewPersistFile.Size Then
- oFSO.CopyFile "X:\minint\smsosd\osdlogs\variables.dat", PersistPath & "\VARIABLES.DAT", true
- End if
- Else
- oFSO.CopyFile "X:\minint\smsosd\osdlogs\variables.dat", PersistPath & "\VARIABLES.DAT", true
- End if
- End if
- End if
- End Property
- Public Function Release
- Set osdV4 = Nothing
- End Function
- End Class
- Class Utility
- ' *** Properties ***
- Public isHTML
- Public isWSH
- Public isMSHTA
- Public isCScript
- Public isWScript
- Public oMSHTA
- Public Arguments
- ' *** Private variables ***
- Dim dicNetworkConnections
- Dim sScriptDir
- Dim oBDDUtility
- Dim oSupportedPlatforms
- Private sLocalRootPath
- Private bCacheLocalRootPath
- Private startTime
- Private lastHeartbeat
- Private iVersionMajor
- Private iVersionMinor
- Private iBuildNumber
- Private iRevision
- ' *** Constructor and destructor ***
- Private Sub Class_Initialize
- Dim re
- Dim arrDrives, i
- Dim oContext, oLocator
- ' Initialize the objects
- Set oFSO = CreateObject("Scripting.FileSystemObject")
- Set oShell = CreateObject("WScript.Shell")
- Set oEnv = oShell.Environment("PROCESS")
- Set oNetwork = CreateObject("WScript.Network")
- Set objWMI = Nothing
- On Error Resume Next
- Set oContext = CreateObject("WbemScripting.SWbemNamedValueSet")
- oContext.Add "__ProviderArchitecture", 64
- Set oLocator = CreateObject("Wbemscripting.SWbemLocator")
- Set objWMI = oLocator.ConnectServer("","root\cimv2","","",,,,oContext)
- On Error Goto 0
- Set dicNetworkConnections = CreateObject("Scripting.Dictionary")
- dicNetworkConnections.CompareMode = TextCompare
- Set oBDDUtility = Nothing
- Set oSupportedPlatforms = Nothing
- isHTML = FALSE
- isWSH = FALSE
- isMSHTA = FALSE
- isCScript = FALSE
- isWScript = FALSE
- set oMSHTA = nothing
- on error resume next
- isHTML = IsObject(window.location)
- isWSH = IsObject(WScript)
- on error goto 0
- If isHTML Then
- isMSHTA = document.all.tags("Application").length > 0
- On error resume next
- set oMSHTA = document.all.tags("Application")(0)
- if window.location.hostname <> "" then
- sScriptDir = oFSO.GetParentFolderName( unescape("\\" & window.location.hostname & window.location.pathname ) )
- else
- sScriptDir = oFSO.GetParentFolderName( unescape(window.location.pathname) )
- end if
- On error goto 0
- ElseIf isWSH Then
- isCScript = ucase(right(WScript.FullName,len("Xscript.exe"))) = "CSCRIPT.EXE"
- isWScript = ucase(right(WScript.FullName,len("Xscript.exe"))) = "WSCRIPT.EXE"
- sScriptDir = oFSO.GetParentFolderName(WScript.ScriptFullName)
- End if
- If Mid(sScriptDir, 2, 2) = ":\" then
- ' Look to see if this is a mapped drive
- On Error Resume Next
- Set arrDrives = oNetwork.EnumNetworkDrives
- If Err then
- On Error Goto 0
- oLogging.CreateEntry "ERROR - Network is unavailable: " & Err.Description & " (" & Err.Number & ")", LogTypeError
- Else
- On Error Goto 0
- For i = 0 to arrDrives.Count - 1 Step 2
- If arrDrives.Item(i) = UCase(Left(sScriptDir,2)) then
- If Len(sScriptDir) > 3 then
- sScriptDir = arrDrives.Item(i+1) & Mid(sScriptDir, 3)
- Else
- sScriptDir = arrDrives.Item(i+1)
- End if
- Exit For
- End if
- Next
- End if
- On Error Goto 0
- End if
- ' By default, set a flag to cache the local root path
- bCacheLocalRootPath = True
- ' Record times for heartbeat events
- startTime = Now
- lastHearbeat = startTime
- End Sub
- ' *** Public methods ***
- Public Sub PrepareEnvironment
- Dim sArg
- Set oLogging = New Logging
- Set oEnvironment = New Environment
- Set oStrings = New Strings
- Set oFileHandling = New FileHandling
- set Arguments = GetArguments
- ' Loop through all the parameters and turn them into environment variables. Enforce debug values.
- On Error Resume Next
- For each sArg in Arguments
- If UCase(sArg) = "DEBUG" then
- If UCase(Arguments(sArg)) = "TRUE" or UCase(Arguments(sArg)) = "FALSE" then
- oLogging.CreateEntry "'debug' parameter was specified.", LogTypeInfo
- Else
- oLogging.CreateEntry "Invalid 'debug' parameter specified: " & Arguments(sArg), LogTypeError
- WScript.Quit Failure
- End if
- oEnvironment.Item(sArg) = UCase(Arguments(sArg))
- Else
- oEnvironment.Item(sArg) = Arguments(sArg)
- End if
- Next
- On Error Goto 0
- Err.Clear
- ' Log the version
- oLogging.CreateEntry "Microsoft Deployment Toolkit version: " & Version, LogTypeInfo
- ' Log where the SMSTS.LOG can be found
- If oEnvironment.Item("_SMSTSLogPath") <> "" then
- oEnvironment.SetDAT "SMSTSLogPath_Cache", oEnvironment.Item("_SMSTSLogPath")
- oLogging.CreateEntry "The task sequencer log is located at " & oEnvironment.Item("_SMSTSLogPath") & "\SMSTS.LOG. For task sequence failures, please consult this log.", LogTypeInfo
- End if
- ' Set a default for debug (if necessary)
- If oEnvironment.Item("Debug") = "" then
- oEnvironment.Item("Debug") = "FALSE"
- End if
- If UCase(oEnvironment.Item("Debug")) = "TRUE" then
- oLogging.Debug = True
- Else
- oLogging.Debug = False
- End if
- If oEnvironment.Item("SLShareDynamicLogging") <> "" then
- If oEnvironment.Item("UserID") <> "" and oEnvironment.Item("UserDomain") <> "" and oEnvironment.Item("UserPassword") <> "" then
- If oFSO.FolderExists( LogPath ) then
- oLogging.CreateEntry "Write all logging text to " & oEnvironment.Item("SLShareDynamicLogging") , LogTypeInfo
- ValidateConnection oEnvironment.Item("SLShareDynamicLogging")
- oUtility.VerifyPathExists oEnvironment.Item("SLShareDynamicLogging")
- If not oFSO.FolderExists(oEnvironment.Item("SLShareDynamicLogging")) then
- oLogging.CreateEntry "An invalid SLShareDynamicLogging value of " & oEnvironment.Item("SLShareDynamicLogging") & " was specified.", LogTypeWarning
- Else
- oLogging.NetworkLogging = oEnvironment.Item("SLShareDynamicLogging")
- End if
- End if
- End if
- End if
- End Sub
- ' This function converts the string representation of a version "xx.xx.xx.xx" to int
- ' The function captures the version major/minor and build major/minor into Utility class variables.
- ' It can be accessed via properties Utility.VersionMajor and Utility.VersionMinor
- ' e.g.
- ' 1. GetMajorMinorVersion("10.0.12.1234") this will capture
- ' Utility.VersionMajor = 10 and Utility.VersionMinor = 0 (BuildMajor and BuildMinor are not yet exposed as properties but the function still captures it)
- ' 2. GetMajorMinorVersion("10.110")
- ' Utility.VersionMajor = 10 and Utility.VersionMinor = 110 (no BuildMajor and BuildMinor)
- ' in case of invalid string representation of version (e.g. GetMajorMinorVersion("Thisisfun") function will set values to Int.Max (32767)
- Public Function GetMajorMinorVersion(sVersion)
- Dim length
- Dim splitArray
- splitArray = Split(sVersion,".")
- length = UBound(splitArray)
- If length >=0 then
- Select case length
- Case 1
- iVersionMinor = CInt(splitArray(1))
- Case 2
- iVersionMinor = CInt(splitArray(1))
- iBuildNumber = CInt(splitArray(2))
- Case 3
- iVersionMinor = CInt(splitArray(1))
- iBuildNumber = CInt(splitArray(2))
- iRevision = CInt(splitArray(3))
- Case Else
- iVersionMinor = 32767
- iBuildNumber = 32767
- iRevision = 32767
- End select
- iVersionMajor = CInt(splitArray(0))
- Else
- iVersionMajor = 32767 'Int.Max for VbScript is 32767
- iVersionMinor = 32767
- iBuildNumber = 32767
- iRevision = 32767
- End if
- End Function
- ' This function retrieves MSXML DOM document using MSXML2.DomDocument.6.0
- ' If it cannot load tries to get from MSXML2.DOMDocument.3.0
- Public Function GetMSXMLDOMDocument
- On Error Resume Next
- Set GetMSXMLDOMDocument = CreateObject("MSXML2.DOMDocument.6.0")
- If Err Then
- Set GetMSXMLDOMDocument = CreateObject("MSXML2.DOMDocument")
- End If
- On Error Goto 0
- End Function
- Private Function GetArguments
- Dim RegExObj
- Dim Match
- set RegExObj = New RegExp
- RegExObj.Global = TRUE
- RegExObj.Multiline = TRUE
- RegExObj.IgnoreCase = TRUE
- RegExObj.Pattern = "\/([^\ ""\:\=]+)(?:(?:[\:\=]""([^""]+)"")|(?:[\:\=]([^\ ""]+)))?"
- if isWSH then
- set GetArguments = wscript.arguments.Named
- elseif isMSHTA and (not oMSHTA is nothing) then
- Set GetArguments = CreateObject("Scripting.Dictionary")
- GetArguments.CompareMode = vbTextCompare
- for each Match in RegExObj.Execute(oMSHTA.CommandLine)
- If not isempty(Match.submatches(0)) then
- if not GetArguments.Exists(Match.submatches(0)) then
- GetArguments.Add Match.submatches(0), Match.submatches(1) & Match.submatches(2)
- End if
- End if
- next
- elseif IsHTML then
- Set GetArguments = CreateObject("Scripting.Dictionary")
- GetArguments.CompareMode = vbTextCompare
- for each Match in oStrings.ForceAsArray( window.location.search,"&")
- If Instr(1,Match,"=",vbTextCompare) <> 0 then
- If not GetArguments.Exists(left(Match,Instr(1,Match,"=",vbTextCompare)-1)) then
- GetArguments.Add left(Match,Instr(1,Match,"=",vbTextCompare)-1), mid(Match,Instr(1,Match,"=",vbTextCompare)+1)
- End if
- End if
- next
- else
- Set GetArguments = CreateObject("Scripting.Dictionary")
- GetArguments.CompareMode = vbTextCompare
- end if
- End function
- Function GetPA
- GetPA = Replace(oShell.Environment("PROCESS")("Processor_Architecture"),"amd64","x64",1,-1,vbTextCompare)
- end function
- Public Function RunNewInstanceEx ( sClassName, sClassInstance, sMain )
- Dim oScriptClass
- Dim iScriptRc
- ' Disable On Error Resume next for advanced debugging
- If not oUtility.Arguments.Exists("DebugCapture") then
- On Error Resume next
- End if
- execute "Set " & sClassInstance & " = New " & sClassName
- TestAndFail SUCCESS, 5400, "Create object: Set " & sClassInstance & " = New " & sClassName
- If oUtility.Arguments.Exists("TestHook") then
- ' Hook for Unit Test code. Allows us to run Unit Tests without modification of the Original script.
- oLogging.CreateEntry "Run Test Script [" & oUtility.Arguments.Item("TestHook") & "]...", LogTypeInfo
- Execute oFSO.OpenTextFile(oUtility.Arguments.Item("TestHook")).ReadAll
- oLogging.CreateEntry "Finished with Test Script! iScriptRc = " & iScriptRc, LogTypeInfo
- End if
- ' Standard execution, call the main function in the created class.
- iScriptRc = eval(sMain)
- ProcessResults iScriptRc
- Wscript.quit iScriptRc
- end function
- Function ConvertBooleanToString(bValue)
- Dim iRetVal
- iRetVal = Failure
- If bValue = -1 Then
- iRetVal = "True"
- ElseIf bValue = 0 Then
- iRetVal = "False"
- End If
- ConvertBooleanToString = iRetVal
- End Function
- Sub ResetLocalRootPath
- sLocalRootPath = empty
- End sub
- Property Get CacheLocalRootPath
- CacheLocalRootPath = bCacheLocalRootPath
- End Property
- Property Let CacheLocalRootPath(bNew)
- bCacheLocalRootPath = bNew
- End Property
- Public Property Get VersionMajor
- VersionMajor = iVersionMajor
- End Property
- Public Property Get VersionMinor
- VersionMinor = iVersionMinor
- End Property
- Public Property Get BuildNumber
- BuildNumber = iBuildNumber
- End Property
- Public Property Get RevisionNumber
- RevisionNumber = iRevision
- End Property
- Property Get LocalRootPath
- Dim sFallBack
- If bCacheLocalRootPath and (not IsEmpty(sLocalRootPath)) then
- LocalRootPath = sLocalRootPath ' Cache the value. Enumeration of Drives can be time expensive.
- Exit property
- End if
- If oEnvironment.GetOSDV4("_SMSTSBootImageID") <> "" then
- LocalRootPath = oEnvironment.GetOSDV4("_SMSTSMDataPath")
- Else
- LocalRootPath = ""
- If oEnv("SystemDrive") = "X:" then
- ' We're in PE
- sFallBack = "X:\MININT"
- Else
- ' We're in a full OS
- sFallBack = "C:\MININT"
- End if
- End if
- ' --------------------------------------------
- If LocalRootPath = "" or IsEmpty(LocalRootPath) then
- For each oDrive in oFSO.Drives
- If oDrive.DriveType = 2 and oDrive.DriveLetter<>"X" then
- If oDrive.IsReady Then
- If OFSO.FolderExists(oDrive.DriveLetter & ":\MININT\SMSOSD\OSDLOGS") then
- LocalRootPath = oDrive.DriveLetter & ":\MININT"
- Exit For
- End if
- If oFSO.FolderExists(oDrive.DriveLetter & ":\_SMSTaskSequence") then
- sFallBack = oDrive.DriveLetter & ":\MININT"
- End if
- End If
- End if
- Next
- If LocalRootPath = "" or IsEmpty(LocalRootPath) then
- LocalRootPath = sFallBack
- End if
- End if
- ' Make sure the root path exists
- oUtility.VerifyPathExists LocalRootPath
- ' Cache the value
- sLocalRootPath = LocalRootPath
- End Property
- Property Get BootDevice
- BootDevice = UCase(oShell.Regread("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SystemBootDevice"))
- End Property
- Property Get LogPath
- If oEnvironment.GetOSDV4("_SMSTSBootImageID") <> "" then
- LogPath = oEnvironment.GetOSDV4("_SMSTSLogPath")
- Else
- LogPath = LocalRootPath & "\SMSOSD\OSDLOGS"
- End if
- oUtility.VerifyPathExistsEx LogPath, False
- End Property
- Property Get StatePath
- Dim sBasePath
- ' Always use the root of the drive.
- sBasePath = "\"
- ' We want to store user state on the same volume as the OS.
- If oEnv("SystemDrive") <> "X:" then
- StatePath = oEnv("SystemDrive") & sBasePath & "StateStore"
- Else
- ' We're offline, so try to use OSDWinPEWinDir, which should be set before reaching here
- If oFSO.FolderExists(oEnvironment.Item("OSDWinPEWinDir")) then
- ' Use the drive that OSDWinPEWinDir points to
- StatePath = Left(oEnvironment.Item("OSDWinPEWinDir"), 2) & sBasePath & "StateStore"
- Else
- ' Fallback logic - put the folder on the local root path
- StatePath = Left(LocalRootPath, 2) & sBasePath & "StateStore"
- End if
- End if
- End Property
- Property Get ScriptName
- On Error Resume Next
- ScriptName = oFSO.GetBaseName(Wscript.ScriptName)
- If Err then
- ScriptName = oFSO.GetBaseName(Unescape(window.location.pathname))
- End if
- On Error Goto 0
- End Property
- Property Get ScriptDir
- ScriptDir = sScriptDir
- End Property
- Public Function ReadIni(file, section, item)
- Dim line, equalpos, leftstring, ini
- ReadIni = ""
- file = Trim(file)
- item = Trim(item)
- On Error Resume Next
- Set ini = oFSO.OpenTextFile( file, 1, False)
- If Err then
- Err.Clear
- Exit Function
- End if
- On Error Goto 0
- Do While (not ini.AtEndOfStream)
- line = ini.ReadLine
- line = oStrings.TrimAllWS(line)
- If LCase(line) = "[" & LCase(section) & "]" and (not ini.AtEndOfStream) Then
- line = ini.ReadLine
- line = oStrings.TrimAllWS(line)
- Do While Left( line, 1) <> "["
- 'If InStr( 1, line, item & "=", 1) = 1 Then
- equalpos = InStr(1, line, "=", 1 )
- If equalpos > 0 Then
- leftstring = Left(line, equalpos - 1 )
- leftstring = oStrings.TrimAllWS(leftstring)
- If LCase(leftstring) = LCase(item) Then
- ReadIni = Mid( line, equalpos + 1 )
- ReadIni = oStrings.TrimAllWS(ReadIni)
- Exit Do
- End If
- End If
- If ini.AtEndOfStream Then Exit Do
- line = ini.ReadLine
- line = oStrings.TrimAllWS(line)
- Loop
- Exit Do
- End If
- Loop
- ini.Close
- End Function
- Public Sub WriteIni( file, section, item, myvalue )
- Dim in_section, section_exists, item_exists, wrote, itemtrimmed
- Dim read_ini, write_ini, temp_ini, linetrimmed, line, equalpos
- Dim leftstring
- in_section = False
- section_exists = False
- item_exists = ( ReadIni( file, section, item ) <> "" )
- wrote = False
- file = Trim(file)
- itemtrimmed = Trim(item)
- myvalue = Trim(myvalue)
- temp_ini = oFSO.GetParentFolderName(file) & "\" & oFSO.GetTempName
- Set read_ini = oFSO.OpenTextFile( file, 1, True, False )
- Set write_ini = oFSO.CreateTextFile( temp_ini, False)
- While read_ini.AtEndOfStream = False
- line = read_ini.ReadLine
- linetrimmed = Trim(line)
- If wrote = False Then
- If LCase(line) = "[" & LCase(section) & "]" Then
- section_exists = True
- in_section = True
- ElseIf InStr( line, "[" ) = 1 Then
- in_section = False
- End If
- End If
- If in_section Then
- If itemtrimmed = "" then
- ' Do nothing: we want to wipe the section
- ElseIf item_exists = False Then
- write_ini.WriteLine line
- If myvalue <> "" then
- write_ini.WriteLine item & "=" & myvalue
- End if
- wrote = True
- in_section = False
- Else
- equalpos = InStr(1, line, "=", 1 )
- If equalpos > 0 Then
- leftstring = Left(line, equalpos - 1 )
- leftstring = Trim(leftstring)
- If LCase(leftstring) = LCase(item) Then
- If myvalue <> "" then
- write_ini.WriteLine itemtrimmed & "=" & myvalue
- End if
- wrote = True
- in_section = False
- End If
- End If
- If Not wrote Then
- write_ini.WriteLine line
- End If
- End If
- Else
- write_ini.WriteLine line
- End If
- Wend
- If section_exists = False and itemtrimmed <> "" Then ' section doesn't exist
- write_ini.WriteLine
- write_ini.WriteLine "[" & section & "]"
- If myvalue <> "" then
- write_ini.WriteLine itemtrimmed & "=" & myvalue
- End if
- End If
- read_ini.Close
- write_ini.Close
- If oFSO.FileExists(file) then
- oFSO.DeleteFile file, True
- End if
- oFSO.CopyFile temp_ini, file, true
- oFSO.DeleteFile temp_ini, True
- End Sub
- Public Function Sections(file)
- Dim oContents
- Dim line, equalpos, leftstring, ini
- Set oContents = CreateObject("Scripting.Dictionary")
- file = Trim(file)
- On Error Resume Next
- Set ini = oFSO.OpenTextFile( file, 1, False)
- If Err then
- Err.Clear
- Exit Function
- End if
- On Error Goto 0
- Do While ini.AtEndOfStream = False
- line = ini.ReadLine
- line = Trim(line)
- If Left(line,1) = "[" then
- equalpos = Instr(line, "]")
- leftstring = Mid(line, 2, equalpos - 2)
- oContents.Add leftstring, ""
- End if
- Loop
- Set Sections = oContents
- End Function
- Public Function SectionContents(file, section)
- Dim oContents
- Dim line, equalpos, leftstring, ini
- Set oContents = CreateObject("Scripting.Dictionary")
- file = Trim(file)
- section = Trim(section)
- On Error Resume Next
- Set ini = oFSO.OpenTextFile( file, 1, False)
- If Err then
- Err.Clear
- Exit Function
- End if
- On Error Goto 0
- Do While ini.AtEndOfStream = False
- line = ini.ReadLine
- line = Trim(line)
- If LCase(line) = "[" & LCase(section) & "]" Then
- line = ini.ReadLine
- line = Trim(line)
- Do While Left( line, 1) <> "["
- 'If InStr( 1, line, item & "=", 1) = 1 Then
- equalpos = InStr(1, line, "=", 1 )
- If equalpos > 0 Then
- leftstring = Left(line, equalpos - 1 )
- leftstring = Trim(leftstring)
- oContents(leftstring) = Trim(Mid(line, equalpos + 1 ))
- End If
- If ini.AtEndOfStream Then Exit Do
- line = ini.ReadLine
- line = Trim(line)
- Loop
- Exit Do
- End If
- Loop
- ini.Close
- Set SectionContents = oContents
- End Function
- Function RegReadEx ( sRegValue, bError )
- on error resume next
- RegReadEx = oShell.Regread( sRegValue )
- If bError then
- TestAndLog not isempty(RegReadEx), "ReadRead(" & sRegValue & ")"
- End if
- on error goto 0
- End function
- Function RegWriteEx ( sKey, sValue, bError )
- on error resume next
- if VarType(sValue) = vbString then
- RegWriteEx = oShell.RegWrite ( sKey, sValue, "REG_SZ" )
- elseif VarType(sValue) = vbInteger or VarType(sValue) = vbLong or VarType(sValue) = vbBoolean then
- RegWriteEx = oShell.RegWrite ( sKey, sValue, "REG_DWORD" )
- end if
- If bError then
- TestAndLog (err = 0), "RegWriteEx( " & sKey & " , " & sValue & " , REG_Type )"
- End if
- on error goto 0
- End function
- Function RegRead( sRegValue )
- RegRead = RegReadEx(sRegValue, True)
- end Function
- Function RegWrite ( sKey, sValue )
- RegWrite = RegWriteEx(sKey, sValue, True)
- end Function
- Function SafeSleep ( iTime )
- On error resume next
- WScript.Sleep iTime
- On error goto 0
- End function
- ' ---------------------------------------------------------------
- Function RunCommandLog( oExec, fExternalHook, iLimit )
- Dim HeartbeatStart
- Dim iMinutes
- Dim iHeartBeat
- Dim iLastProgress
- Dim iResult
- ' Initialize the last heartbeat time (start the timer) and interval
- HeartbeatStart = Now
- iLastProgress = 0
- iResult = SUCCESS
- ' Main Processing Loop
- do while oExec.Status = 0
- ' See if it is time for a heartbeat
- iMinutes = DateDiff("n", HeartbeatStart, now )
- If iMinutes >= iLimit and iLimit <> -1 and VarType(iLimit) = 2 then
- oLogging.CreateEvent 41009, LogTypeError, "Command has been running for " & CStr(iMinutes) & " minutes (process ID " & oExec.ProcessID & "). Now over limit!", Array(iMinutes)
- RunCommandLog = False
- exit function
- End if
- Heartbeat "ZTI Heartbeat: command has been running for " & CStr(iMinutes) & " minutes (process ID " & oExec.ProcessID & ")"
- If IsNull(fExternalHook) then
- SafeSleep 100
- Else
- SafeSleep 1
- If VarType(fExternalHook) = 9 then
- iResult = fExternalHook(oExec, iLastProgress) ' fExternal Hook is a GetRef( function )
- ElseIf VarType(fExternalHook) = 8 then
- iResult = execute( fExternalHook ) ' fExternalHook is a string function
- Else
- iResult = StandardConsoleProcessing(oExec, iLastProgress) ' Do standard processing
- End if
- If iResult <> SUCCESS then
- Exit do
- End if
- End if
- loop
- If IsNull(fExternalHook) or iResult <> SUCCESS then
- SafeSleep 100
- Else
- ' Jump to the end of the sub-progress if started
- If not IsEmpty(iLastProgress) and iLastProgress > 9 and iLastProgress < 91 then
- oLogging.ReportProgress "process ID " & oExec.ProcessID & " Finished ", 100
- End if
- If VarType(fExternalHook) = 9 then
- iResult = fExternalHook(oExec, iLastProgress) ' fExternal Hook is a GetRef( function )
- ElseIf VarType(fExternalHook) = 8 then
- iResult = execute( fExternalHook ) ' fExternalHook is a string function
- Else
- iResult = StandardConsoleProcessing(oExec, iLastProgress) ' Do standard processing
- End if
- End if
- ' Return the exit code to the caller
- oLogging.CreateEntry "Return code from command = " & oExec.ExitCode, LogTypeInfo
- RunCommandLog = oExec.ExitCode
- End function
- Function Heartbeat(sMessage)
- Dim iMinutes
- If DateDiff("n", lastHeartbeat, Now ) >= 5 then
- lastHeartbeat = Now
- iMinutes = DateDiff("n", startTime, lastHeartbeat)
- oLogging.CreateEvent 41003, LogTypeInfo, sMessage, Array(iMinutes)
- End if
- End function
- Function StandardConsoleProcessing ( oExec, byRef iLastProgress )
- Dim sLines
- Dim sLine
- Dim oMatch
- StandardConsoleProcessing = SUCCESS
- Do Until oExec.StdOut.atEndOfStream
- sLines = oExec.StdOut.ReadLine
- if vartype(sLines) = 8 then
- For each sLine in split(sLines,vbNewLine)
- If asc(mid(sline,1,1)) = 0 then
- sLine = replace(sLine,chr(0),"") ' Quick and dirty Unicode to ANSI fix.
- End if
- oLogging.CreateEntry " Console > " & sLine, LogTypeInfo
- if oExec.Status = 0 then
- ' If the output contains a percentage, then interpret it a status.
- ' Check for DISM-style progress
- Set oMatch = oRegEx.GetRegExMatches("([01]?[0-9]?[0-9])\.[0-9]\%",sLine)
- If oMatch.Count > 0 then
- iLastProgress = cint(oMatch(oMatch.Count -1).SubMatches(0))
- oLogging.ReportProgress sLine, iLastProgress
- Else
- ' Check for "other" percentage
- set oMatch = oRegEx.GetRegExMatches("([01]?[0-9]?[0-9]) ?\%",sLine)
- If oMatch.Count > 0 then
- iLastProgress = cint(oMatch(oMatch.Count -1).SubMatches(0))
- oLogging.ReportProgress sLine, iLastProgress
- End if
- End if
- End if
- Next
- End if
- if oExec.Status = 0 then
- Exit Function
- End if
- Loop
- if oExec.Status <> 0 then
- StandardConsoleProcessing = FAILURE
- Else
- do until oExec.StdErr.atEndOfStream
- sLines = oExec.StdErr.ReadAll
- if vartype(sLine) = 8 then
- For each sLine in split(sLines,vbNewLine)
- If asc(mid(sline,1,1)) = 0 then
- sLine = replace(sLine,chr(0),"") ' Quick and dirty Unicode to ANSI fix.
- End if
- oLogging.CreateEntry " Console # " & sLine, LogTypeError
- Next
- End if
- loop
- End if
- End Function
- Function StandardFileProcessing ( oExec, ByRef iLastProgress, sExternalLogFile )
- Dim oMatch
- If oExec.Status = 0 then
- If oFSO.FileExists(sExternalLogFile) then
- set oMatch = oRegEx.GetRegExMatchesFromFile(sProgress,sExternalLogFile)
- If oMatch.Count > 0 then
- If cint(oMatch(oMatch.Count - 1).SubMatches(0)) > iLastProgress then
- iLastProgress = cint(oMatch(oMatch.Count - 1).SubMatches(0))
- oLogging.ReportProgress "Progress [" & sExternalLogFile & "] ... " & iLastProgress & "%", iLastProgress
- exit function
- End if
- End if
- End if
- End if
- oUtility.SafeSleep 100
- End function
- Function RunCommandStart(sCmd, aInput)
- Dim oExec
- Dim sLine
- ' Start the command
- oLogging.CreateEntry "About to run command: " & sCmd, LogTypeInfo
- Set oExec = oShell.Exec(sCmd)
- oLogging.CreateEntry "Command has been started (process ID " & oExec.ProcessID & ")", LogTypeInfo
- ' Log any input lines
- If isArray( aInput ) then
- For each sLine in aInput
- RunCommandWrite oExec, sLine
- next
- End if
- set RunCommandStart = oExec
- End function
- Function RunCommandWrite( oExec, sCommand )
- If sCommand <> "" then
- oLogging.CreateEntry " Console + " & sCommand, LogTypeInfo
- oExec.stdIn.WriteLine sCommand
- End if
- End function
- Function RunCommandEx(sCmd, aInput, fExternalHook, iLimit )
- Dim oExec
- ' Start the command
- set oExec = RunCommandStart(sCmd, aInput)
- SafeSleep 500
- ' Wait for the results
- RunCommandEx = RunCommandLog (oExec, fExternalHook, iLimit )
- End function
- Function RunWithHeartbeat(sCmd)
- RunWithHeartbeat = RunCommandEx(sCmd, null, null, -1)
- End function
- Function RunWithConsoleLogging(sCmd)
- RunWithConsoleLogging = RunCommandEx(sCmd, empty, empty, -1)
- End function
- Function RunWithConsoleLoggingAndHidden(sCmd)
- Dim iRC
- Dim sScriptFile
- iRC = oUtility.FindFile( "ztiRunCommandHidden.wsf", sScriptFile )
- TestAndLog iRC, "Verify ztiRunCommandHidden.wsf is in the path"
- If iRC = Success then
- RunWithConsoleLoggingAndHidden = RunCommand ( "cscript.exe //nologo """ & sScriptFile & """ """ & sCmd & """", 0, True)
- Else
- oLogging.CreateEntry "Visible console fallback." , LogTypeInfo
- RunWithConsoleLoggingAndHidden = oUtility.RunWithConsoleLogging( sCmd )
- End if
- End function
- Function FindExeAndRunWithLogging( sCmd, sParameters )
- Dim iRC
- Dim sFoundFile
- iRC = oUtility.FindFile ( sCmd, sFoundFile )
- TestAndFail iRC, 5441, "FindFile: " & sCmd
- FindExeAndRunWithLogging = RunWithConsoleLogging( """" & sFoundFile & """ " & sParameters )
- End function
- Function FindExeAndRun( sCmd, sParameters )
- Dim iRC
- Dim sFoundFile
- iRC = oUtility.FindFile ( sCmd, sFoundFile )
- TestAndFail iRC, 5442, "FindFile: " & sCmd
- FindExeAndRun = RunWithHeartbeat( """" & sFoundFile & """ " & sParameters )
- End function
- Function RunCommand ( sCmd, iWindowStyle, bWaitOnReturn )
- oLogging.CreateEntry "About to run command: " & sCmd, LogTypeInfo
- RunCommand = oShell.Run ( sCmd, iWindowStyle, bWaitOnReturn )
- oLogging.CreateEntry "Command has returned: " & RunCommand, LogTypeInfo
- End Function
- Function ComputerName
- Dim re
- Dim sComputer
- Set re = New RegExp
- ' Figure out the computer name to include
- If oEnvironment.Item("_SMSTSMachineName") <> "" then
- If oEnvironment.Item("OSDCOMPUTERNAME") <> "" and Instr(oEnvironment.Item("OSDCOMPUTERNAME"),":") = 0 then
- sComputer = oEnvironment.Item("OSDComputerName")
- Else
- sComputer = oEnvironment.Item("_SMSTSMachineName")
- End If
- ElseIf oEnvironment.Item("OSDCOMPUTERNAME") <> "" and Instr(oEnvironment.Item("OSDCOMPUTERNAME"),":") = 0 then
- sComputer = oEnvironment.Item("OSDCOMPUTERNAME")
- ElseIf oEnvironment.Item("OSDNEWMACHINENAME") <> "" then
- oEnvironment.Item("OSDComputerName") = oEnvironment.Item("OSDNEWMACHINENAME")
- sComputer = oEnvironment.Item("OSDCOMPUTERNAME")
- ElseIf oEnvironment.Item("ComputerName") <> "" then
- oEnvironment.Item("OSDComputerName") = oEnvironment.Item("ComputerName")
- sComputer = oEnvironment.Item("OSDComputerName")
- ElseIf oEnvironment.Item("OSVersion") = "WinPE" and oEnvironment.Item("OSDCOMPUTERNAME") <> "" then
- sComputer = oEnvironment.Item("OSDCOMPUTERNAME")
- re.Pattern = ":"
- sComputer = re.Replace(sComputer, "")
- Else
- sComputer = oEnvironment.Item("HostName")
- End if
- ComputerName = oEnvironment.Substitute(sComputer)
- End Function
- Function FindFile(sFilename, sFoundPath)
- Dim iRetVal
- Dim sDir
- iRetVal = Failure
- sFoundPath = ""
- ' Look through the standard locations
- If oEnvironment.Item("DeployRoot") <> "" then
- For each sDir in Array("\", "\Tools\", "\Servicing\", "\Scripts\", "\Control\", "\Templates\", "\x86\", "\amd64\")
- If oFSO.FileExists(oEnvironment.Item("DeployRoot") & sDir & sFileName) then
- sFoundPath = oEnvironment.Item("DeployRoot") & sDir & sFileName
- iRetVal = Success
- Exit For
- ElseIf oEnvironment.Item("Architecture") <> "" and oFSO.FileExists(oEnvironment.Item("DeployRoot") & sDir & oEnvironment.Item("Architecture") & "\" & sFileName) then
- sFoundPath = oEnvironment.Item("DeployRoot") & sDir & oEnvironment.Item("Architecture") & "\" & sFileName
- iRetVal = Success
- Exit For
- ' oEnvironment.Item("Architecture") *can* be blank, search in the %Processor_Architecture% directory.
- ElseIf ucase(oEnv("Processor_Architecture")) = "AMD64" and oFSO.FileExists(oEnvironment.Item("DeployRoot") & sDir & "x64\" & sFileName) then
- sFoundPath = oEnvironment.Item("DeployRoot") & sDir & "x64\" & sFileName
- iRetVal = Success
- Exit For
- ElseIf oFSO.FileExists(oEnvironment.Item("DeployRoot") & sDir & oEnv("Processor_Architecture") & "\" & sFileName) then
- sFoundPath = oEnvironment.Item("DeployRoot") & sDir & oEnv("Processor_Architecture") & "\" & sFileName
- iRetVal = Success
- Exit For
- End if
- Next
- End if
- If sFoundPath <> "" then
- FindFile = iRetVal
- Exit Function
- End if
- ' Check resource root locations (normally OSD only)
- If oEnvironment.Item("ResourceRoot") <> "" and oEnvironment.Item("ResourceRoot") <> oEnvironment.Item("DeployRoot") then
- For each sDir in Array("\", "\Tools\", "\Servicing\", "\Scripts\", "\Templates\", "\Control\")
- If oFSO.FileExists(oEnvironment.Item("ResourceRoot") & sDir & sFileName) then
- sFoundPath = oEnvironment.Item("ResourceRoot") & sDir & sFileName
- iRetVal = Success
- Exit For
- ElseIf oFSO.FileExists(oEnvironment.Item("ResourceRoot") & sDir & oEnvironment.Item("Architecture") & "\" & sFileName) then
- sFoundPath = oEnvironment.Item("ResourceRoot") & sDir & oEnvironment.Item("Architecture") & "\" & sFileName
- iRetVal = Success
- Exit For
- End if
- Next
- End if
- If sFoundPath <> "" then
- FindFile = iRetVal
- Exit Function
- End if
- ' Now look in the log directory, this directory, working directory, and SYSTEM32 directory
- If oFSO.FileExists(oUtility.LogPath & "\" & sFilename) then
- sFoundPath = oUtility.LogPath & "\" & sFilename
- iRetVal = Success
- ElseIf oFSO.FileExists(oUtility.ScriptDir & "\" & sFilename) then
- sFoundPath = oUtility.ScriptDir & "\" & sFilename
- iRetVal = Success
- ElseIf oFSO.FileExists(oUtility.LocalRootPath & "\" & sFileName) then
- sFoundPath = oUtility.LocalRootPath & "\" & sFileName
- iRetVal = Success
- ElseIf oFSO.FileExists(".\" & sFileName) then
- sFoundPath = oShell.CurrentDirectory & "\" & sFilename
- iRetVal = Success
- ElseIf oFSO.FileExists(oEnvironment.Substitute("%WINDIR%\SYSNATIVE\" & sFilename)) then
- sFoundPath = oEnvironment.Substitute("%WINDIR%\SYSNATIVE\" & sFilename)
- iRetVal = Success
- ElseIf oFSO.FileExists(oEnvironment.Substitute("%WINDIR%\SYSTEM32\" & sFilename)) then
- sFoundPath = oEnvironment.Substitute("%WINDIR%\SYSTEM32\" & sFilename)
- iRetVal = Success
- ElseIf oEnvironment.Item("OSDPACKAGEPATH") <> "" and oFSO.FileExists(oEnvironment.Item("OSDPACKAGEPATH") & "\" & sFilename) then
- sFoundPath = oEnvironment.Item("OSDPACKAGEPATH") & "\" & sFilename
- iRetVal = Success
- ElseIf oEnvironment.Item("_SMSTSPackagePath") <> "" and oFSO.FileExists(oEnvironment.Item("_SMSTSPackagePath") & "\" & sFilename) then
- sFoundPath = oEnvironment.Item("_SMSTSPackagePath") & "\" & sFilename
- iRetVal = Success
- ElseIf oFSO.FileExists(".\x86\" & sFileName) then
- sFoundPath = oShell.CurrentDirectory & "\x86\" & sFilename
- iRetVal = Success
- ElseIf oFSO.FileExists(".\x64\" & sFileName) then
- sFoundPath = oShell.CurrentDirectory & "\x64\" & sFilename
- iRetVal = Success
- ElseIf oFSO.FileExists(".\amd64\" & sFileName) then
- sFoundPath = oShell.CurrentDirectory & "\amd64\" & sFilename
- iRetVal = Success
- ElseIf oFSO.FileExists(sFileName) then
- sFoundPath = sFilename
- iRetVal = Success
- End if
- If iRetVal <> Success then
- oLogging.CreateEntry "FindFile: The file " & sFilename & " could not be found in any standard locations.", LogTypeInfo
- End if
- FindFile = iRetVal
- End Function
- Function FindMappedDrive(sServerUNC)
- Dim arrSplit
- Dim sServerShare, sServerName
- Dim arrDrives, i
- ' If the UNC isn't a UNC, just return the drive letter
- If Len(sServerUNC) < 3 then
- FindMappedDrive = ""
- EXIT FUNCTION
- End if
- If Mid(sServerUNC,2,2) = ":\" then
- FindMappedDrive = Left(sServerUNC, 2)
- EXIT FUNCTION
- End if
- ' Build the UNC
- If Instr(Mid(sServerUNC, 3), "\") <= 0 or Left(sServerUNC, 2) <> "\\" then
- FindMappedDrive = ""
- EXIT FUNCTION
- End if
- arrSplit = Split(Mid(sServerUNC,3), "\",2)
- sServerName = arrSplit(0)
- sServerShare = "\\" & sServerName & "\" & arrSplit(1)
- ' Look to see if this is a mapped drive
- On Error Resume Next
- Set arrDrives = oNetwork.EnumNetworkDrives
- If Err then
- FindMappedDrive = ""
- Exit Function
- Else
- On Error Goto 0
- For i = 0 to arrDrives.Count - 1 Step 2
- If UCase(sServerShare) = UCase(arrDrives.Item(i+1)) and arrDrives.Item(i) <> "" then
- FindMappedDrive = arrDrives.Item(i)
- Exit Function
- End if
- Next
- End if
- On Error Goto 0
- FindMappedDrive = ""
- End Function
- Function ValidateConnection(sServerUNC)
- ValidateConnection = ValidateConnectionEx(sServerUNC, False)
- End function
- Function GetNextNAACred(Index)
- Dim iMaxNumLength
- Dim sNumberAsString
- Dim sNAAName
- Dim sNAAPass
- iMaxNumLength = 3
- sNAAName = "_SMSTSReserved1-"
- sNAAPass = "_SMSTSReserved2-"
- If Index <= 0 Then
- sNumberAsString = "000"
- Else
- sNumberAsString = String(iMaxNumLength - Fix(Log(Fix(Index)) / Log(10)) - 1, "0") & CStr(Fix(Index))
- End If
- sNAAName = sNAAName & sNumberAsString
- sNAAPass = sNAAPass & sNumberAsString
- If oEnvironment.Item(sNAAName) <> "" AND oEnvironment.Item(sNAAPass) <> "" Then
- OEnvironment.Item("UserDomain") = Left(oEnvironment.Item(sNAAName),Instr(oEnvironment.Item(sNAAName),"\")-1)
- oEnvironment.Item("UserID")= Mid(oEnvironment.Item(sNAAName),Instr(oEnvironment.Item(sNAAName),"\")+1)
- oEnvironment.Item("UserPassword")=oEnvironment.Item(sNAAPass)
- GetNextNAACred = True
- Else
- GetNextNAACred = False
- End if
- End Function
- Function ValidateConnectionEx(sServerUNC, bForceConnection)
- Dim iRetVal
- Dim arrSplit
- Dim sServerShare, sServerName, sFoundDrive
- Dim sOSDConnectToUNC, sRIPInfo, sCmd
- Dim sWizardHTA, sUserID
- Dim sCurrentServerName, i
- ' Make sure a UNC is specified
- If sServerUNC = "" then
- oLogging.CreateEntry "WARNING - Unable to validation connection because a blank UNC was specified.", LogTypeWarning
- ValidateConnectionEx = Failure
- EXIT FUNCTION
- End if
- If Mid(sServerUNC,2,2) = ":\" then
- oLogging.CreateEntry "Using a local or mapped drive, no connection is required.", LogTypeInfo
- ValidateConnectionEx = Success
- EXIT FUNCTION
- End if
- oLogging.CreateEntry "Validating connection to " & sServerUNC, LogTypeInfo
- iRetVal = ValidateNetworkConnectivity
- If iRetVal <> Success then
- 'blow up
- ValidateConnectionEx = Failure
- Exit Function
- End IF
- ' See if we've already connected
- If bForceConnection then
- ' When forcing a connection, map all the way down to the specified folder
- arrSplit = Split(Mid(sServerUNC,3), "\", 2)
- Else
- ' When not forcing, split into more chunks so we only get server and share
- arrSplit = Split(Mid(sServerUNC,3), "\")
- End if
- sServerName = arrSplit(0)
- sServerShare = "\\" & sServerName & "\" & arrSplit(1)
- oLogging.CreateEntry "Mapping server share: " & sServerShare, LogTypeInfo
- ' This isn't necessary if we're trying to connect to the current DP, so check that.
- If Left(oUtility.ScriptDir, 2) = "\\" then
- arrSplit = Split(Mid(oUtility.ScriptDir, 3), "\")
- sCurrentServerName = arrSplit(0)
- If UCase(sServerName) = UCase(sCurrentServerName) then
- oLogging.CreateEntry "Already connected to server " & sServerName & " as that is where this script is running from.", LogTypeInfo
- If bForceConnection then
- ' We want a mapped drive in this case, without credentials because we are already connected
- If MapNetworkDrive(sServerShare, "", "") <> Success then
- oLogging.CreateEntry "Unable to map a drive to the deployment share.", LogTypeInfo
- End if
- End if
- ValidateConnectionEx = Success
- EXIT FUNCTION
- End if
- End if
- ' Now see if there is already a server connection.
- ' We may wish to use bForceConnection if we *Require* the Drive letter,
- ' even though the computer may be connected to the sever via another share.
- If dicNetworkConnections.Exists(sServerName) and not bForceConnection then
- oLogging.CreateEntry "Already connected to server " & sServerName, LogTypeInfo
- ValidateConnectionEx = Success
- EXIT FUNCTION
- End if
- 'Map the SCCM user variables to the CS.INI variables
- GetNextNAACred 0 'Attempt to get first NAA info
- ' It is possible that the server allows anonymous connections, skip if the share is readable.
- 'if oFso.FolderExists(sServerName) then
- ' oLogging.CreateEntry "Already connected to server " & sServerName, LogTypeInfo
- ' ValidateConnectionEx = Success
- ' EXIT FUNCTION
- 'end if
- ' If no credentials are available, prompt. (Only works in WinPE)
- If oEnvironment.Item("UserID") = "" or oEnvironment.Item("UserPassword") = "" or ( oEnvironment.Item("UserDomain") = "" and _
- instr(1,oEnvironment.Item("UserID"),"\",vbTextCompare) = 0 and instr(1,oEnvironment.Item("UserID"),"@",vbTextCompare) = 0 ) then
- ' Find the HTA that prompts for credentials
- iRetVal = FindFile("Wizard.hta", sWizardHTA)
- If iRetVal <> Success then
- oLogging.CreateEntry "ERROR - Unable to find Wizard.hta, so it is impossible to prompt for credentials.", LogTypeError
- ValidateConnectionEx = Failure
- Exit Function
- End if
- ' Execute the HTA
- oShell.Run "mshta.exe """ & sWizardHTA & """ /NotWizard /LeaveShareOpen /ValidateAgainstUNCPath:""" & sServerShare & """ /Definition:Credentials_ENU.xml", 1, true
- ' See if the values are populated now
- If oEnvironment.Item("UserID") = "" then
- oLogging.CreateEntry "ERROR - no credentials were returned from LTICredentials.hta, so no connection is possible.", LogTypeError
- ValidateConnectionEx = Failure
- Exit Function
- End if
- End if
- ' Map a drive
- Dim iTryIteration
- Dim bAnotherNAA
- iTryIteration = 1
- bAnotherNAA = True
- Do
- If oEnvironment.Item("UserDomain") <> "" then
- sUserID = oEnvironment.Item("UserDomain") & "\" & oEnvironment.Item("UserID")
- Else
- sUserID = oEnvironment.Item("UserID")
- End if
- For i = 1 to 5
- If MapNetworkDrive(sServerShare, sUserID, oEnvironment.Item("UserPassword")) = Success then
- Exit for
- End If
- oLogging.CreateEntry "Unable to connect to " & sServerShare & ". Sleeping for " & CStr(i * 5) & " seconds.", LogTypeInfo
- On error Resume next
- WScript.Sleep i * 5000
- on error goto 0
- Next
- If IsNetworkDriveMapped(sServerShare) = True Then Exit Do
- 'After 5 failures, try another account
- bAnotherNAA = GetNextNAACred(iTryIteration)
- iTryIteration = iTryIteration + 1
- If Not bAnotherNAA Then
- oLogging.CreateEntry "ERROR - Unable to map a network drive to " & sServerShare & ".", LogTypeError
- ValidateConnectionEx = Failure
- Exit Function
- End If
- Loop While bAnotherNAA = True
- ' Record the mapped drive
- oLogging.CreateEntry "Successfully established connection using supplied credentials.", LogTypeInfo
- If not dicNetworkConnections.Exists(sServerName) then
- dicNetworkConnections.Add sServerName, sServerShare
- End if
- iRetVal = Success
- ValidateConnectionEx = iRetVal
- End Function
- Function ValidateNetworkConnectivity
- Dim Entity, ID, oAdapter, oAdapter2, colAdapters, colAdapters2, sIPConnectionMetric, sWirelessConnectionMetric
- Dim bValidIP
- ' Check for networkadapters present
- bValidIP = True
- If objWMI.ExecQuery("select * from win32_NetworkAdapter where Installed = true and adaptertypeid = 0").Count = 0 then
- oLogging.CreateEntry "No networking adapters found, The network drivers for your device are not present",LogTypeError
- ValidateNetworkConnectivity = Failure
- exit function
- End if
- 'Check for IP address
- Set colAdapters = objWMI.ExecQuery("select * from win32_NetworkAdapterConfiguration where IPEnabled=True")
- For Each oAdapter in colAdapters
- If oAdapter.DHCPEnabled = TRUE Then
- If oAdapter.DHCPServer = "255.255.255.255" Then
- bValidIP = False
- Else
- bValidIP = True
- Exit For
- End if
- Else
- oLogging.CreateEntry "DHCP is not enabled, assuming static IP address", LogTypeInfo
- bValidIP = True
- Exit For
- End if
- Next
- If bValidIP <> True Then
- 'No IP Address, do an ipconfig /renew
- oShell.Run "ipconfig /renew",0,true
- on error resume next
- wscript.sleep 5000
- on error goto 0
- Set colAdapters2 = objWMI.ExecQuery("select * from win32_NetworkAdapterconfiguration where IPEnabled = True")
- For Each oAdapter2 in colAdapters2
- If oAdapter2.DHCPEnabled = TRUE Then
- If oAdapter2.DHCPServer = "255.255.255.255" Then
- oLogging.CreateEntry "IP Address could not be obtained",LogTypeError
- ValidateNetworkConnectivity = Failure
- Exit Function
- Else
- Exit for
- End if
- End if
- Next
- End If
- 'Check for wireless connectivity
- Set colAdapters = objWMI.ExecQuery("select * from win32_NetworkAdapterconfiguration where IPEnabled = True")
- For Each oAdapter in colAdapters
- If Instr(UCase(oAdapter.Caption),"WIRELESS") = 0 Then
- If oAdapter.IPConnectionMetric < sIPConnectionMetric Or sIPConnectionMetric = "" Then
- sIPConnectionMetric = oAdapter.IPConnectionMetric
- End If
- End IF
- If Instr(UCase(oAdapter.Caption),"WIRELESS") Then
- sWirelessConnectionMetric = oAdapter.IPConnectionMetric
- End If
- Next
- If sIPConnectionMetric = "" Then
- oLogging.CreateEntry "No physical adapters present, cannot deploy over wireless", LogTypeError
- ValidatenetworkConnectivity = Failure
- Exit Function
- End IF
- 'TODO Check for VPN connectivity
- ValidateNetworkConnectivity = Success
- End Function
- Function IsNetworkDriveMapped(sShare)
- IsNetworkDriveMapped = False
- If IsEmpty(sShare) Or IsNull(sShare) Or TypeName(sShare) = "Nothing" Then
- oLogging.CreateEntry "Specified network path is null or invalid.", LogTypeError
- Exit Function
- End if
- Dim i
- Dim arrDrives
- On Error Resume Next
- Set arrDrives = oNetwork.EnumNetworkDrives
- If Err then
- oLogging.CreateEntry "Unable to enumerate network drives (is the network initialized?): " & Err.Description & " (" & Err.Number & ")", LogTypeWarning
- Else
- ' Find any previous connections (skip connections without drive letters)
- For i = 0 to arrDrives.Count - 1 Step 2
- If UCase(sShare) = UCase(arrDrives(i+1)) and arrDrives(i) <> "" then
- IsNetworkDriveMapped = True
- oLogging.CreateEntry "Found Existing UNC Path " & arrDrives(i) & " = " & sShare , LogTypeInfo
- Exit function
- End if
- Next
- End if
- End Function
- ' For Backwards Compatiblity
- Function MapNetworkDrive (sShare, sDomID, sDomPwd )
- ' Make sure networking is initialized
- If IsNetworkDriveMapped(sShare) Then
- MapNetworkDrive = Success
- Exit Function
- End If
- If Len(MapNetworkDriveEx (sShare, sDomID, sDomPwd, LogTypeError )) = 2 then
- MapNetworkDrive = Success
- Else
- MapNetworkDrive = Failure
- End if
- End function
- '
- ' maps a drive letter to the sShare UNC path.
- ' Returns the drive letter example: "C:", otherwise returns an error string!
- ' sDomID and sDomPwd can be EMPTY.
- '
- Function MapNetworkDriveEx (sShare, sDomID, sDomPwd, iLogType )
- Dim sDrive
- Dim HasError
- Dim ErrDesc
- Dim i
- On Error Goto 0
- ' Find the first available drive letter
- For sDrive = asc("Z") to asc("C") step -1
- On Error Resume Next
- If sDomID <> "" and sDomPwd <> "" then
- oNetwork.MapNetworkDrive chr(sDrive)&":", sShare, False, sDomID, sDomPwd
- Else
- oNetwork.MapNetworkDrive chr(sDrive)&":", sShare, False
- End if
- HasError = err.number
- ErrDesc = err.Description
- On Error Goto 0
- Select case HasError
- Case 0 ' No Error, SUCCESS
- MapNetworkDriveEx = chr(sDrive)&":"
- oLogging.CreateEntry "Mapped Network UNC Path " & MapNetworkDriveEx & " = " & sShare , LogTypeInfo
- Exit function
- Case &h80070055 ' The local device name is already in use.
- Case &h800704B2 ' The local device name has a remembered connection to another network resource.
- ' Case &h800704C3 ' Multiple connections to a server or shared resource by the same user, using more than one user name, are not allowed.
- ' Case &h8007052E ' Logon failure: unknown user name or bad password.
- Case Else
- oLogging.CreateEntry "Unable to connect to share: " & ErrDesc & "( 0x" & hex(HasError) & " ) , trying to connect without username. ", LogTypeInfo
- Err.Clear
- On Error Resume Next
- oNetwork.MapNetworkDrive chr(sDrive)&":", sShare, False
- HasError = err.number
- ErrDesc = err.Description
- On Error Goto 0
- If HasError <> 0 Then
- ' There was a some kind of fatal error.
- If ErrDesc <> "" then
- MapNetworkDriveEx = ErrDesc
- Else
- MapNetworkDriveEx = "Unable to map UNC Path " & sShare & " :" & "( 0x" & hex(HasError) & " ) "
- End if
- oLogging.CreateEntry MapNetworkDriveEx & "", iLogType
- Exit function
- Else
- MapNetworkDriveEx = chr(sDrive)&":"
- Exit Function
- End If
- End select
- Next
- MapNetworkDriveEx = "Unable to map UNC Path " & sShare & " : No available local device names! "
- oLogging.CreateEntry MapNetworkDriveEx , iLogType
- End function
- Public Function VerifyPathExistsEx(strPath, bAdjustSD)
- Dim oHelper, sSDDL, oLogicalFile, oDescriptor
- If strPath = "" then
- VerifyPathExistsEx = True
- Exit Function
- End if
- If oFSO.FolderExists(strPath) then
- VerifyPathExistsEx = true
- Exit Function
- Else
- VerifyPathExists oFSO.GetParentFolderName(strPath)
- On Error Resume Next
- oFSO.CreateFolder strPath
- 'Set Permissions if it is not a UNC path
- If Left(strPath, 2) <> "\\" and bAdjustSD Then
- strPath = Replace(strPath, "\", "\\")
- Set oHelper = objWMI.Get("Win32_SecurityDescriptorHelper")
- sSDDL = "O:BAG:SYD:PAI(A;OICI;FA;;;BA)(A;OICI;FA;;;SY)"
- oHelper.SDDLToWin32SD sSDDL, oDescriptor
- Set oLogicalFile = objWMI.Get("Win32_LogicalFileSecuritySetting.Path='" & strPath & "'")
- TestAndLog oLogicalFile.SetSecurityDescriptor(oDescriptor), "Set security on folder " & strPath
- End If
- On Error Goto 0
- End if
- End function
- Public Function VerifyPathExists(strPath)
- VerifyPathExists = VerifyPathExistsEx(strPath, false)
- End Function
- Function GetAllFixedDrives(bReturnOnlyBootable)
- Dim oWMIDiskPart
- Dim oDiskPart
- Dim oDisk
- oLogging.CreateEntry "ZTIUtility!GetAllFixedDrives (" & bReturnOnlyBootable & ")", LogTypeInfo
- for each oWMIDiskPart in AllDiskPart
- set oDiskPart = new ZTIDiskPartition
- set oDiskPart.DiskPart = oWMIDiskPart
- set oDisk = oDiskPart.GetDiskObject
- If oDisk.IsOSReady("0.0.0.0") then
- GetAllFixedDrives = GetAllFixedDrives & " " & oDiskPart.Drive
- End if
- next
- oLogging.CreateEntry "ZTIUtility!GetAllFixedDrives = " & GetAllFixedDrives, LogTypeInfo
- GetAllFixedDrives = split(trim(GetAllFixedDrives)," ")
- End function
- '
- ' Create an XMLDOM Object
- '
- Function CreateXMLDOMObjectEx( sFileName )
- Dim bRetVal
- on error resume next
- Set CreateXMLDOMObjectEx = nothing
- Set CreateXMLDOMObjectEx = oUtility.GetMSXMLDOMDocument
- TestAndFail not (CreateXMLDOMObjectEx is nothing), 5490, "Create MSXML2.DOMDocument."
- CreateXMLDOMObjectEx.Async = FALSE
- If sFileName <> "" then
- oLogging.CreateEntry "CreateXMLDOMObjectEx(" & sFileName & ")", LogTypeVerbose
- bRetVal = CreateXMLDOMObjectEx.Load (sFileName )
- TestAndLog bRetVal, "CreateXMLDOMObjectEx...Length = " & CreateXMLDOMObjectEx.documentElement.childNodes.Length
- With CreateXMLDOMObjectEx.ParseError
- If .errorCode <> 0 then
- oLogging.CreateEntry "File: " & sFileName & " Line: " & .Line & " - " & .Reason & " - " & .SrcText, LogTypeWarning
- End if
- End with
- End if
- on error goto 0
- End function
- ' Create an XMLDOM Object, do not return if there is a parse error.
- Function CreateXMLDOMObjectSafe( sFileName )
- Set CreateXMLDOMObjectSafe = CreateXMLDOMObjectEx( sFileName )
- TestAndFail CreateXMLDOMObjectSafe.ParseError.ErrorCode, 5495, "Create MSXML2.DOMDocument .ParseErr.ErrCode."
- End function
- Function CreateXMLDOMObject
- Set CreateXMLDOMObject = CreateXMLDOMObjectEx( empty )
- End function
- ' Load an XML file via FindFile
- Function LoadConfigFile( sConfigFile )
- Set LoadConfigFile = LoadConfigFileEx( sConfigFile, false )
- End function
- ' Load an XML file via FindFile, do not return if there is any error.
- Function LoadConfigFileSafe( sConfigFile )
- Set LoadConfigFileSafe = LoadConfigFileEx( sConfigFile, TRUE )
- End function
- ' Load an XML file via FindFile, do not return if there is any error.
- Function LoadConfigFileEx( sConfigFile, bMustSucceed )
- Dim sFoundFile
- Dim iRetVal
- iRetVal = oUtility.FindFile( sConfigFile , sFoundFile)
- If bMustSucceed then
- TestAndFail iRetVal, 5496, "LoadControlFile.FindFile: " & sConfigFile
- set LoadConfigFileEx = CreateXMLDOMObjectSafe (sFoundFile)
- Else
- set LoadConfigFileEx = CreateXMLDOMObjectEx (sFoundFile)
- End if
- End function
- Function BDDUtility
- Dim sBDDUtility
- Dim iRetval
- Dim sProc
- ' Already retrieved an instance? Return it.
- If not (oBDDUtility is Nothing) then
- Set BDDUtility = oBDDUtility
- Exit Function
- End if
- ' Already registered? Call Routine.
- on error resume next
- Set oBDDUtility = CreateObject("Microsoft.BDD.Utility")
- on error goto 0
- If not (oBDDUtility is Nothing) then
- Set BDDUtility = oBDDUtility
- Exit Function
- End if
- ' Find each Microsoft.BDD.Utility.dll file, and copy locally if over the network.
- for each sProc in array("x86","x64")
- If not oFSO.FileExists(oEnv("TEMP") & "\Tools\" & sProc & "\Microsoft.BDD.Utility.dll") then
- iRetVal = FindFile( sProc & "\Microsoft.BDD.Utility.dll", sBDDUtility)
- oLogging.CreateEntry "FindFile(...\Microsoft.BDD.Utility.dll) Result : " & iRetVal, LogTypeInfo
- If left(sBDDUtility,2) = "\\" then
- oUtility.VerifyPathExistsEx oEnv("TEMP") & "\Tools\" & sProc , false
- oFileHandling.CopyFile sBDDUtility, oEnv("TEMP") & "\Tools\" & sProc & "\", True
- End if
- End if
- If oFSO.FileExists(oEnv("TEMP") & "\Tools\" & sProc & "\Microsoft.BDD.Utility.dll") then
- sBDDUtility = oEnv("TEMP") & "\Tools\" & sProc & "\Microsoft.BDD.Utility.dll"
- End if
- ' Register the DLL
- oLogging.CreateEntry "RUN: regsvr32.exe /s """ & sBDDUtility & """", LogTypeInfo
- oShell.Run "regsvr32.exe /s """ & sBDDUtility & """", 0, true ' Always returns 0 - Success
- next
- ' Create an instance
- on error resume next
- Set oBDDUtility = CreateObject("Microsoft.BDD.Utility")
- TestAndLog not oBDDUtility is nothing, "CreateObject(Microsoft.BDD.Utility)"
- on error goto 0
- Set BDDUtility = oBDDUtility
- End Function
- Private Sub SetIfChanged(sVar, sVal)
- If oEnvironment.Item(sVar) <> sVal then
- oEnvironment.Item(sVar) = sVal
- End if
- End Sub
- Sub SetTaskSequenceProperties(tsID)
- Dim oTaskSequences
- Dim oTaskSequence
- Dim oOperatingSystems
- Dim oOS
- Dim oImageLang
- Dim sImageLang
- Dim oLanguage
- Dim sImagePath
- Dim oWDSServer
- Dim sWDSServer
- Dim objTmp
- Dim oTS
- Dim oOSGUID
- Dim oDestinationDisk,oDestinationPartition,ODestinationLogicalDrive
- Dim sSourcePath
- ' If there is task sequence ID set, get the properties
- If tsID <> "" then
- ' Get the task sequence record
- tsID = Ucase(tsID)
- Set oTaskSequences = oUtility.CreateXMLDOMObjectEx(oEnvironment.Item("DeployRoot") & "\Control\TaskSequences.xml")
- Set oTaskSequence = oTaskSequences.selectSingleNode("//ts[ID='" & tsID & "']")
- If oTaskSequence is Nothing then
- oLogging.CreateEntry "ERROR: Invalid task sequence ID " & tsID & " specified", LogTypeError
- Exit Sub
- End if
- ' Set the simple build properties
- oEnvironment.Item("TaskSequenceName") = oUtility.SelectSingleNodeString(oTaskSequence,"Name")
- oEnvironment.Item("TaskSequenceVersion") = oUtility.SelectSingleNodeStringEx(oTaskSequence,"Version", False)
- oEnvironment.Item("TaskSequenceTemplate") = oUtility.SelectSingleNodeStringEx(oTaskSequence,"TaskSequenceTemplate", False)
- ' Blank out any previous values
- SetIfChanged "ImageIndex", ""
- SetIfChanged "ImageSize", ""
- SetIfChanged "ImageFlags", ""
- SetIfChanged "ImageBuild", ""
- SetIfChanged "InstallFromPath", ""
- SetIfChanged "ImageMemory", ""
- SetIfChanged "ImageProcessor", ""
- SetIfChanged "OSGUID", ""
- SetIfChanged "IsOSUpgrade", ""
- ' Load the TS.XML
- Set oTS = oUtility.CreateXMLDOMObjectEx(oEnvironment.Item("DeployRoot") & "\Control\" & tsID & "\TS.xml")
- ' Determine the deployment type
- 'If (oTS.SelectSingleNode("//step[@type='BDD_InstallOS']") is nothing) and (oTS.SelectSingleNode("//step[@type='BDD_UpgradeOS']") is nothing) then
- If (oTS.SelectSingleNode("//step[@type='BDD_InstallOS' and @disable='false']") is nothing) and (oTS.SelectSingleNode("//step[@type='BDD_UpgradeOS' and @disable='false']") is nothing) then
- oLogging.CreateEntry "Task Sequence does not contain an OS and does not contain a LTIApply.wsf step, possibly a Custom Step or a Client Replace.", LogTypeInfo
- oEnvironment.Item("OSGUID")=""
- If not (oTS.SelectSingleNode("//group[@name='State Restore']") is nothing) then
- oEnvironment.Item("DeploymentType") = "StateRestore"
- ElseIf oEnvironment.Item("TaskSequenceTemplate") <> "ClientReplace.xml" and oTS.SelectSingleNode("//step[@name='Capture User State']") is nothing then
- oEnvironment.Item("DeploymentType") = "CUSTOM"
- Else
- oEnvironment.Item("DeploymentType") = "REPLACE"
- oEnvironment.Item("ImageProcessor") = Ucase(oEnvironment.Item("Architecture"))
- End if
- Elseif oEnvironment.Item("OSVERSION")="WinPE" Then
- oEnvironment.Item("DeploymentType") = "NEWCOMPUTER"
- Else
- oLogging.CreateEntry "Task Sequence contains a LTIApply.wsf step, and is not running within WinPE.", LogTypeInfo
- If oTS.SelectSingleNode("//globalVarList/variable[@name='IsOSUpgrade']") is nothing then
- oEnvironment.Item("DeploymentType") = "REFRESH"
- Else
- oEnvironment.Item("DeploymentType") = "UPGRADE"
- oEnvironment.Item("IsOSUpgrade") = "1"
- End if
- End if
- If oEnvironment.Item("IsOSUpgrade") = "" then
- oEnvironment.Item("IsOSUpgrade") = "0"
- End if
- ' Get the OS details
- Set oOSGUID = oTS.SelectSingleNode("//globalVarList/variable[@name='OSGUID']")
- If not (oOSGUID is Nothing) then
- ' Get the OS record
- oEnvironment.Item("OSGUID") = oOSGUID.text
- Set oOperatingSystems = oUtility.CreateXMLDOMObjectEx(oEnvironment.Item("DeployRoot") & "\Control\OperatingSystems.xml")
- Set oOS = oOperatingSystems.selectSingleNode("//os[@guid='" & oOSGUID.text & "']")
- If oOS is Nothing then
- oLogging.CreateEntry "ERROR: Invalid OS GUID " & oOSGUID.text & " specified for task sequence " & tsID & " specified", LogTypeInfo
- Exit Sub
- End if
- ' Set the simple OS properties
- oEnvironment.Item("ImageIndex") = oUtility.SelectSingleNodeString(oOS,"ImageIndex")
- oEnvironment.Item("ImageSize") = oUtility.SelectSingleNodeString(oOS,"Size")
- on error resume next
- oEnvironment.Item("ImageFlags") = oOS.selectSingleNode("Flags").text
- on error goto 0
- oEnvironment.Item("ImageBuild") = oUtility.SelectSingleNodeString(oOS,"Build")
- oEnvironment.Item("ImageProcessor") = oUtility.SelectSingleNodeString(oOS,"Platform")
- ' Get the languages
- Set oImageLang = oOS.selectNodes("Language")
- sImageLang = ""
- If not (oImageLang is Nothing) then
- For each oLanguage in oImageLang
- sImageLang = sImageLang & oLanguage.text & vbTab
- Next
- End if
- If right(sImageLang,1) = vbTab then
- sImageLang = Left(sImageLang, Len(sImageLang)-1) ' Remove trailing tab
- End if
- oEnvironment.ListItem("ImageLanguage") = split(sImageLang, vbTab)
- ' Set the image path
- If oOS.selectSingleNode("ImageFile") is nothing then
- sImagePath = "."
- Else
- sImagePath = oOS.selectSingleNode("ImageFile").Text
- If sImagePath = "" and left(oEnvironment.Item("ImageBuild"),1) = "5" then
- sImagePath = "."
- End if
- End if
- If Left(sImagePath, 1) = "." then
- ' See if this is a WDS image
- Set oWDSServer = oOS.selectSingleNode("WDSServer")
- If not (oWDSServer is Nothing) then
- sWDSServer = oWDSServer.Text
- End if
- ' Make sure that's where we want to pull it from
- If sWDSServer <> "" then
- If oEnvironment.Item("WDSServer") <> "" then
- sWDSServer = oEnvironment.Item("WDSServer")
- End if
- End if
- ' Set the actual image path
- If sWDSServer <> "" then
- sImagePath = "\\" & sWDSServer & "\REMINST" & Mid(sImagePath, 2)
- Else
- sImagePath = oEnvironment.Item("DeployRoot") & Mid(sImagePath, 2)
- End if
- End if
- oLogging.CreateEntry "InstallFromPath: " & sImagePath, LogTypeInfo
- oEnvironment.Item("InstallFromPath") = oFileHandling.NormalizePath(sImagePath)
- sSourcePath = oUtility.SelectSingleNodeString(oOS,"Source")
- If Left(sSourcePath, 1) = "." then
- sSourcePath = oEnvironment.Item("DeployRoot") & Mid(sSourcePath, 2)
- End if
- oLogging.CreateEntry "SourcePath: " & sSourcePath, LogTypeInfo
- oEnvironment.Item("SourcePath") = sSourcePath
- End if
- End if
- End Sub
- Function IsSupportedPlatform(sPlatform)
- Dim iRetVal
- Dim sSupportedPlatforms
- Dim oPlatformNode
- Dim oNode
- Dim oResults
- Dim oResult
- Dim bFound
- ' Special case: check for Windows PE
- If oEnvironment.Item("OSVersion") = "WinPE" then
- If sPlatform = "Windows PE" then
- IsSupportedPlatform = true
- Else
- IsSupportedPlatform = false
- End if
- Exit Function
- End if
- ' Load the XML file if not yet loaded
- If oSupportedPlatforms is Nothing then
- iRetVal = oUtility.FindFile("ZTISupportedPlatforms.xml", sSupportedPlatforms)
- Set oSupportedPlatforms = CreateXMLDOMObjectEx(sSupportedPlatforms)
- End if
- ' Find the selected platform
- Set oPlatformNode = oSupportedPlatforms.SelectSingleNode("//SupportedPlatform[@name='" & sPlatform & "']")
- If oPlatformNode is Nothing then
- oLogging.CreateEntry "Platform " & sPlatform & " is not found.", LogTypeInfo
- IsSupportedPlatform = False
- Exit Function
- End if
- ' Check each of the expressions. If any don't return a record, return false
- For each oNode in oPlatformNode.SelectNodes("Expression")
- bFound = false
- Set oResults = objWMI.ExecQuery(oNode.Text)
- For each oResult in oResults
- bFound = true
- Exit For
- Next
- If not bFound then
- oLogging.CreateEntry "Condition " & oNode.Text & " not satisfied, platform " & sPlatform & " is not supported.", LogTypeInfo
- IsSupportedPlatform = False
- Exit Function
- End if
- Next
- ' All conditions satisfied, return true
- oLogging.CreateEntry "Platform " & sPlatform & " is supported on this computer.", LogTypeInfo
- IsSupportedPlatform = True
- End Function
- Function SetTagForDrive( sDriveLetter, sTagVariable )
- Dim oDiskPart
- oLogging.CreateEntry "Set the Tag variable: " & sTagVariable, LogTypeInfo
- oEnvironment.Item(sTagVariable) = ""
- For each oDiskPart in objWMI.ExecQuery( "SELECT * FROM Win32_LogicalDisk WHERE DeviceID = '" & left(sDriveLetter,2) & "'" )
- oEnvironment.Item(sTagVariable) = "SELECT * FROM Win32_LogicalDisk WHERE Size = '" & oDiskPart.Size & "' and VolumeName = '" & oDiskPart.VolumeName & "' and VolumeSerialNumber = '" & oDiskPart.VolumeSerialNumber & "'"
- exit For
- next
- End function
- Function GetDriveFromTag ( sTagVariable )
- Dim oDiskPart
- oLogging.CreateEntry "Search for Drive: " & sTagVariable & " " & oEnvironment.Item(sTagVariable), LogTypeInfo
- For each oDiskPart in objWMI.ExecQuery( oEnvironment.Item(sTagVariable) )
- oLogging.CreateEntry "Found Drive: " & oDiskPart.DeviceID, logTypeInfo
- GetDriveFromTag = left(oDiskPart.DeviceID,2)
- Exit For
- next
- End function
- Function ClearRelativeDriveLetters
- oLogging.CreateEntry "If there is a drive letter defined, make sure we clear it now so we can *force* recalcutation.", logTypeInfo
- oEnvironment.Item("OSDTargetDriveCache") = "DIRTY"
- End function
- Function ForceRelativeDriveReCalc
- oLogging.CreateEntry "We can no longer assume any information on drive letters, reset everything!.", logTypeInfo
- ClearRelativeDriveLetters
- If oEnvironment.Item("TargetPartitionIdentifier") <> "" Then
- oEnvironment.Item("TargetPartitionIdentifier") = "DIRTY"
- End if
- End function
- Function GetOSTargetDriveLetterEx( bRequired )
- Dim oDiskPart
- Dim bDiskPartFound
- ' First check to see if the full OS is running
- If oEnv("SystemDrive") <> "X:" then
- ' We are not running within WinPE, Drive Letter may be easy to determine.
- If ucase(oEnvironment.Item("DestinationOSRefresh")) = "OKTOUSEOTHERDISKANDPARTITION" and ucase(oEnvironment.Item("DeploymentType")) = "REFRESH" and ucase(oEnvironment.Item("PHASE")) <> "STATERESTORE" then
- oLogging.CreateEntry "It is possible that the Existing SystemRoot is not the Destiation Drive", logTypeInfo
- Else
- oLogging.CreateEntry "TargetOS is the current SystemDrive", logTypeInfo
- GetOSTargetDriveLetterEx = left(oEnv("SystemDrive"),2)
- exit function ' Easy case, exit now!
- End if
- End if
- ' We may wish to use some advanced Disk Partitioning Routines from ZTIDIskPart.vbs. Check availabiltiy.
- On error resume next
- bDiskPartFound = false
- bDiskPartFound = not isempty(ZTIDiskPart_Script)
- on error goto 0
- If oEnvironment.Item("OriginalPartitionIdentifier") <> "" and ucase(oEnvironment.Item("DestinationOSRefresh")) <> "OKTOUSEOTHERDISKANDPARTITION" Then
- oLogging.CreateEntry "OriginalPartitionIdentifier is set, find disk: " & oEnvironment.Item("OriginalPartitionIdentifier"), logTypeInfo
- GetOSTargetDriveLetterEx = GetDriveFromTag ( "OriginalPartitionIdentifier" )
- ElseIf oEnvironment.Item("OSDTargetDriveCache") <> "" and oEnvironment.Item("OSDTargetDriveCache") <> "DIRTY" and Ucase(oUtility.ScriptName) <> "ZTIDISKPART" Then
- oLogging.CreateEntry "OSDTargetDriveCache was determined earlier : " & oEnvironment.Item("OSDTargetDriveCache"), logTypeInfo
- GetOSTargetDriveLetterEx = left(oEnvironment.Item("OSDTargetDriveCache") ,2)
- ElseIf oEnvironment.Item("TargetPartitionIdentifier") <> "" and oEnvironment.Item("TargetPartitionIdentifier") <> "DIRTY" Then
- oLogging.CreateEntry "TargetPartitionIdentifier is set, find disk: " & oEnvironment.Item("TargetPartitionIdentifier"), logTypeInfo
- GetOSTargetDriveLetterEx = GetDriveFromTag ( "TargetPartitionIdentifier" )
- ElseIf oEnvironment.Item("DeploymentMethod") <> "SCCM" then
- '
- ' Litetouch Scenarios:
- '
- If ucase(oEnvironment.Item("DestinationOSInstallType")) = "BYDRIVELETTER" and oEnvironment.Item("DestinationOSDriveLetter") <> "" then
- oLogging.CreateEntry "DestinationOSInstallType = BYDRIVELETTER (Generally not recomended scenario, drive letters *can* change between reboots).", LogTypeInfo
- GetOSTargetDriveLetterEx = left(oEnvironment.Item("DestinationOSDriveLetter") ,1) & ":"
- ElseIf ucase(oEnvironment.Item("DestinationOSInstallType")) = "BYVARIABLE" and oEnvironment.IndirectItem("DestinationOSVariable") <> "" then
- oLogging.CreateEntry "Found: DestinationOSVariable: " & oEnvironment.IndirectItem("DestinationOSVariable"), LogTypeInfo
- GetOSTargetDriveLetterEx = left(oEnvironment.IndirectItem("DestinationOSVariable") ,2)
- Elseif bDiskPartFound then
- ' Uses functions within ztidiskutility.vbs
- If ucase(oEnvironment.Item("DestinationOSInstallType")) = "NEXTPARTITION" then
- oLogging.CreateEntry "Found: DestinationOSInstallType = NEXTPARTITION ", LogTypeInfo
- GetOSTargetDriveLetterEx = left(GetFirstPossibleSystemDrive,2)
- ElseIf (ucase(oEnvironment.Item("DestinationOSInstallType")) = "BYDISKPARTITION" or oEnvironment.Item("DestinationOSInstallType") = "" ) and isnumeric(oEnvironment.Item("DestinationDisk")) and isnumeric(oEnvironment.Item("DestinationPartition")) then
- oLogging.CreateEntry "DestinationOSInstallType = BYDISKPARTITION", LogTypeInfo
- oLogging.CreateEntry "Found: DestinationDisk: " & oEnvironment.Item("DestinationDisk"), LogTypeInfo
- oLogging.CreateEntry "Found: DestinationPartition: " & oEnvironment.Item("DestinationPartition"), LogTypeInfo
- set oDiskPart = new ZTIDiskPartition
- oDiskPart.SetDiskPart oEnvironment.Item("DestinationDisk"), oEnvironment.Item("DestinationPartition")
- If isEmpty( oDiskPart.oWMIDiskPart ) then
- oLogging.CreateEntry "No partition Found!", logTypeInfo
- ElseIf IsEmpty(oDiskPart.Drive) then
- oLogging.CreateEntry "No drive mapped to Disk Partition: " & oDIskPart.oWMIDiskPart.Path_, logTypeInfo
- Else
- oLogging.CreateEntry "Disk Size : " & FormatLargeSize( oDiskPart.oWMIDiskPart.Size ), logTypeInfo
- oLogging.CreateEntry "Min Size : " & FormatLargeSize(GetMinimumDiskPartitionSizeMB * 1000 * 1000) , logTypeInfo
- If (oDiskPart.oWMIDiskPart.Size /1000 /1000) < (GetMinimumDiskPartitionSizeMB) and 1 = cint(oEnvironment.Item("DestinationPartition")) then
- oLogging.CreateEntry "Partition is set too small, assume BDEPartition and recover.", logTypeInfo
- set oDiskPart = new ZTIDiskPartition
- oDiskPart.SetDiskPart oEnvironment.Item("DestinationDisk"), 2
- If isEmpty( oDiskPart.oWMIDiskPart ) then
- oLogging.CreateEntry "No partition Found!", logTypeInfo
- ElseIf IsEmpty(oDiskPart.Drive) then
- oLogging.CreateEntry "No drive mapped to Disk Partition: " & oDIskPart.oWMIDiskPart.Path_, logTypeInfo
- Else
- oLogging.CreateEntry "Disk Size : " & FormatLargeSize( oDiskPart.oWMIDiskPart.Size ), logTypeInfo
- oLogging.CreateEntry "Min Size : " & FormatLargeSize(GetMinimumDiskPartitionSizeMB * 1000 * 1000) , logTypeInfo
- If (oDiskPart.oWMIDiskPart.Size /1000 /1000) > (GetMinimumDiskPartitionSizeMB) then
- GetOSTargetDriveLetterEx = left(oDiskPart.Drive,2)
- oEnvironment.Item("DestinationPartition") = "2"
- End if
- End if
- Else
- GetOSTargetDriveLetterEx = left(oDiskPart.Drive,2)
- End if
- End if
- End if
- If isempty(GetOSTargetDriveLetterEx) then
- oLogging.CreateEntry "Unable to yield a target Partition (Special Recovery option for Litetouch).", logTypeInfo
- If AllDiskDrives.Count = 1 then
- oLogging.CreateEntry "There is only one disk, so assume that this is the Destination disk.", logTypeInfo
- GetOSTargetDriveLetterEx = left(GetFirstPossibleSystemDrive,2)
- End if
- End if
- End if
- Else
- '
- ' SCCM Scenarios:
- '
- If oEnvironment.Item("_SMSTSMediaType") = "OEMMedia" and oEnvironment.Item("OSDUseAlreadyDeployedImage") = "TRUE" then
- oLogging.CreateEntry "Prestaged media deployment, use data path drive.", LogTypeInfo
- GetOSTargetDriveLetterEx = Left(oEnvironment.Item("_SMSTSMDataPath"), 2)
- ElseIf oEnvironment.Item("OSDTargetDrive") <> "" Then
- oLogging.CreateEntry "OSDTargetDrive is set, find disk: " & oEnvironment.Item("OSDTargetDrive"), logTypeInfo
- GetOSTargetDriveLetterEx = Left(oEnvironment.Item("OSDTargetDrive"), 2)
- ElseIf oEnvironment.Item("OSDisk") <> "" Then
- oLogging.CreateEntry "OSDisk is set, find disk: " & oEnvironment.Item("OSDisk"), logTypeInfo
- GetOSTargetDriveLetterEx = Left(oEnvironment.Item("OSDisk") ,2)
- ElseIf oEnvironment.Item("OSDTemporaryDrive") <> "" Then
- oLogging.CreateEntry "OSDTemporaryDiskDrive is set. Most likely a early setup scenario.", logTypeInfo
- GetOSTargetDriveLetterEx = Left(oEnvironment.Item("OSDTemporaryDrive"), 2)
- ' Hard Exit
- Exit function
- End if
- End if
- If IsEmpty(GetOSTargetDriveLetterEx) then
- oLogging.CreateEntry "DestinationDisk and Partition did not yield a target Partition.", logTypeInfo
- If bRequired then
- oLogging.ReportFailure "Unable to determine Destination Disk, Partition, and/or Drive. See BDD.LOG for more information.", 5456
- End if
- Else
- ' Cache the Deployment drive if found
- oEnvironment.Item("OSDTargetDriveCache") = GetOSTargetDriveLetterEx
- oEnvironment.Item("OSDisk") = GetOSTargetDriveLetterEx
- ' Cache the Partition if not set already.
- If oEnvironment.Item("TargetPartitionIdentifier") = "" then
- SetTagForDrive left(GetOSTargetDriveLetterEx,2), "TargetPartitionIdentifier"
- End if
- oLogging.CreateEntry "Found GetOSTargetDriveLetterEx: " & GetOSTargetDriveLetterEx, logTypeVerbose
- End if
- End function
- Function DeterminePartition
- oLogging.CreateEntry "DeterminePartition is deprecated.", logTypeDeprecated
- If true then
- DeterminePartition = false
- Else
- ' Legacy solution
- ReCalculateDestinationDiskAndPartition (true)
- DeterminePartition = true
- End if
- End function
- Function ReCalculateDestinationDiskAndPartition ( bRequired )
- Dim sDriveLetter
- Dim oDiskPart
- Dim bDiskPartFound
- ' We may wish to use some advanced Disk Partitioning Routines from ZTIDIskPart.vbs. Check availabiltiy.
- On error resume next
- bDiskPartFound = false
- bDiskPartFound = not isempty(ZTIDiskPart_Script)
- on error goto 0
- sDriveLetter = GetOSTargetDriveLetterEx(bRequired)
- If bRequired then
- TestAndFail bDiskPartFound , 5452, "Verify ZTIDiskPArt is loaded"
- set oDiskPart = new ZTIDiskPartition
- oDiskPart.Drive = sDriveLetter
- TestAndFail not isEmpty(oDiskPart.Drive),5451, "Verify oDiskPart.Drive is found!"
- oEnvironment.Item("DestinationDisk") = oDiskPart.Disk
- oEnvironment.Item("DestinationPartition") = oDiskPart.Partition
- ElseIf bDiskPartFound then
- set oDiskPart = new ZTIDiskPartition
- oDiskPart.Drive = sDriveLetter
- If not isEmpty(oDiskPart.Drive) then
- oEnvironment.Item("DestinationDisk") = oDiskPart.Disk
- oEnvironment.Item("DestinationPartition") = oDiskPart.Partition
- Else
- oLogging.CreateEntry "Drive not found: " & sDriveLetter, LogTypeINfo
- End if
- Else
- oLogging.CreateEntry "ZTIDiskPart_Script not found ", LogTypeINfo
- End if
- End function
- Function GetOSTargetDriveLetter
- GetOSTargetDriveLetter = GetOSTargetDriveLetterEx(true)
- End function
- Function SelectSingleNodeString( oXMLDomNode, sXPath )
- SelectSingleNodeString = SelectSingleNodeStringEx(oXMLDomNode, sXPath, True )
- End function
- Function SelectSingleNodeStringEx( oXMLDomNode, sXPath, bError )
- If bError then
- 'TestAndLog not oXMLDomNode is nothing, "verify oXMLDomNode is object."
- End if
- If not oXMLDomNode.SelectSingleNode(sXPath) is nothing then
- SelectSingleNodeStringEx = oXMLDomNode.SelectSingleNode(sXPath).Text
- Else
- If bError then
- oLogging.CreateEntry "SelectSingleNodeString(" & sXPath & ") Missing Node.", LogTypeWarning
- End if
- SelectSingleNodeStringEx = ""
- End if
- End function
- Function SelectNodesSafe ( oXMLDomNode, sXPath )
- set SelectNodesSafe = SelectNodesSafeEx ( oXMLDomNode, sXPath, True )
- End function
- Function SelectNodesSafeEx ( oXMLDomNode, sXPath, bError )
- If bError then
- 'TestAndLog not oXMLDomNode is nothing, "verify oXMLDomNode is object."
- End if
- set SelectNodesSafeEx = oXMLDomNode.SelectNodes(sXPath)
- If SelectNodesSafeEx is nothing then
- If bError then
- oLogging.CreateEntry "SelectNodesSafeEx(" & sXPath & ") Missing Node.", LogTypeWarning
- End if
- set SelectNodesSafeEx = CreateObject("Scripting.Dictionary") ' Empty object
- End if
- End function
- Function FindSysprepAnswerFile
- Dim sSysprepInf
- Dim sBuildPath
- Dim iRetVal
- Dim sBootDrive
- iRetVal = SUCCESS
- If oEnvironment.Item("TaskSequenceID") = "" Then
- oLogging.CreateEntry "The TaskSequenceID is blank, possibly a misconfigured customsettings.ini or task sequence",LogTypeWarning
- End If
- sBuildPath = oEnvironment.Item("DeployRoot") & "\Control\" & oEnvironment.Item("TaskSequenceID")
- If not oFSO.FolderExists(sBuildPath) then
- sBuildPath = oEnvironment.Item("DeployRoot")
- End if
- sBootDrive = oUtility.GetOSTargetDriveLetterEx(false)
- if sBootDrive = "" then
- oLogging.CreateEntry "Destination Logical Drive was not specificed, defaulting to #:\", LogTypeInfo
- sBootDrive = "#:" ' Unknown Boot Drive
- End if
- oLogging.CreateEntry "Looking for Sysprep.inf in " & sBootDrive & "\sysprep\Sysprep.inf", LogTypeInfo
- If oFSO.FileExists(oEnvironment.Item("OSDAnswerFilePathSysprep")) Then
- FindSysprepAnswerFile = iRetVal
- Exit Function
- ElseIf oFSO.FileExists(sBootDrive & "\sysprep\Sysprep.inf") then
- sSysprepInf = sBootDrive & "\sysprep\Sysprep.inf"
- oLogging.CreateEntry "Found Sysprep.inf at " & sSysprepInf & ".", LogTypeInfo
- ElseIf oFSO.FileExists("x:\sysprep\Sysprep.inf") then
- sSysprepInf = "x:\sysprep\Sysprep.inf"
- oLogging.CreateEntry "Found Sysprep.inf at " & sSysprepInf & ".", LogTypeInfo
- ElseIf oFSO.FileExists(sBuildPath & "\Sysprep.inf") then
- ' Copy it locally
- sSysprepInf = sBootDrive & "\sysprep\Sysprep.inf"
- oLogging.CreateEntry "Found Sysprep.inf at " & sBuildPath & "\Sysprep.inf, will copy to " & sSysprepInf, LogTypeInfo
- If not oFSO.FolderExists(sBootDrive & "\Sysprep") then
- oFSO.CreateFolder sBootDrive & "\Sysprep"
- End if
- oFSO.CopyFile sBuildPath & "\Sysprep.inf", sSysprepInf
- oFSO.GetFile(sSysprepInf).Attributes = 0
- oLogging.CreateEntry "Copied " & sBuildPath & "\Sysprep.inf to " & sBootDrive & "\sysprep", LogTypeInfo
- ElseIf oEnvironment.Item("OSDTargetSystemDrive")<> "" and oFSO.FileExists(oEnvironment.Item("OSDTargetSystemDrive") & "\sysprep\sysprep.inf") then
- sSysprepInf = oEnvironment.Item("OSDTargetSystemDrive") & "\sysprep\sysprep.inf"
- oLogging.CreateEntry "Found Sysprep.inf at " & sSysprepInf & ".", LogTypeInfo
- Else
- oLogging.CreateEntry "The sysprep.inf file was not found.", LogTypeInfo
- End if
- oEnvironment.Item("OSDAnswerFilePathSysprep") = sSysprepInf
- FindSysprepAnswerFile = iRetVal
- End Function
- Function FindUnattendAnswerFile
- Dim sUnattendXML, sUnattendTxt
- Dim sBuildPath
- Dim iRetVal
- iRetVal = SUCCESS
- If oEnvironment.Item("TaskSequenceID") = "" Then
- oLogging.CreateEntry "The TaskSequenceID is blank, possibly a misconfigured customsettings.ini or task sequence",LogTypeWarning
- End If
- sBuildPath = oEnvironment.Item("DeployRoot") & "\Control\" & oEnvironment.Item("TaskSequenceID")
- If not oFSO.FolderExists(sBuildPath) then
- sBuildPath = oEnvironment.Item("DeployRoot")
- End if
- If oFSO.FileExists(sBuildPath & "\Unattend.txt") then
- ' Copy it locally
- sUnattendTxt = oUtility.LocalRootPath & "\unattend.txt"
- oLogging.CreateEntry "Found Unattend.txt at " & sBuildPath & "\Unattend.txt, will copy to " & sUnattendTxt, LogTypeInfo
- oFSO.CopyFile sBuildPath & "\Unattend.txt", sUnattendTxt, true
- oFSO.GetFile(sUnattendTxt).Attributes = 0
- oLogging.CreateEntry "Copied " & sBuildPath & "\Unattend.txt to " & sUnattendTxt, LogTypeInfo
- ElseIf oFso.FileExists(oEnvironment.Item("OSDAnswerFilePath")) and Instr(1,oEnvironment.Item("OSDAnswerFilePath"),".txt",vbTextCompare) > 0 then
- sUnattendTxt = oEnvironment.Item("OSDAnswerFilePath")
- oLogging.CreateEntry "Found unattend.txt at " & sUnattendTxt,LogTypeInfo
- Else
- oLogging.CreateEntry "The unattend.txt file was not found.", LogTypeInfo
- End if
- ' First see if there is already a local unattend.xml. If not, copy one.
- If oFSO.FileExists(Left(oUtility.LocalRootPath, 2) & "\Windows\Panther\unattend\unattend.xml") then
- sUnattendXml = Left(oUtility.LocalRootPath, 2) & "\Windows\Panther\unattend\unattend.xml"
- oLogging.CreateEntry "Found existing unattend.xml at " & sUnattendXml, LogTypeInfo
- ElseIf oFSO.FileExists(oUtility.LocalRootPath & "\unattend.xml") then
- sUnattendXml = oUtility.LocalRootPath & "\unattend.xml"
- oLogging.CreateEntry "Found existing unattend.xml at " & sUnattendXml, LogTypeInfo
- ElseIf oFSO.FileExists(sBuildPath & "\Unattend.xml") then
- sUnattendXml = oUtility.LocalRootPath & "\Unattend.xml"
- oLogging.CreateEntry "Found unattend.xml at " & sBuildPath & "\Unattend.xml, will copy to " & sUnattendXml, LogTypeInfo
- oFSO.CopyFile sBuildPath & "\Unattend.xml", sUnattendXml, true
- oLogging.CreateEntry "Copied " & sBuildPath & "\Unattend.xml to " & sUnattendXml, LogTypeInfo
- oFSO.GetFile(sUnattendXml).Attributes = 0
- ElseIf oFso.FileExists(oEnvironment.Item("OSDAnswerFilePath")) and Instr(1,oEnvironment.Item("OSDAnswerFilePath"),".xml",vbTextCompare) >0 then
- sUnattendXML= oEnvironment.Item("OSDAnswerFilePath")
- oLogging.CreateEntry "Found existing unattend.xml at " & sUnattendXml, LogTypeInfo
- Else
- sUnattendXml = ""
- oLogging.CreateEntry "File " & sBuildPath & "\Unattend.xml does not exist, unable to copy", LogTypeInfo
- End if
- If sUnattendTxt <> "" AND sUnattendXML <> "" Then
- oLogging.CreateEntry "Found an unattend.xml and an unattend.txt file, Invalid configuration", LogTypeError
- iRetVal = FAILURE
- FindUnattendAnswerFile = iRetVal
- Exit Function
- ElseIf sUnattendTxt <> "" AND sUnattendXML = "" Then
- oEnvironment.Item("OSDAnswerFilePath") = sUnattendTxt
- ElseIF sUnattendXML <> "" AND sUnattendTxt = "" Then
- oEnvironment.Item("OSDAnswerFilePath") = sUnattendXML
- Else
- oLogging.CreateEntry "No answer file could be found",LogTypeWarning
- End If
- FindUnattendAnswerFile = iRetVal
- End Function
- Function IsHighEndSKUEx( sSKU )
- ' Windows Ultimate/Enterprise and Server SKU's allow for some
- ' higher-end features, like Bitlocker and Multiple Language Packs.
- select case (ucase(trim(sSKU)))
- case "ULTIMATE", "ULTIMATEE", "ULTIMATEN"
- IsHighEndSKUEx = TRUE
- case "ENTERPRISE", "ENTERPRISEN", "ENTERPRISES", "ENTERPRISESN"
- IsHighEndSKUEx = TRUE
- case "PROFESSIONAL", "PROFESSIONALN"
- IsHighEndSKUEx = TRUE
- case "EDUCATION", "EDUCATIONN"
- IsHighEndSKUEx = TRUE
- case "HYPERV"
- IsHighEndSKUEx = TRUE
- case "PRERELEASE"
- IsHighEndSKUEx = TRUE
- case else
- If Instr(1, ucase(trim(sSKU)), "SERVER", vbTextCompare) > 0 then
- IsHighEndSKUEx = TRUE
- Else
- IsHighEndSKUEx = FALSE
- End if
- End Select
- End function
- Function IsHighEndSKU
- TestAndLog oEnvironment.Item("OSSKU") <> "", "Verify %OSSKU% is defined."
- IsHighEndSKU = IsHighEndSKUEx( oEnvironment.Item("OSSKU") )
- End function
- Function InternetFileDownload(sInternetURL, sDest)
- Dim oInternetBuffer
- Dim oADODB
- ' Assume failure
- InternetFileDownload = false
- ' Create the web request using ADO
- Set oADODB = CreateObject("ADODB.Stream")
- Set oInternetBuffer = CreateObject("Msxml2.XmlHttp")
- oInternetBuffer.open "GET", sInternetURL, false
- On Error Resume Next
- oInternetBuffer.send ""
- On Error Goto 0
- ' Check that the request is completed (ReadyState=4). If it isn't, log it as a warning (will likely fail below
- ' because the status won't be 200).
- If oInternetBuffer.ReadyState = 4 then
- oLogging.CreateEntry "Status: " & oInternetBuffer.Status & " " & sInternetURL, LogTypeInfo
- Else
- oLogging.CreateEntry "Ready State : " & oInternetBuffer.ReadyState & " " & sInternetURL, LogTypeWarning
- End if
- ' If the status indicates a successful download, save the file to the specified path
- If oInternetBuffer.Status = 200 then
- If oADODB.State <> 0 then ADODB.Close
- oADODB.Type = 1 '(1=binary,2=Text)
- oADODB.Mode = 3 '(1=Read,2=Write,3=RW)
- oADODB.Open
- oADODB.Write oInternetBuffer.ResponseBody
- oADODB.SaveToFile sDest, 2
- oADODB.Close
- InternetFileDownload = True
- End if
- End function
- End Class
- '
- ' Common String Processing Routines
- '
- Class Strings
- Function isNullOrEmpty( sString )
- isNullOrEmpty = false
- If isEmpty(sString) or isNull(sString) then
- isNullOrEmpty = True
- ElseIf VarType(sString) = 8 then
- isNullOrEmpty = (sString = "")
- End if
- End function
- ' Create a delimited list of items.
- Sub AddToList(byref List, Item, Delimiter)
- if isempty(list) then
- List = cstr(item)
- else
- list = list & delimiter & cstr(Item)
- end if
- end Sub
- ' Display a Hex value with width
- Function HexWidth ( Value, Width )
- HexWidth = right( "00000000" & hex ( value ), Width)
- end Function
- ' Display a Hex value with width
- Function HexWidthByte ( Value, Width )
- HexWidthByte = right( "00000000" & hex ( ascb( value ) ), Width )
- end Function
- Function IsWhiteSpace (MyChar)
- ' Whitespace defined as vtTab[9], vbLF[10], vbVerticalTab[11], vbFormFeed[12], vbCr[13]
- IsWhiteSpace = MyChar = " " or ( MyChar >= chr(9) and MyChar <= chr(13) ) or MyChar = chr(160)
- end Function
- Function TrimAllWS( MyString )
- TrimAllWS = MyString
- While len(TrimAllWS) > 0 and IsWhiteSpace(left(TrimAllWS,1))
- TrimAllWS = Mid(TrimAllWS,2)
- wend
- While len(TrimAllWS) > 0 and IsWhiteSpace(right(TrimAllWS,1))
- TrimAllWS = Mid(TrimAllWS,1,len(TrimAllWS)-1)
- wend
- end Function
- Function RightAlign( MyString, Width )
- RightAlign = Right( Space(Width) & MyString, Width )
- end Function
- Function LeftAlign( MyString, Width )
- LeftAlign = Left( MyString & Space(Width), Width )
- end Function
- '
- ' Force a value to a string format.
- ' Non-printable types will return empty.
- '
- Function ForceAsString ( InputVar )
- dim InputType, Item
- InputType = VarType(InputVar)
- if isObject(InputVar) or isNull(InputVar) or isEmpty(InputVar) then
- ForceAsString = ""
- elseif InputType = vbError or InputType = vbVariant or InputType = vbDataObject then
- ForceAsString = ""
- elseif InputType = ( vbArray or vbByte ) then
- for item = 1 to LenB( InputVar )
- AddToList ForceAsString, ForceAsString( HexWidthByte(midb(InputVar,Item,1),2) ), ""
- next
- elseif isArray(InputVar) then
- for each item in InputVar
- AddToList ForceAsString, ForceAsString(Item), " " ' recurse
- next
- elseif InputType = vbByte then
- ForceAsString = HexWidthByte(InputVar,2)
- else
- ForceAsString = cstr(InputVar)
- end if
- end Function
- '
- ' Given a variant, will ensure the Function returns an array
- '
- ' Parameters:
- ' InputVar - Variable to convert to an array
- ' sDelimiter - OPTIONAL delimiter to force spliting in the array
- ' If sDelimiter is empty or blank, Function will return an array of 1 element.
- ' Notes
- Function ForceAsArray( InputVar, sDelimiter )
- dim i
- if isArray(InputVar) then
- ForceAsArray = InputVar
- elseif VarType(InputVar) = vbObject then
- redim newarray(InputVar.Count-1)
- for i = 0 to InputVar.Count-1
- newarray(i) = InputVar(i)
- next
- ForceAsArray = NewArray
- elseif VarType(InputVar) = vbString and VarType(sDelimiter) = vbString then
- ForceAsArray = split(InputVar,sDelimiter, -1, vbTextCompare )
- else
- ForceAsArray = array(InputVar)
- end if
- end Function
- Function GenerateRandomGUID
- GenerateRandomGUID = left( CreateObject("Scriptlet.TypeLib").GUID, 38 )
- end Function
- ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
- '
- ' Base64 Functions
- '
- Function BASE64_TABLE
- BASE64_TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
- End function
- Function SafeAsc ( sPlainText, pos )
- if VarType(sPlainText) = (vbArray or vbByte) then
- SafeAsc = cint(midb(sPlainText, pos + 1 , 1))
- elseif (pos + 1) <= len(sPlainText) then
- SafeAsc = asc(mid(sPlainText, pos + 1, 1))
- else
- SafeAsc = 0
- end if
- End Function
- Function SafeEnc( n, x )
- SafeEnc = mid(BASE64_TABLE, ((n\(2^x)) and 63) + 1,1)
- End Function
- Function base64Encode( sPlainText )
- Dim i, n
- if 0 < len(sPlainText) then
- for i = 0 to len(sPlainText) - 1 step 3
- ' Add a new line ...
- if i > 0 and i mod 57 = 0 then
- base64Encode = base64Encode & vbNewLine
- end if
- ' three 8-bit characters become one 24-bit number
- n = (SafeAsc(sPlainText,i)*&h10000 + SafeAsc(sPlainText,i+1)*&h100 + SafeAsc(sPlainText,i+2))
- ' the 24-bit number becomes four 6-bit numbers
- base64Encode = base64Encode & SafeEnc( n, 18 ) & SafeEnc( n, 12 ) & SafeEnc( n, 6 ) & SafeEnc( n, 0 )
- next
- end if
- ' Pad Text at End of String
- n = (3-(len(sPlainText)mod 3)) mod 3
- base64Encode = left ( base64Encode, len(base64Encode) - n ) + string( n, "=" )
- End Function
- Function SafeDecode( s, i, x )
- SafeDecode = ( InStr(1, BASE64_TABLE, mid(s,i,1), vbBinaryCompare) - 1) * (2 ^ x)
- End Function
- Function base64Decode( sEncodedText )
- Dim sEncText
- Dim regex
- Dim p, i, n
- ' Remove all non base64 text
- set regex = new RegExp
- regex.pattern = "[^=" & BASE64_TABLE & "]"
- regex.global = true
- sEncText = regex.Replace(sEncodedText,"")
- sEncText = replace( sEncText, vbLF, "")
- sEncText = replace( sEncText, vbCR, "")
- ' Verify String is in Base64 format (multiple of 4 chars)
- if len(sEncText) mod 4 <> 0 then
- oLogging.CreateEntry "Variable is not a valid string (not Base64 Format)", LogTypeInfo
- base64Decode = ""
- exit function
- end if
- if right(sEncText,2) = "==" then
- p = 2
- elseif right(sEncText,1) = "=" then
- p = 1
- end if
- sEncText = left(sEncText,len(sEncText)-p) & string(p,"A")
- for i = 1 to len(sEncText) step 4
- ' Convert four 6-bit numbers into one 24 bit value
- n = SafeDecode(sEncText,i+3,0) + SafeDecode(sEncText,i+2,6) + SafeDecode(sEncText,i+1,12) + SafeDecode(sEncText,i+0,18)
- ' Convert the 24-bit value back into three 8-bit values.
- base64Decode = base64Decode & chr( (n \ (2^16)) and 255 ) & chr( (n \ (2^8)) and 255 ) & chr( n and 255 )
- next
- ' Trim off any excess space.
- base64Decode = left(base64Decode,len(base64Decode)-p)
- End Function
- End Class
- Class FileHandling
- Function RemoveFolder(sPath)
- RemoveFolder = RemoveFolderEx (sPath, TRUE)
- End Function
- Function RemoveFolderEx(sPath, bLogging )
- Dim oFile, oFolder
- If bLogging then
- oLogging.CreateEntry "Remove Folder: " & sPath, LogTypeInfo
- End if
- ' Make sure the folder exists
- If not oFSO.FolderExists(sPath) then
- Exit Function
- End if
- ' First try to remove any files
- on error resume next
- For each oFile in oFSO.GetFolder(sPath).Files
- DeleteFileEx oFile.Path, bLogging
- Next
- On Error Goto 0
- ' Then take care of subfolders
- on error resume next
- For each oFolder in oFSO.GetFolder(sPath).Subfolders
- RemoveFolderEx oFolder.Path, bLogging
- Next
- On Error Goto 0
- ' Now try to remove the folder
- On Error Resume Next
- oFSO.DeleteFolder sPath, true
- If bLogging then
- TestAndLog Err = 0, "Delete Folder: " & sPath
- End if
- RemoveFolderEx = Err
- Err.Clear
- On Error Goto 0
- End Function
- Function DeleteFile(sFile)
- DeleteFile = DeleteFileEx ( sFile, TRUE )
- End function
- Function DeleteFileEx(sFile, bLogging)
- If bLogging then
- oLogging.CreateEntry "Delete File: " & sFile, LogTypeInfo
- End if
- On Error Resume Next
- oFSO.DeleteFile sFile, TRUE
- If bLogging then
- TestAndLog Err = 0, "Delete File: " & sFile
- End if
- DeleteFileEx = Err
- Err.Clear
- On Error Goto 0
- End function
- Function MoveFile(sFile,sDest)
- MoveFile = MoveFileEx(sFile,sDest,True)
- End function
- Function MoveFileEx(sFile,sDest,bLogging)
- If bLogging then
- oLogging.CreateEntry "Move File: " & sFile & " to " & sDest , LogTypeInfo
- End if
- On Error Resume Next
- oFSO.MoveFile sFile, sDest
- If bLogging then
- TestAndLog Err = 0, "Move File: " & sFile & " to " & sDest
- End if
- MoveFileEx = Err
- Err.Clear
- On Error Goto 0
- End function
- Function CopyFile(sFile,sDest, bOverwrite)
- CopyFile = CopyFileEx(sFile,sDest, bOverwrite,True)
- End function
- Function CopyFileEx(sFile,sDest, bOverwrite,bLogging)
- If bLogging then
- oLogging.CreateEntry "Copy File: " & sFile & " to " & sDest , LogTypeInfo
- End if
- On Error Resume Next
- oFSO.CopyFile sFile, sDest, bOverwrite
- If bLogging then
- TestAndLog Err = 0, "Copy File: " & sFile & " to " & sDest
- End if
- CopyFileEx = Err
- Err.Clear
- On Error Goto 0
- End function
- Function CopyFolder (sSource, sDest, bOverwrite)
- CopyFolder = CopyFolderEx(sSource, sDest, bOverwrite, True)
- End function
- Function CopyFolderEx (sSource, sDest, bOverwrite,bLogging)
- If bLogging then
- oLogging.CreateEntry "Copy Folder: " & sSource & " to " & sDest , LogTypeInfo
- End if
- On Error Resume Next
- oFSO.CopyFolder sSource, sDest, bOverwrite
- If bLogging then
- TestAndLog Err = 0, "Copy Folder: " & sSource & " to " & sDest
- End if
- CopyFolderEx = Err
- Err.Clear
- On Error Goto 0
- End function
- Function MoveFolder (sSource, sDest )
- MoveFolder = MoveFolderEx (sSource, sDest, True )
- End function
- Function MoveFolderEx (sSource, sDest, bLogging )
- If bLogging then
- oLogging.CreateEntry "Move Folder " & sSource & " to " & sDest , LogTypeInfo
- End if
- On Error Resume Next
- oFSO.MoveFolder sSource,sDest
- If bLogging then
- TestAndLog Err = 0, "Move Folder " & sSource & " to " & sDest
- End if
- MoveFolderEx = Err
- Err.Clear
- On Error Goto 0
- End function
- Function NormalizePath( Path )
- NormalizePath = oFSO.GetAbsolutePathName (Path )
- End function
- Function GetTempFile
- GetTempFile = oFso.BuildPath( GetTempFolder, oFSO.GetTempName )
- End function
- Function GetTempFileEx(sExt)
- GetTempFileEx = oFso.BuildPath( GetTempFolder, oFSO.GetBaseName(oFSO.GetTempName) & "." & sExt )
- End function
- Function GetTempFolder
- GetTempFolder = oFSO.GetSpecialFolder(2) 'TemporaryFolder
- End function
- Function GetWindowsFolder
- GetWindowsFolder = oFSO.GetSpecialFolder(0) 'WindowsFolder
- End function
- Function CheckFileVersion ( sFileName, sMinVersion )
- ' Returns True if the sFileName is the sMinVersion or greater, False if less, or not found.
- Dim sFoundFile
- Dim sMSIVer
- Dim sMSIVer2
- Dim i
- CheckFileVersion = oUtility.FindFile(sFileName, sFoundFile) = SUCCESS
- TestAndLog CheckFileVersion, "FindFile (" & sFileName & ")"
- If CheckFileVersion then
- sMSIVer = split(oFSO.GetFileVersion(sFoundFile),".")
- sMSIVer2 = split(sMinVersion,".")
- i = 0
- do while CheckFileVersion and ( i <= ubound(sMSIVer) ) and ( i <= ubound(sMSIVer2) )
- If sMSIVer(i) <> sMSIVer2(i) then
- CheckFileVersion = clng(sMSIVer(i)) >= clng(sMSIVer2(i))
- exit do
- End if
- i = i + 1
- Loop
- oLogging.CreateEntry sFileName & " version: [ " & join(sMSIVer,".") & " | " & sMinVersion & " ]. Is version found? " & ( CheckFileVersion ), LogTypeInfo
- Else
- oLogging.CreateEntry sFileName & " Not found! Needs upgrade. " & ( CheckFileVersion ), LogTypeInfo
- End if
- End function
- End Class
- '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
- '
- ' Regular Expression Helper functions
- ' http://msdn.microsoft.com/en-us/library/6wzad2b2(VS.85).aspx
- '
- ' Usage:
- ' for each Match in oRegEx.GetRegExMatchesFromFile( "\[([^\]]*)\]","c:\boot.ini" )
- ' Wscript.echo "Match: " & Match
- ' next
- '
- dim g_oRegEx
- Function oRegEx
- if isempty(g_oRegEx) then
- set g_oRegEx = new clsRegEx
- end if
- set oRegEx = g_oRegEx
- end Function
- class clsRegEx
- Private Function ReadEntireFile( sFileName )
- ' TestAndLog oFSO.FileExists(sFileName), "File Test: " & sFileName
- ReadEntireFile = oFSO.OpenTextFile(sFileName, ForReading, FALSE ).ReadAll
- End function
- private Function RegExObj ( SearchPattern, IgnoreCase, IsGlobal )
- set RegExObj = New RegExp
- RegExObj.Global = IsGlobal
- RegExObj.Multiline = TRUE
- RegExObj.IgnoreCase = IgnoreCase
- RegExObj.Pattern = SearchPattern
- end Function
- Function GetRegExMatches ( SearchPattern, Buffer )
- set GetRegExMatches = RegExObj ( SearchPattern, TRUE, TRUE ).Execute(Buffer)
- end Function
- Function TestRegEx ( SearchPattern, Buffer )
- TEstRegEx = RegExObj ( SearchPattern, TRUE, TRUE ).Test(Buffer)
- end Function
- Function ReplaceRegEx ( SearchPattern, ReplacementString, Buffer )
- ReplaceRegEx = RegExObj ( SearchPattern, TRUE, TRUE ).Replace(Buffer, ReplacementString)
- end Function
- Function GetRegExMatchesFromFile ( SearchPattern, FileName )
- set GetRegExMatchesFromFile = GetRegExMatches ( SearchPattern, ReadEntireFile(FileName) )
- end Function
- Function TestRegExFromFile ( SearchPattern, FileName )
- TestRegExFromFile = TestRegEx ( SearchPattern, ReadEntireFile(FileName) )
- end Function
- Function ReplaceRegExFromFile ( SearchPattern, ReplacementString, FileName )
- ReplaceRegExFromFile = ReplaceRegEx ( SearchPattern, ReplacementString, ReadEntireFile(FileName) )
- end Function
- Function FindStrInFile( SearchStr, FileName )
- FindStrInFile = InStr(1, ReadEntireFile( sFileName ), SearchStr, vbTextCompare)
- end Function
- end class
Add Comment
Please, Sign In to add comment