dax6600

Untitled

Jan 4th, 2017
831
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
VBScript 133.74 KB | None | 0 0
  1.  
  2. ' // ***************************************************************************
  3. ' //
  4. ' // Copyright (c) Microsoft Corporation.  All rights reserved.
  5. ' //
  6. ' // Microsoft Deployment Toolkit Solution Accelerator
  7. ' //
  8. ' // File:      ZTIUtility.vbs
  9. ' //
  10. ' // Version:   6.3.8443.1000
  11. ' //
  12. ' // Purpose:   Common Libraries for Microsoft Deployment Toolkit
  13. ' //
  14. ' // ***************************************************************************
  15.  
  16.  
  17. Option Explicit
  18.  
  19. ' Public constants
  20.  
  21. Public Const ForReading = 1
  22. Public Const ForWriting = 2
  23. Public Const ForAppending = 8
  24.  
  25. Public Const Success = 0
  26. Public Const Failure = 1
  27.  
  28. Public Const LogTypeInfo = 1
  29. Public Const LogTypeWarning = 2
  30. Public Const LogTypeError = 3
  31. Public Const LogTypeVerbose = 4
  32. Public Const LogTypeDeprecated = 5
  33.  
  34. Public Const TextCompare = 1
  35.  
  36. Public Const adOpenStatic = 3
  37. Public Const adLockReadOnly = 1
  38. Public Const adLockOptimistic = 3
  39.  
  40. Public Const Version = "6.3.8443.1000"
  41.  
  42.  
  43. ' Global variables
  44.  
  45. Dim oShell, oEnv, oNetwork, oFSO, objWMI, oDrive
  46. Dim oUtility, oLogging, oEnvironment
  47. Dim oStrings
  48. Dim oFileHandling
  49.  
  50. ' Initialization code
  51.  
  52. On Error Resume Next
  53. Set oUtility = New Utility
  54. oUtility.PrepareEnvironment
  55.  
  56.  
  57. function PrnErrValue ( iError )
  58.     PrnErrValue = oLogging.FormatError ( iError )
  59. end function
  60.  
  61.  
  62. Sub ProcessResults(iRc)
  63.     ProcessResults = oLogging.ProcessResults ( iRc )
  64. End Sub
  65.  
  66. function RunNewInstance
  67.     Dim oScriptClass
  68.     RunNewInstance = oUtility.RunNewInstanceEx ( oUtility.ScriptName, "oScriptClass", "oScriptClass.Main" )
  69. end function
  70.  
  71.  
  72. Function TestAndLog ( iRc , sMessage)
  73.  
  74.     TestAndLog = oLogging.TRACEEX(iRc, "", sMessage, FALSE)
  75.  
  76. End function
  77.  
  78. Function TestAndFail ( iRc, iError, sMessage)
  79.  
  80.     TestAndFail = oLogging.TRACEEX(iRc, iError, sMessage, TRUE)
  81.  
  82. End function
  83.  
  84. '//---------------------------------------------------------------------------
  85. '//  Function:  ConvertBooleanToString()
  86. '//  Purpose:   Perform a Cstr operation manually to prevent localization
  87. '//             from converting True/False to non-english values.
  88. '//---------------------------------------------------------------------------
  89. Function ConvertBooleanToString(bValue)
  90.  
  91.     ConvertBooleanToString = oUtility.ConvertBooleanToString(bValue)
  92.  
  93. End Function
  94.  
  95.  
  96.  
  97. ' Public classes
  98.  
  99. ' //////////////////////////////////////////////////////
  100.  
  101. class Logging
  102.  
  103.     ' //
  104.     ' // Logging is a public class used for trace logging within the BDD/MDT scripting Environment
  105.     ' //
  106.     ' // Assumes: oUtility, oEnvironment, oFSO - Must be initialized and active.
  107.     ' //
  108.  
  109.  
  110.     ' ***  Public variables ***
  111.  
  112.     Public LogFile
  113.     Public MasterLogFile
  114.     Public Component
  115.     Public Debug
  116.     Public NetworkLogging
  117.  
  118.  
  119.     ' ***  Private variables ***
  120.  
  121.  
  122.     ' ***  Constructor and destructor ***
  123.  
  124.     Private Sub Class_Initialize
  125.  
  126.  
  127.         ' Set file names and paths
  128.  
  129.         Component = oUtility.ScriptName
  130.         LogFile = Component & ".log"
  131.         MasterLogFile = "BDD.log"
  132.         NetworkLogging = ""
  133.  
  134.  
  135.         ' Set debug to false, allow PrepareEnvironment to override
  136.  
  137.         Debug = False
  138.  
  139.  
  140.     End Sub
  141.  
  142.  
  143.     ' ***  Public methods ***
  144.  
  145.     ' //
  146.     ' // Standard MDT logging routine, used for most logging operations
  147.     ' //
  148.     ' //  Standard Error Types
  149.     ' //     Public Const LogTypeInfo        = 1   ' Informational Message
  150.     ' //     Public Const LogTypeWarning     = 2   ' Warning Message
  151.     ' //     Public Const LogTypeError       = 3   ' Error Message
  152.     ' //     Public Const LogTypeVerbose     = 4   ' Verbose Messages only logged when Debug has been set.
  153.     ' //     Public Const LogTypeDeprecated  = 5   ' Informational Message that is elevated to Error when Debug is set.
  154.     ' //
  155.  
  156.     Public Function CreateEntry(sLogMsg, iType)
  157.         Dim sTime, sDate, sTempMsg, oLog, bConsole
  158.  
  159.  
  160.         ' Each of the operations below has the potential to cause a runtime error.
  161.         ' However, we must not stop operation if there is a failure, so allways continue.
  162.  
  163.         On Error Resume Next
  164.  
  165.  
  166.         ' Special Handling for Debug vs. Non-Debug messages
  167.  
  168.         If not Debug then
  169.  
  170.             If iType = LogTypeVerbose Then
  171.                 Exit Function  ' Verbose Messages are only displayed when Debug = True
  172.             Elseif iType = LogTypeDeprecated Then
  173.                 iType = LogTypeInfo ' Deprecated messages are normally Info messages
  174.             End if         
  175.  
  176.         Else  ' Debug = True
  177.  
  178.             If iType = LogTypeVerbose then
  179.                 iType = LogTypeInfo
  180.             Elseif iType = LogTypeDeprecated Then
  181.                 iType = LogTypeError
  182.             End if
  183.  
  184.         End if
  185.  
  186.         ' Suppress messages containing password
  187.  
  188.             If Instr(1, sLogMsg, "password", 1) > 0 then
  189.                 sLogMsg = "<Message containing password has been suppressed>"
  190.             End if
  191.  
  192.         ' Populate the variables to log
  193.  
  194.         sTime = Right("0" & Hour(Now), 2) & ":" & Right("0" & Minute(Now), 2) & ":" & Right("0" & Second(Now), 2) & ".000+000"
  195.         sDate = Right("0"& Month(Now), 2) & "-" & Right("0" & Day(Now), 2) & "-" & Year(Now)
  196.         sTempMsg = "<![LOG[" & sLogMsg & "]LOG]!><time=""" & sTime & """ date=""" & sDate & """ component=""" & Component & """ context="""" type=""" & iType & """ thread="""" file=""" & oUtility.ScriptName & """>"
  197.  
  198.  
  199.         ' Make sure the LogPath directory exists
  200.  
  201.         oUtility.VerifyPathExistsEx LogPath, False
  202.  
  203.  
  204.         ' If debug, echo the message
  205.  
  206.         bConsole = InStr(1,Wscript.FullName,"CSCRIPT.EXE", vbTextCompare ) <> 0
  207.         If bConsole = True then
  208.             Wscript.echo sLogMsg
  209.         End if
  210.  
  211.  
  212.         ' Create the log entry
  213.  
  214.         Set oLog = oFSO.OpenTextFile(LogPath & "\" & LogFile, ForAppending, True)
  215.         oLog.WriteLine sTempMsg
  216.         oLog.Close
  217.  
  218.  
  219.         ' Create the master log entry
  220.  
  221.         Set oLog = oFSO.OpenTextFile(LogPath & "\" & MasterLogFile, ForAppending, True)
  222.         oLog.WriteLine sTempMsg
  223.         oLog.Close
  224.  
  225.  
  226.         ' Write to a network Share Entry
  227.  
  228.         If NetworkLogging <> "" then
  229.             Set oLog = oFSO.OpenTextFile(NetworkLogging & "\" & MasterLogFile, ForAppending, True)
  230.             oLog.WriteLine sTempMsg
  231.             oLog.Close
  232.         End if
  233.  
  234.         On error goto 0
  235.  
  236.     End Function
  237.  
  238.     ' //
  239.     ' // Standard MDT Event Messaging routine, used To send event status messages to a networked log file.
  240.     ' //
  241.     ' //  Standard Error Types
  242.     ' //     Public Const LogTypeInfo     = 1   ' Informational Message
  243.     ' //     Public Const LogTypeWarning  = 2   ' Warning Message
  244.     ' //     Public Const LogTypeError    = 3   ' Error Message
  245.     ' //     Public Const LogTypeVerbose  = 4   ' Verbose Messages only logged when Debug has been set.
  246.     ' //
  247.  
  248.     Function CreateEvent(iEventID, iType, sMessage, arrParms)
  249.  
  250.         Dim sEventFile
  251.         Dim fptr
  252.         Dim sLine
  253.         Dim iMOMType
  254.         Dim sDomain
  255.         Dim sComputer
  256.         Dim sPackage
  257.         Dim sAdvert
  258.         Dim i
  259.         Dim sCurrentStep
  260.         Dim sTotalSteps
  261.  
  262.         Dim sScript
  263.         Dim oService
  264.         Dim sID
  265.         Dim oResult
  266.  
  267.  
  268.         On Error Resume Next
  269.  
  270.  
  271.         ' Log the message specified
  272.  
  273.         CreateEntry sMessage, iType
  274.  
  275.  
  276.         ' Get some information from the task sequence environment for use below (if needed)
  277.  
  278.         sCurrentStep = oEnvironment.Item("_SMSTSNextInstructionPointer")
  279.         If sCurrentStep = "" then
  280.             sCurrentStep = "0"
  281.         End if
  282.         sTotalSteps = oEnvironment.Item("_SMSTSInstructionTableSize")
  283.         If sTotalSteps = "" then
  284.             sTotalSteps = "0"
  285.         End if
  286.  
  287.  
  288.         ' Send events to the event share if specified
  289.  
  290.         If oEnvironment.Item("EventShare") <> "" then
  291.  
  292.             ' Make sure the path is accessible
  293.  
  294.             oUtility.ValidateConnection oEnvironment.Item("EventShare")
  295.  
  296.  
  297.             ' Create a unique file name on the share.
  298.  
  299.             sEventFile = oEnvironment.Item("EventShare") & "\" & oUtility.ComputerName & "_" & oFSO.GetTempName
  300.             Set fptr = oFSO.CreateTextFile(sEventFile, True)
  301.             If Err then
  302.                 CreateEntry "Unable to create event file " & sEventFile & ": " & Err.Description & " (" & Err.Number & ")", LogTypeError
  303.                 Exit function
  304.             End if
  305.  
  306.  
  307.             ' Build the first line to write
  308.  
  309.             Select Case iType
  310.             Case LogTypeInfo
  311.                 iMOMType = 4
  312.             Case LogTypeWarning
  313.                 iMOMType = 2
  314.             Case LogTypeError
  315.                 iMOMType = 1
  316.             End Select
  317.  
  318.             sDomain = oEnvironment.Item("JoinDomain")
  319.             sComputer = oUtility.ComputerName
  320.  
  321.             If oEnvironment.Item("_SMSTSAdvertID") <> "" then
  322.                 sAdvert = oEnvironment.Item("_SMSTSAdvertId")
  323.                 sPackage = oEnvironment.Item("_SMSTSPackageID")
  324.             ElseIf oEnvironment.Item("OSDADVERTID") = "" then
  325.                 sAdvert = "OSD00000"
  326.                 sPackage = "OSD00000"
  327.             Else
  328.                 sAdvert = oEnvironment.Item("OSDADVERTID")
  329.                 sPackage = oEnvironment.Item("OSDPACKAGEID")
  330.             End if
  331.  
  332.  
  333.             ' Write out the first line (common content)
  334.  
  335.             sLine = CStr(iEventID) & "," & CStr(iMOMType) & "," & sDomain & "," & sComputer & "," & sPackage & "," & sAdvert & "," & sCurrentStep & "," & sTotalSteps & "," & oEnvironment.Item("DeploymentMethod")
  336.             fptr.WriteLine sLine
  337.             If Err then
  338.                 CreateEntry "Unable to write event file " & sEventFile & ": " & Err.Description & " (" & Err.Number & ")", LogTypeError
  339.                 Exit function
  340.             End if
  341.  
  342.  
  343.             ' Write out the second line (insertion strings)
  344.  
  345.             fptr.WriteLine Join(arrParms, ",")
  346.             If Err then
  347.                 CreateEntry "Unable to write event file " & sEventFile & ": " & Err.Description & " (" & Err.Number & ")", LogTypeError
  348.                 Exit function
  349.             End if
  350.  
  351.  
  352.             ' Write out the third line (message)
  353.  
  354.             fptr.WriteLine sMessage
  355.             If Err then
  356.                 CreateEntry "Unable to write event file " & sEventFile & ": " & Err.Description & " (" & Err.Number & ")", LogTypeError
  357.                 Exit function
  358.             End if
  359.  
  360.  
  361.             ' Close the file
  362.  
  363.             fptr.Close
  364.             Set fptr = Nothing
  365.  
  366.             CreateEntry "Event " & CStr(iEventID) & " sent: " & sMessage, LogTypeInfo
  367.  
  368.         End if
  369.  
  370.  
  371.         ' Send events to the event service if specified
  372.  
  373.         If oEnvironment.Item("EventService") <> "" then
  374.  
  375.             ' Create a web service object
  376.  
  377.             Set oService = Nothing
  378.             Err.Clear
  379.             Set oService = new WebService
  380.             If Err then
  381.  
  382.                 ' Load ZTIDataAccess.vbs and try again
  383.                 sScript = oFSO.OpenTextFile(oEnv("ScriptRoot") & "\ZTIDataAccess.vbs", 1, false).ReadAll
  384.                 ExecuteGlobal sScript
  385.  
  386.                 Set oService = new WebService
  387.  
  388.             End if
  389.  
  390.             If oService is Nothing then
  391.                 oLogging.CreateEntry "Unable to create WebService class", LogTypeWarning
  392.                 Exit Function
  393.             End if
  394.  
  395.  
  396.             ' Build the parameters to pass to the web service
  397.  
  398.             sService = "PostEvent"
  399.             sID = oEnvironment.Item("UUID") & "," & Join(oEnvironment.ListItem("MacAddress").Keys, ",")
  400.             sLine = "uniqueID=" & oEnvironment.Item("LTIGUID") & "&computerName=" & oUtility.ComputerName & "&messageID=" & CStr(iEventID) & "&severity=" & CStr(iType) & "&stepName=" & oEnvironment.Item("_SMSTSCurrentActionName") & "&currentStep=" & sCurrentStep & "&totalSteps=" & sTotalSteps & "&id=" & sID & "&message=" & sMessage
  401.             sLine = sLine & "&dartIP=" & oEnvironment.Item("DartIP001") & "&dartPort=" & oEnvironment.Item("DartPort001") & "&dartTicket=" & oEnvironment.Item("DartTicket") & "&vmHost=" & oEnvironment.Item("VMHost") & "&vmName=" & oEnvironment.Item("VMName")
  402.  
  403.  
  404.             ' Call the web service
  405.  
  406.             oService.WebService = oEnvironment.Item("EventService") & "/MDTMonitorEvent/PostEvent?" & sLine
  407.             oService.Method = "GET"
  408.             oService.Quiet = true
  409.             Set oResult = oService.Query
  410.  
  411.  
  412.             ' Remember the returned GUID value
  413.  
  414.             If oEnvironment.Item("LTIGUID") <> oResult.DocumentElement.Text then
  415.                 oEnvironment.Item("LTIGUID") = oResult.DocumentElement.Text
  416.             End if
  417.  
  418.  
  419.             CreateEntry "Event " & CStr(iEventID) & " sent: " & sMessage, LogTypeInfo
  420.  
  421.         End if
  422.  
  423.  
  424.     End Function
  425.  
  426.  
  427.  
  428.     Function GetDiscoveryArray
  429.  
  430.         Dim sLine
  431.         Dim dicMac
  432.         Dim arrMac
  433.         Dim i
  434.  
  435.  
  436.         ' Add the local entries
  437.  
  438.         sLine = oEnvironment.Item("PHASE") & "," & oEnvironment.Item("AssetTag") & "," & oEnvironment.Item("UUID")
  439.         Set dicMac = oEnvironment.ListItem("MacAddress")
  440.         arrMac = dicMac.Keys
  441.  
  442.         For i = 0 to 4
  443.             If i > UBound(arrMac) then
  444.                 sLine = sLine & ","
  445.             Else
  446.                 sLine = sLine & "," & arrMac(i)
  447.             End if
  448.         Next
  449.  
  450.  
  451.         ' Add the user data entries (which might not be available yet)
  452.  
  453.         sLine = oEnvironment.Substitute(sLine & "," & oEnvironment.Item("SLShare") & "," & oEnvironment.Item("UDShare") & "," & oEnvironment.Item("UDDir"))
  454.  
  455.  
  456.         ' Split it into an array and return it
  457.  
  458.         GetDiscoveryArray = Split(sLine,",")
  459.  
  460.     End Function
  461.  
  462.  
  463.     Public Function CopyLog()
  464.  
  465.         Dim oFile
  466.         Dim iRetVal, fptr1, fptr2, sLine, sNewLogFolderName, sLogFile
  467.         Dim sComputer
  468.         Dim sLog
  469.         Dim sBootDrive
  470.  
  471.         On Error Resume Next
  472.  
  473.  
  474.         ' Figure out where to copy the local logfile to
  475.  
  476.         If oEnvironment.Item("SLShare") = "" then
  477.             oLogging.CreateEntry "Unable to copy log to the network as no SLShare value was specified.", LogTypeInfo
  478.             Exit Function
  479.         End if
  480.  
  481.  
  482.         ' Make sure the path is accessible
  483.         oUtility.ValidateConnection oEnvironment.Item("SLShare")
  484.         oUtility.VerifyPathExists oEnvironment.Item("SLShare")
  485.         If not oFSO.FolderExists(oEnvironment.Item("SLShare")) then
  486.             oLogging.CreateEntry "An invalid SLShare value of " & oEnvironment.Item("SLShare") & " was specified.", LogTypeWarning
  487.             Exit Function
  488.         End if
  489.  
  490.  
  491.         ' Figure out the computer name
  492.  
  493.         sComputer = oUtility.ComputerName
  494.  
  495.         sBootDrive = oUtility.GetOSTargetDriveLetterEx(false)
  496.         if sBootDrive = "" then
  497.             oLogging.CreateEntry "Destination Logical Drive was not specificed, defaulting to #:\", LogTypeInfo
  498.             sBootDrive = "#:"  ' Unknown Boot Drive
  499.         End if
  500.  
  501.  
  502.         ' Construct the new folder name
  503.  
  504.         sNewLogFolderName = oEnvironment.Item("SLShare") & "\" & sComputer
  505.         oUtility.VerifyPathExists sNewLogFolderName
  506.  
  507.  
  508.         ' Copy all the main logs (except BDD.LOG, which we'll merge later)
  509.  
  510.         For each oFile in oFSO.GetFolder(oLogging.LogPath).Files
  511.             If UCase(oFile.Name) <> "BDD.LOG" and (Right(UCase(oFile.Name), 4) = ".LOG" or Right(UCase(oFile.Name), 4) = ".XML") then
  512.                 oLogging.CreateEntry "Copying " & oLogging.LogPath & "\" & oFile.Name & " to " & sNewLogFolderName & "\" & oFile.Name, LogTypeInfo
  513.                 oFSO.CopyFile oLogging.LogPath & "\" & oFile.Name, sNewLogFolderName & "\", True           
  514.             End if
  515.         Next
  516.  
  517.  
  518.         ' Copy any exceptions we can find
  519.  
  520.         For each sLog in Array("SMSTS.LOG", "Debug\Netsetup.log", "wpeinit.log", "Debug\DCPROMO.LOG", "Debug\DCPROMOUI.LOG", "OSDSetupWizard.log")
  521.  
  522.             If oFSO.FileExists(oEnvironment.Item("SMSTSLogPath_Cache") & "\" & sLog) then
  523.                 oLogging.CreateEntry "Copying " & oEnvironment.Item("SMSTSLogPath_Cache") & "\" & sLog & " to " & sNewLogFolderName & "\" & sLog, LogTypeInfo
  524.                 oFSO.CopyFile oEnvironment.Item("SMSTSLogPath_Cache") & "\" & sLog, sNewLogFolderName & "\", True
  525.             ElseIf oFSO.FileExists(oEnvironment.Item("_SMSTSLogPath") & "\" & sLog) then
  526.                 oLogging.CreateEntry "Copying " & oEnvironment.Item("_SMSTSLogPath") & "\" & sLog & " to " & sNewLogFolderName & "\" & sLog, LogTypeInfo
  527.                 oFSO.CopyFile oEnvironment.Item("_SMSTSLogPath") & "\" & sLog, sNewLogFolderName & "\", True
  528.             ElseIf oFSO.FileExists(oEnv("TEMP") & "\" & sLog) then
  529.                 oLogging.CreateEntry "Copying " & oEnv("TEMP") & "\" & sLog & " to " & sNewLogFolderName & "\" & sLog, LogTypeInfo
  530.                 oFSO.CopyFile oEnv("TEMP") & "\" & sLog, sNewLogFolderName & "\", True
  531.             ElseIf oFSO.FileExists(oEnv("SystemRoot") & "\" & sLog) then
  532.                 oLogging.CreateEntry "Copying " & oENV("SystemRoot") & "\" & sLog & " to " & sNewLogFolderName & "\", LogTypeInfo
  533.                 oFSO.CopyFile oENV("SystemRoot") & "\" & sLog,  sNewLogFolderName & "\", True
  534.             ElseIf oFSO.FileExists(oEnv("SystemRoot") & "\System32\" & sLog) then
  535.                 oLogging.CreateEntry "Copying " & oENV("SystemRoot") & "\System32\" & sLog & " to " & sNewLogFolderName & "\", LogTypeInfo
  536.                 oFSO.CopyFile oENV("SystemRoot") & "\System32\" & sLog,  sNewLogFolderName & "\", True
  537.             End if
  538.  
  539.         Next
  540.  
  541.  
  542.         ' Copy the Panther Logs
  543.  
  544.         If oFSO.FileExists(oENV("SystemRoot") & "\Panther\setupact.log") Then
  545.  
  546.             oUtility.VerifyPathExists sNewLogFolderName & "\Panther"
  547.             OLogging.CreateEntry "Copying " & oENV("SystemRoot") & "\Panther\setupact.log to " & sNewLogFolderName & "\Panther", LogTypeInfo
  548.             oFSO.CopyFile oENV("SystemRoot") & "\Panther\setupact.log",  sNewLogFolderName & "\Panther\", True
  549.         End If
  550.  
  551.         If oFSO.FileExists(oENV("SystemRoot") & "\Panther\setuperr.log") Then
  552.  
  553.             oUtility.VerifyPathExists sNewLogFolderName & "\Panther"
  554.             OLogging.CreateEntry "Copying " & oENV("SystemRoot") & "\Panther\setuperr.log to " & sNewLogFolderName & "\Panther", LogTypeInfo
  555.             oFSO.CopyFile oENV("SystemRoot") & "\Panther\setuperr.log",  sNewLogFolderName & "\Panther\", True
  556.         End If
  557.  
  558.         If oFSO.FileExists(oENV("SystemRoot") & "\Panther\cbs_unattend.log") Then
  559.  
  560.             oUtility.VerifyPathExists sNewLogFolderName & "\Panther"
  561.             OLogging.CreateEntry "Copying " & oENV("SystemRoot") & "\Panther\cbs_unattend.log to " & sNewLogFolderName & "\Panther", LogTypeInfo
  562.             oFSO.CopyFile oENV("SystemRoot") & "\Panther\cbs_unattend.log",  sNewLogFolderName & "\Panther\", True
  563.         End If
  564.  
  565.         If oFSO.FileExists(oENV("SystemRoot") & "\Panther\UnattendGC\setupact.log") Then
  566.  
  567.             oUtility.VerifyPathExists sNewLogFolderName & "\Panther\UnattendGC"
  568.             OLogging.CreateEntry "Copying " & oENV("SystemRoot") & "\Panther\UnattendGC\setupact.log to " & sNewLogFolderName & "\Panther\UnattendGC", LogTypeInfo
  569.             oFSO.CopyFile oENV("SystemRoot") & "\Panther\UnattendGC\setupact.log",  sNewLogFolderName & "\Panther\UnattendGC\", True
  570.         End If
  571.  
  572.         If oFSO.FileExists(oENV("SystemRoot") & "\Panther\UnattendGC\setuperr.log") Then
  573.  
  574.             oUtility.VerifyPathExists sNewLogFolderName & "\Panther\UnattendGC"
  575.             OLogging.CreateEntry "Copying " & oENV("SystemRoot") & "\Panther\UnattendGC\setuperr.log to " & sNewLogFolderName & "\Panther\UnattendGC", LogTypeInfo
  576.             oFSO.CopyFile oENV("SystemRoot") & "\Panther\UnattendGC\setuperr.log",  sNewLogFolderName & "\Panther\UnattendGC\", True
  577.  
  578.         End If         
  579.  
  580.         If oFSO.FileExists(sBootDrive & "\$WINDOWS.~BT\Sources\Panther\setupact.log") Then
  581.  
  582.             oUtility.VerifyPathExists sNewLogFolderName & "\Panther"
  583.             OLogging.CreateEntry "Copying " & sBootDrive & "\$WINDOWS.~BT\Sources\Panther\setupact.log to " & sNewLogFolderName & "\Panther", LogTypeInfo
  584.             oFSO.CopyFile sBootDrive & "\$WINDOWS.~BT\Sources\Panther\setupact.log",  sNewLogFolderName & "\Panther\", True
  585.         End If
  586.  
  587.         If oFSO.FileExists(sBootDrive & "\$WINDOWS.~BT\Sources\Panther\setuperr.log") Then
  588.  
  589.             oUtility.VerifyPathExists sNewLogFolderName & "\Panther"
  590.             OLogging.CreateEntry "Copying " & sBootDrive & "\$WINDOWS.~BT\Sources\Panther\setuperr.log to " & sNewLogFolderName & "\Panther", LogTypeInfo
  591.             oFSO.CopyFile sBootDrive & "\$WINDOWS.~BT\Sources\Panther\setuperr.log",  sNewLogFolderName & "\Panther\", True
  592.         End If
  593.        
  594.         If oFSO.FileExists(sBootDrive & "\$WINDOWS.~BT\Sources\Panther\cbs_unattend.log") Then
  595.  
  596.             oUtility.VerifyPathExists sNewLogFolderName & "\Panther"
  597.             OLogging.CreateEntry "Copying " & sBootDrive & "\$WINDOWS.~BT\Sources\Panther\cbs_unattend.log to " & sNewLogFolderName & "\Panther", LogTypeInfo
  598.             oFSO.CopyFile sBootDrive & "\$WINDOWS.~BT\Sources\Panther\cbs_unattend.log",  sNewLogFolderName & "\Panther\", True
  599.         End If
  600.        
  601.         If oFSO.FileExists(sBootDrive & "\$WINDOWS.~BT\Sources\Panther\UnattendGC\setupact.log") Then
  602.  
  603.             oUtility.VerifyPathExists sNewLogFolderName & "\Panther\UnattendGC"
  604.             OLogging.CreateEntry "Copying " & sBootDrive & "\$WINDOWS.~BT\Sources\Panther\UnattendGC\setupact.log to " & sNewLogFolderName & "\Panther\UnattendGC", LogTypeInfo
  605.             oFSO.CopyFile sBootDrive & "\$WINDOWS.~BT\Sources\Panther\UnattendGC\setupact.log",  sNewLogFolderName & "\Panther\UnattendGC\", True
  606.         End If
  607.  
  608.         If oFSO.FileExists(sBootDrive & "\$WINDOWS.~BT\Sources\Panther\UnattendGC\setuperr.log") Then
  609.  
  610.             oUtility.VerifyPathExists sNewLogFolderName & "\Panther\UnattendGC"
  611.             OLogging.CreateEntry "Copying " & sBootDrive & "\$WINDOWS.~BT\Sources\Panther\UnattendGC\setuperr.log to " & sNewLogFolderName & "\Panther\UnattendGC", LogTypeInfo
  612.             oFSO.CopyFile sBootDrive & "\$WINDOWS.~BT\Sources\Panther\UnattendGC\setuperr.log",  sNewLogFolderName & "\Panther\UnattendGC\", True
  613.  
  614.         End If                 
  615.  
  616.  
  617.  
  618.         ' Make sure we have a local log file; it might not exist if the disk isn't yet writable.
  619.  
  620.         sLogFile = LogPath & "\" & MasterLogFile
  621.         If not oFSO.FileExists(sLogFile) then
  622.             oLogging.CreateEntry "Master log file " & sLogFile & " was not found, unable to copy to " & sNewLogFolderName & "\BDD.LOG", LogTypeInfo
  623.             Exit Function
  624.         End if
  625.  
  626.  
  627.         ' Copy the file contents to the end of the network file. (It might already exist from a previous action, so append to it.)
  628.  
  629.         oLogging.CreateEntry "Copying log " & sLogFile & " contents to " & sNewLogFolderName & "\BDD.LOG", LogTypeInfo
  630.  
  631.         Set fptr1 = oFSO.OpenTextFile(sLogFile, ForReading, True)
  632.         If Err then
  633.             oLogging.CreateEntry "Unable to open " & sLogFile & " for reading: " & Err.Description & " (" & Err.Number & ")", LogTypeInfo
  634.             Err.Clear
  635.             Exit Function
  636.         End if
  637.  
  638.         Set fptr2 = oFSO.OpenTextFile(sNewLogFolderName & "\BDD.LOG", ForAppending, True)
  639.         If Err then
  640.             oLogging.CreateEntry "Unable to open " & sNewLogFolderName & "\BDD.LOG for appending: " & Err.Description & " (" & Err.Number & ")", LogTypeInfo
  641.             Err.Clear
  642.             Exit Function
  643.         End if
  644.  
  645.         Do while Not fptr1.AtEndOfStream
  646.             sLine = fptr1.readline
  647.             fptr2.writeline sLine
  648.         Loop
  649.  
  650.         fptr1.Close
  651.         fptr2.Close
  652.  
  653.  
  654.         Err.Clear
  655.         On Error Goto 0
  656.  
  657.     End Function
  658.  
  659.  
  660.     Public Function ReportProgress(sMsg, iPercent)
  661.  
  662.         Dim iMaxPercent
  663.         Dim oProgress
  664.         Dim uStep
  665.         Dim uMaxStep
  666.  
  667.         CreateEntry "Update progress [ " & iPercent & " ] : " & sMsg , LogTypeVerbose
  668.  
  669.  
  670.         ' Try to create the progress UI object
  671.  
  672.         On Error Resume Next
  673.         Set oProgress = CreateObject("Microsoft.SMS.TSProgressUI")
  674.         If Err then
  675.             Err.Clear
  676.  
  677.             ' Record the progress in the registry
  678.  
  679.             oShell.RegWrite "HKLM\Software\Microsoft\Deployment 4\ProgressPercent", iPercent, "REG_DWORD"
  680.             oShell.RegWrite "HKLM\Software\Microsoft\Deployment 4\ProgressText", sMsg, "REG_SZ"
  681.  
  682.             on error goto 0
  683.             Exit Function
  684.         End if
  685.         On Error Goto 0
  686.  
  687.  
  688.         ' Update the progress
  689.  
  690.         On Error Resume Next
  691.  
  692.         iMaxPercent = 100
  693.         uStep = CLng(oEnvironment.Item("_SMSTSNextInstructionPointer"))
  694.         uMaxStep = CLng(oEnvironment.Item("_SMSTSInstructionTableSize"))
  695.         Call oProgress.ShowActionProgress(oEnvironment.Item("_SMSTSOrgName"), oEnvironment.Item("_SMSTSPackageName"), oEnvironment.Item("_SMSTSCustomProgressDialogMessage"), oEnvironment.Item("_SMSTSCurrentActionName"), (uStep), (uMaxStep), sMsg, (iPercent), (iMaxPercent))
  696.         If Err then
  697.             CreateEntry "Unable to update progress: " & Err.Description & " (" & Err.Number & ")", LogTypeInfo
  698.             ReportProgress = Failure
  699.             Err.Clear
  700.             Exit Function
  701.         End if
  702.  
  703.         On Error Goto 0
  704.  
  705.  
  706.         ' Dispose of the object
  707.  
  708.         Set oProgress = Nothing
  709.  
  710.     End Function
  711.  
  712.  
  713.     Property Get LogPath
  714.  
  715.         Dim iRetVal
  716.         LogPath = oUtility.LogPath
  717.         'Preserve the existing logpath before creating the new logpath
  718.        
  719.         If Ucase(oUtility.ScriptName) = "ZTIDISKPART" and Left(LogPath,2)<> "X:" Then
  720.             oUtility.VerifyPathExistsEx "X:\MININT\SMSOSD\OSDLOGS", FALSE
  721.             LogPath = "X:\MININT\SMSOSD\OSDLOGS"
  722.         End If
  723.        
  724.         If oEnvironment.Item("LogPath") <> "" AND oEnvironment.Item("LogPath") <> LogPath And Ucase(oUtility.ScriptName) <> "LTICLEANUP" Then
  725.  
  726.             On Error Resume Next
  727.             iRetVal = oShell.Run("xcopy """ & oEnvironment.Item("LogPath") & """ """ & LogPath & """ /D /s /e /h /y /c",0, true)
  728.             oEnvironment.Item("LogPath") = LogPath
  729.             on Error goto 0
  730.  
  731.         End If
  732.         If oEnvironment.Item("LogPath") = "" And Ucase(oUtility.ScriptName) <> "LTICLEANUP" Then   
  733.  
  734.             oEnvironment.Item("LogPath") = LogPath
  735.  
  736.         End If
  737.  
  738.     End Property
  739.  
  740.  
  741.     Function ReportFailure ( sMessage, iError )
  742.  
  743.         CreateEvent 41002, LogTypeError, oEnvironment.Substitute( "FAILURE ( " & FormatError(iError) & " ): " & sMessage ), Array(iError)
  744.  
  745.         ' It is possible that we are are not running in the Wscript Host ( HTML Page ).
  746.         on error resume next
  747.             WScript.Quit iError
  748.         on error goto 0
  749.  
  750.     End function
  751.  
  752.  
  753.     ' //
  754.     ' //  Perform an inline check of the condition and write out the message
  755.     ' //    iRC can be either SUCCESS (0), FAILURE(not 0) as defined above.
  756.     ' //    or iRC can be Boolean either TRUE or FALSE
  757.     ' //  
  758.     ' //  Anything other than Success or Failure will log a Warning or Error.
  759.     ' //
  760.     Function TRACEEX( iRc, iError, sMessage, bFatal)
  761.  
  762.         TRACEEX = iRc
  763.  
  764.         If Err then
  765.  
  766.             ' Error
  767.             TRACEEX = Err.Number
  768.             sMessage = sMessage & " - " & Err.Description
  769.             CreateEntry oEnvironment.Substitute( "FAILURE (Err): " & FormatError(TRACEEX) & ": " & sMessage ), LogTypeWarning
  770.             If bFatal then
  771.                 ' Fatial Error
  772.                 ReportFailure sMessage, iError
  773.             End if
  774.  
  775.         Elseif (VarType(iRC) = vbInteger) or (VarType(iRC) = vbLong) or (VarType(iRC) = vbBoolean) then
  776.  
  777.             ' iRC is either a Variant Integer (Either SUCCESS or FAILURE), or a Variant Bool (Either True or False)
  778.            
  779.             If ( (iRC = Success or iRC = 3010) and ((VarType(iRC) = vbInteger) or (VarType(iRC) = vbLong)) ) or ( iRC = TRUE and VarType(iRC) = vbBoolean ) then
  780.                 CreateEntry oEnvironment.Substitute( "SUCCESS: " & FormatError(iRC) & ": " & sMessage ), LogTypeVerbose
  781.             ElseIf bFatal then
  782.                 ' Fatial Error
  783.                 ReportFailure  FormatError(iRC) & ": " & sMessage, iError
  784.             Else
  785.                 CreateEntry oEnvironment.Substitute( "FAILURE: " & FormatError(iRC) & ": " & sMessage ), LogTypeWarning
  786.             End if
  787.            
  788.         Elseif (VarType(iRC) <> vbEmpty) and (VarType(iRC) <> vbNull ) then
  789.  
  790.             CreateEntry oEnvironment.Substitute( "UNKNOWN: " & TypeName(iRc) & " = " & iRc & " : " & FormatError(iError) & ": " & sMessage ), LogTypeWarning
  791.  
  792.         End if
  793.  
  794.     End function
  795.  
  796.  
  797.     Function ProcessResults( iRc )
  798.         Dim iMainRc
  799.         Dim sError
  800.         Dim sMainRc
  801.  
  802.         iMainRc = iRc
  803.         sMainRc = FormatError ( iMainRc )
  804.         If Err then
  805.             iMainRc = Err.Number
  806.             sError = Err.Description
  807.             sMainRc = FormatError ( iMainRc )
  808.             CreateEvent 41002, LogTypeError, "ZTI ERROR - Unhandled error returned by " & oUtility.ScriptName & ": " & sError & " (" & sMainRc & ")", Array(iMainRc)
  809.         ElseIf iRc <> Success then
  810.             CreateEvent 41002, LogTypeError, "ZTI ERROR - Non-zero return code by " & oUtility.ScriptName & ", rc = " & sMainRc, Array(iMainRc)
  811.         Else
  812.             CreateEvent 41001, LogTypeInfo, oUtility.ScriptName & " processing completed successfully.", Array()
  813.         End if
  814.         WScript.Quit iMainRc
  815.  
  816.     End function
  817.  
  818.     Function FormatError( iError )
  819.  
  820.         ' Error messages above 0x1000000 are most likely Hex values, print both Hex and Decimal
  821.         If not isNumeric( iError ) then
  822.             FormatError = ""
  823.         ElseIf Abs(iError) >= &H1000000 then
  824.             FormatError = cstr(iError) & "  0x" & right( "00000000" & hex ( iError ), 8 )
  825.         Else
  826.             FormatError = cstr(iError)
  827.         End if
  828.  
  829.     End function
  830.  
  831.  
  832. End Class
  833.  
  834. ' //////////////////////////////////////////////////////
  835.  
  836.  
  837.  
  838.  
  839. Class Environment
  840.  
  841.     ' ***  Public variables ***
  842.  
  843.     Public PersistFile
  844.  
  845.  
  846.     ' ***  Private variables ***
  847.  
  848.     Private oVariables
  849.     Private dLastModified
  850.     Private dLastSize
  851.     Private osdV4
  852.  
  853.  
  854.     ' ***  Constructor and destructor ***
  855.  
  856.     Private Sub Class_Initialize
  857.  
  858.         PersistFile = "VARIABLES.DAT"
  859.  
  860.  
  861.         On Error Resume Next
  862.         Err.Clear
  863.         Set oVariables = oUtility.CreateXMLDOMObject
  864.         If Err then
  865.             ' Unable to create XML object
  866.             Err.Clear
  867.         End if
  868.         On Error Goto 0
  869.         dLastModified = 0
  870.         dLastSize = 0
  871.  
  872.  
  873.         ' Create SMSv4 Task Sequence environment
  874.  
  875.         On Error Resume Next
  876.         Err.Clear
  877.         Set osdV4 = CreateObject("Microsoft.SMS.TSEnvironment")
  878.         If Err then
  879.             Set osdV4 = Nothing
  880.             Err.Clear
  881.         End if
  882.         On Error Goto 0
  883.  
  884.         Err.Clear
  885.  
  886.     End Sub
  887.  
  888.  
  889.     ' ***  Private methods ***
  890.  
  891.     Function GetOSDV4(sVariable)
  892.  
  893.         GetOSDV4 = ""
  894.         On Error Resume Next
  895.         If osdV4 is Nothing then
  896.             Exit Function
  897.         Else
  898.             GetOSDV4 = osdV4(sVariable)
  899.             If Err then
  900.                 ' oLogging.CreateEntry "WARNING - Unable to get SMSv4 Task Sequencer environment: " & Err.Description & " (" & Err.Number & ")", LogTypeWarning
  901.             End if
  902.         End if
  903.         On Error Goto 0
  904.         Err.Clear
  905.  
  906.     End Function
  907.  
  908.     Function SetOSDV4(sVariable, sNew)
  909.         On Error Resume Next
  910.         If osdV4 is Nothing then
  911.             SetOSDV4 = False
  912.             Exit Function
  913.         Else
  914.             osdV4(sVariable) = sNew
  915.             If Err then
  916.                 ' oLogging.CreateEntry "WARNING - Unable to get SMSv4 Task Sequencer environment: " & Err.Description & " (" & Err.Number & ")", LogTypeWarning
  917.                 SetOSDV4 = False
  918.             End if
  919.         End if
  920.         On Error Goto 0
  921.         Err.Clear
  922.         SetOSDV4 = True
  923.  
  924.     End Function
  925.  
  926.     Property Get VariablesDat
  927.         Dim sVariablesFile
  928.  
  929.         ' If necessary, load the XML file
  930.  
  931.         sVariablesFile = PersistPath & "\" & PersistFile
  932.         If oFSO.FileExists(sVariablesFile) then
  933.             If (oFSO.GetFile(sVariablesFile).DateLastModified <> dLastModified) or (oFSO.GetFile(sVariablesFile).Size <> dLastSize) then
  934.                 On Error Resume Next
  935.                 Do
  936.                     oVariables.Load sVariablesFile
  937.                     dLastModified = oFSO.GetFile(sVariablesFile).DateLastModified
  938.                     dLastSize = oFSO.GetFile(sVariablesFile).Size
  939.                 Loop While oVariables.DocumentElement is Nothing
  940.                 On Error Goto 0
  941.             End if
  942.         ElseIf dLastModified = 0 then
  943.             oVariables.LoadXml "<?xml version=""1.0"" ?><MediaVarList Version=""4.00.5345.0000""></MediaVarList>"
  944.             dLastModified = Now  ' The file hasn't been saved yet, but we don't want to reset this
  945.         End if
  946.  
  947.  
  948.         ' Set the return value to the XML document
  949.  
  950.         Set VariablesDat = oVariables
  951.  
  952.     End Property
  953.  
  954.     Function GetDAT(sVariable)
  955.         Dim sLockFile
  956.         Dim oNode
  957.         Dim fLock
  958.  
  959.         GetDAT = ""
  960.  
  961.         If Ucase(oUtility.ScriptName) <> "LTICLEANUP" Then
  962.             sLockFile = PersistPath & "\" & PersistFile & ".LOCK"
  963.             On error resume next
  964.             Set fLock = nothing
  965.             Set fLock = oFSO.CreateTextFile(sLockFile, 2, true)
  966.             Do while fLock is nothing
  967.                 dLastModified = 0 ' FORCE a rescan.
  968.                 ' ologging.CreateEntry sLockFile & " is locked by another process, Wait!", LogTypeVerbose
  969.                 oUtility.SafeSleep 10
  970.                 Set fLock = oFSO.CreateTextFile( sLockFile, 2, true)
  971.             Loop
  972.             On error goto 0
  973.         End if
  974.  
  975.  
  976.         On Error Resume Next
  977.         Set oNode = Nothing
  978.         Set oNode = VariablesDat.DocumentElement.SelectSingleNode("//var[@name='" & UCase(sVariable) & "']")
  979.         On Error Goto 0
  980.         If not (oNode is Nothing) then
  981.             GetDAT = oNode.Text
  982.         End if
  983.  
  984.     End Function
  985.  
  986.     Function SetDAT(sVariable, sNew)
  987.         Dim sVariablesFile
  988.         Dim sLockFile
  989.         Dim oNode, oCDATA, oVD
  990.         Dim fLock
  991.        
  992.         If osdv4 is Nothing OR oEnvironment.Item("_SMSTSStandAloneMode") = "true" then
  993.             If oFSO.FolderExists(PersistPath) then
  994.  
  995.                 sVariablesFile = PersistPath & "\" & PersistFile
  996.  
  997.                 If Ucase(oUtility.ScriptName) <> "LTICLEANUP" Then
  998.                     sLockFile = PersistPath & "\" & PersistFile & ".LOCK"
  999.                     On error resume next
  1000.                     Set fLock = nothing
  1001.                     Set fLock = oFSO.CreateTextFile(sLockFile, 2, true)
  1002.                     Do while fLock is nothing
  1003.                         dLastModified = 0 ' FORCE a rescan.
  1004.                         ' ologging.CreateEntry sLockFile & " is locked by another process, Wait!", LogTypeVerbose
  1005.                         oUtility.SafeSleep 10
  1006.                         Set fLock = oFSO.CreateTextFile(sLockFile, 2, true)
  1007.                     Loop
  1008.                     On error goto 0
  1009.                 End if
  1010.  
  1011.                 Set oVD = VariablesDat
  1012.  
  1013.  
  1014.                 ' See if the variable is already defined.  If not, append a new node
  1015.  
  1016.                 Set oNode = oVD.DocumentElement.SelectSingleNode("//var[@name='" & UCase(sVariable) & "']")
  1017.                 If oNode is Nothing then
  1018.                     Set oNode = oVD.CreateElement("var")
  1019.                     oVD.DocumentElement.appendChild oNode
  1020.                 Else
  1021.                     If oNode.Text = sNew then
  1022.                         ' oLogging.CreateEntry "Not changing variable " & sVariable & " because the value was not changed.", LogTypeInfo
  1023.                         SetDAT = True
  1024.                         Exit Function
  1025.                     End if
  1026.                 End if
  1027.  
  1028.  
  1029.                 ' Set the name of the node
  1030.  
  1031.                 oNode.SetAttribute "name", UCase(sVariable)
  1032.  
  1033.  
  1034.                 ' Set the value of the node
  1035.  
  1036.                 Set oCDATA = oVD.createCDATASection(sNew)
  1037.                 If oNode.hasChildNodes then
  1038.                     oNode.removeChild(oNode.childNodes.item(0))
  1039.                 End if
  1040.                 oNode.appendChild(oCDATA)
  1041.  
  1042.  
  1043.                 ' Save the updated XML file
  1044.  
  1045.                 On Error Resume Next
  1046.                 oVD.Save sVariablesFile
  1047.                 dLastModified = oFSO.GetFile(sVariablesFile).DateLastModified
  1048.                 dLastSize = oFSO.GetFile(sVariablesFile).Size
  1049.                 If Err then
  1050.                     oLogging.CreateEntry "WARNING - Unable to persist items to " & sVariablesFile & ": " & Err.Description & " (" & Err.Number & ")", LogTypeWarning
  1051.                     SetDat = False
  1052.                     Err.Clear
  1053.                 End if
  1054.                 On Error Goto 0
  1055.             Else
  1056.                 SetDat=False
  1057.             End if
  1058.         Else
  1059.             SetDat = False
  1060.         End If
  1061.         SetDat = True
  1062.     End Function
  1063.  
  1064.  
  1065.     Function ObfuscateEncode(sVariable, sNew)
  1066.  
  1067.         Select Case Ucase(sVariable)
  1068.         Case "USERID", "USERPASSWORD", "USERDOMAIN", "DOMAINADMIN", "DOMAINADMINPASSWORD", "DOMAINADMINDOMAIN", _
  1069.                    "ADMINPASSWORD", "BDEPIN", "TPMOWNERPASSWORD",  "USERNAME", "USERPASSWORD", "PRODUCTKEY", "OSDJOINACCOUNT",_
  1070.                    "SAFEMODEADMINPASSWORD","OSDJOINPASSWORD"
  1071.             ObfuscateEncode = oStrings.Base64Encode(sNew)
  1072.         Case Else
  1073.             ObfuscateEncode = sNew
  1074.         End Select
  1075.  
  1076.     End Function
  1077.  
  1078.  
  1079.     Function ObfuscateDecode(sVariable, sCurrent)
  1080.  
  1081.         Select Case Ucase(sVariable)
  1082.         Case "USERID", "USERPASSWORD", "USERDOMAIN", "DOMAINADMIN", "DOMAINADMINPASSWORD", "DOMAINADMINDOMAIN", _
  1083.                    "ADMINPASSWORD", "BDEPIN", "TPMOWNERPASSWORD",  "USERNAME", "USERPASSWORD", "PRODUCTKEY", "OSDJOINACCOUNT",_
  1084.                    "SAFEMODEADMINPASSWORD","OSDJOINPASSWORD"
  1085.             ObfuscateDecode = oStrings.Base64Decode(sCurrent)
  1086.  
  1087.  
  1088.             ' If the variable wasn't a valid base64 string, an empty string will be returned.  Instead of
  1089.             ' passing that back, return the current value.  (The Base64Decode method should log a warning.)
  1090.  
  1091.             If ObfuscateDecode = "" and sCurrent <> "" then
  1092.                 ObfuscateDecode = sCurrent
  1093.             End if
  1094.  
  1095.         Case Else
  1096.             ObfuscateDecode = sCurrent
  1097.         End Select
  1098.  
  1099.     End Function
  1100.  
  1101.  
  1102.     ' ***  Public methods ***
  1103.  
  1104.     Public Property Get Exists(sVariable)
  1105.  
  1106.         If Item(sVariable) <> "" then
  1107.             Exists = True
  1108.         Else
  1109.             Exists = False
  1110.         End if
  1111.  
  1112.     End Property
  1113.  
  1114.  
  1115.     Public Property Get Item(sVariable)
  1116.  
  1117.         Dim sOriginal
  1118.         Dim bSync
  1119.  
  1120.  
  1121.         ' First try TS environment, then (for Lite Touch only) try the XML file
  1122.        
  1123.         Item = GetOSDV4(sVariable)
  1124.         If Item = "" and GetOSDV4("DeploymentMethod") <> "SCCM" then
  1125.  
  1126.             ' No value retrieved from the task sequence, try the XML file
  1127.  
  1128.             Item = GetDat(sVariable)
  1129.             If Item <> "" then
  1130.                 bSync = true
  1131.             End if
  1132.  
  1133.         End if
  1134.  
  1135.  
  1136.         ' Decode and sync if not blank
  1137.  
  1138.         If Item <> "" then
  1139.  
  1140.             ' Decode the variable
  1141.  
  1142.             sOriginal = Item
  1143.             Item = ObfuscateDecode(sVariable, sOriginal)
  1144.  
  1145.  
  1146.             ' Try to set the value in the task sequence environment (sync)
  1147.  
  1148.             If bSync then
  1149.                 SetOSDV4 sVariable, sOriginal
  1150.             End if
  1151.  
  1152.         End if
  1153.  
  1154.     End Property
  1155.  
  1156.  
  1157.     Public Property Let Item(sVariable, sNew)
  1158.  
  1159.         Dim sEncoded
  1160.  
  1161.  
  1162.         ' Encode as required
  1163.  
  1164.         sEncoded = ObfuscateEncode(sVariable, sNew)
  1165.  
  1166.  
  1167.         ' Save to all available environments
  1168.  
  1169.         If SetOSDV4(sVariable, sEncoded) or SetDat(sVariable, sEncoded) Then
  1170.             oLogging.CreateEntry "Property " & sVariable & " is now = " & sNew, LogTypeInfo
  1171.         End If
  1172.  
  1173.  
  1174.         ' For completeness, set the variable in the process's environment as well
  1175.  
  1176.         oEnv(sVariable) = sNew
  1177.  
  1178.     End Property
  1179.  
  1180.  
  1181.     Public Property Get ListItem(sVariable)
  1182.  
  1183.         Dim i
  1184.         Dim sPadded
  1185.  
  1186.         Set ListItem = CreateObject("Scripting.Dictionary")
  1187.         For i = 1 to 999
  1188.  
  1189.             sPadded = sVariable & Right("000" & CStr(i), 3)
  1190.             If Item(sPadded) <> "" then
  1191.                 If not ListItem.Exists(Item(sPadded)) then
  1192.                     ListItem.Add Item(sPadded), ""
  1193.                 End if
  1194.             ElseIf Item(sVariable & CStr(i)) <> "" then
  1195.                 If not ListItem.Exists(Item(sVariable & CStr(i))) then
  1196.                     ListItem.Add Item(sVariable & CStr(i)), ""
  1197.                 End if
  1198.             Else
  1199.                 Exit For  ' Exit on first "not found" entry
  1200.             End if
  1201.  
  1202.         Next
  1203.  
  1204.     End Property
  1205.  
  1206.     Public Sub SetListItemEx (sVariable, sNew)
  1207.  
  1208.         Dim sElement
  1209.         Dim i
  1210.         Dim sPadded
  1211.  
  1212.         i = 0
  1213.         For each sElement in sNew
  1214.             i = i + 1
  1215.             sPadded = sVariable & Right("000" & CStr(i), 3)
  1216.             Item(sPadded) = sElement
  1217.         Next
  1218.  
  1219.  
  1220.         ' Blank out the next in case there was something there
  1221.  
  1222.         sPadded = sVariable & Right("000" & CStr(i+1), 3)
  1223.         If Exists(sPadded) then
  1224.             Item(sPadded) = ""
  1225.         End if
  1226.  
  1227.  
  1228.         ' Blank out the non-list item if it was there
  1229.  
  1230.         If exists(sVariable) then
  1231.             Item(sVariable) = ""
  1232.         End if
  1233.  
  1234.     End sub
  1235.  
  1236.     Public Property Set ListItem(sVariable, sNew)
  1237.  
  1238.         SetListItemEx sVariable, sNew
  1239.  
  1240.     End Property
  1241.  
  1242.     Public Property Let ListItem(sVariable, sNew)
  1243.  
  1244.         SetListItemEx sVariable, sNew
  1245.  
  1246.     End Property
  1247.  
  1248.  
  1249.     Public Property Get IndirectItem( sVariable )
  1250.  
  1251.         IndirectItem = oEnvironment.Item(oEnvironment.Item(sVariable))
  1252.  
  1253.     End Property
  1254.  
  1255.     Public Property Let IndirectItem( sVariable, sNew )
  1256.  
  1257.         If oEnvironment.Item(sVariable) = "" then
  1258.             oLogging.CreateEntry "Invalid MDT Indirect Variable pointer: " & sVariable, LogTypeWarning
  1259.         Else
  1260.             oEnvironment.Item(oEnvironment.Item(sVariable)) = sNew
  1261.         End if
  1262.  
  1263.     End Property
  1264.  
  1265.  
  1266.     Function Substitute(sVal)
  1267.  
  1268.         Dim sReplace, iPos, iEnd, sEval
  1269.  
  1270.         ' Substitute the appropriate values
  1271.  
  1272.         iPos = Instr(sVal, "%")
  1273.         While iPos > 0
  1274.  
  1275.             ' Find ending "%"
  1276.             iEnd = Instr(iPos+1, sVal, "%")
  1277.             If iEnd > 0 then
  1278.  
  1279.                 sEval = Mid(sVal, iPos+1, iEnd - iPos - 1)
  1280.  
  1281.                 sReplace = ""
  1282.                 If oEnvironment.ListItem(sEval).Count > 0 then
  1283.                     For each sReplace in oEnvironment.ListItem(sEval).Keys
  1284.                         Exit For  ' Grab the first value
  1285.                     Next
  1286.                 ElseIf oEnvironment.Item(sEval) <> "" then
  1287.                     sReplace = oEnvironment.Item(sEval)
  1288.                 End if
  1289.  
  1290.                 If sReplace <> "" then
  1291.                     If iPos = 1 then
  1292.                         sVal = CStr(sReplace) & Mid(sVal, iEnd + 1)
  1293.                     ElseIf iEnd = Len(sVal) then
  1294.                         sVal = Left(sVal, iPos - 1) & CStr(sReplace)
  1295.                     Else
  1296.                         sVal = Left(sVal, iPos - 1) & CStr(sReplace) & Mid(sVal, iEnd + 1)
  1297.                     End if
  1298.                     iPos = Instr(sVal, "%")
  1299.                 Else
  1300.                     iPos = iEnd
  1301.                 End if
  1302.             Else
  1303.                 iPos = iEnd
  1304.             End if
  1305.         WEnd
  1306.  
  1307.  
  1308.         ' Expand any environment variables
  1309.  
  1310.         sVal = oShell.ExpandEnvironmentStrings(sVal)
  1311.  
  1312.  
  1313.         ' Finally, look for evaluate blocks
  1314.  
  1315.         iPos = Instr(sVal, "#")
  1316.         While iPos > 0
  1317.  
  1318.             ' Find ending "#"
  1319.             iEnd = Instr(iPos+1, sVal, "#")
  1320.             If iEnd > 0 then
  1321.            
  1322.                 sEval = Mid(sVal, iPos+1, iEnd - iPos - 1)
  1323.                
  1324.                 sReplace = empty
  1325.                 On Error Resume Next
  1326.                 sReplace = Eval(sEval)
  1327.                 On Error Goto 0
  1328.                
  1329.                 If not isEmpty(sReplace) then
  1330.                     If iPos = 1 then
  1331.                         sVal = sReplace & Mid(sVal, iEnd + 1)
  1332.                     ElseIf iEnd = Len(sVal) then
  1333.                         sVal = Left(sVal, iPos - 1) & sReplace
  1334.                     Else
  1335.                         sVal = Left(sVal, iPos - 1) & sReplace & Mid(sVal, iEnd + 1)
  1336.                     End if
  1337.                     iPos = Instr(sVal, "#")
  1338.                 Else
  1339.                     iPos = iEnd
  1340.                 End if
  1341.             Else
  1342.                 iPos = iEnd
  1343.             End if
  1344.  
  1345.         WEnd
  1346.  
  1347.         Substitute = Trim(sVal)
  1348.  
  1349.     End Function
  1350.  
  1351.  
  1352.     Public Property Get PersistPath
  1353.         Dim oOrigPersistFile
  1354.         Dim oNewPersistFile
  1355.         PersistPath = oUtility.LogPath
  1356.  
  1357.         If oEnv("SystemDrive") = "X:" then
  1358.             If oFSO.FileExists("X:\minint\smsosd\osdlogs\variables.dat") Then
  1359.                 Set oOrigPersistFile = oFSO.GetFile("X:\minint\smsosd\osdlogs\variables.dat")
  1360.                 If oFSO.FileExists(PersistPath & "\VARIABLES.DAT") Then
  1361.                     Set oNewPersistFile = oFSO.GetFile(PersistPath & "\VARIABLES.DAT")
  1362.  
  1363.                     If oOrigPersistFile.Size > oNewPersistFile.Size Then
  1364.                         oFSO.CopyFile "X:\minint\smsosd\osdlogs\variables.dat", PersistPath & "\VARIABLES.DAT", true
  1365.                     End if
  1366.                 Else
  1367.                     oFSO.CopyFile "X:\minint\smsosd\osdlogs\variables.dat", PersistPath & "\VARIABLES.DAT", true
  1368.                 End if
  1369.             End if
  1370.  
  1371.         End if
  1372.  
  1373.     End Property
  1374.  
  1375.  
  1376.     Public Function Release
  1377.  
  1378.         Set osdV4 = Nothing
  1379.  
  1380.     End Function
  1381.  
  1382. End Class
  1383.  
  1384.  
  1385. Class Utility
  1386.  
  1387.     ' ***  Properties ***
  1388.  
  1389.     Public isHTML
  1390.     Public isWSH
  1391.     Public isMSHTA
  1392.     Public isCScript
  1393.     Public isWScript
  1394.     Public oMSHTA
  1395.     Public Arguments
  1396.  
  1397.     ' ***  Private variables ***
  1398.  
  1399.     Dim dicNetworkConnections
  1400.     Dim sScriptDir
  1401.     Dim oBDDUtility
  1402.     Dim oSupportedPlatforms
  1403.     Private sLocalRootPath
  1404.     Private bCacheLocalRootPath
  1405.     Private startTime
  1406.     Private lastHeartbeat
  1407.     Private iVersionMajor
  1408.     Private iVersionMinor
  1409.     Private iBuildNumber
  1410.     Private iRevision
  1411.  
  1412.     ' ***  Constructor and destructor ***
  1413.  
  1414.     Private Sub Class_Initialize
  1415.  
  1416.         Dim re
  1417.         Dim arrDrives, i
  1418.         Dim oContext, oLocator
  1419.  
  1420.  
  1421.         ' Initialize the objects
  1422.  
  1423.         Set oFSO = CreateObject("Scripting.FileSystemObject")
  1424.         Set oShell = CreateObject("WScript.Shell")
  1425.         Set oEnv = oShell.Environment("PROCESS")
  1426.         Set oNetwork = CreateObject("WScript.Network")
  1427.  
  1428.         Set objWMI = Nothing
  1429.         On Error Resume Next
  1430.         Set oContext = CreateObject("WbemScripting.SWbemNamedValueSet")
  1431.         oContext.Add "__ProviderArchitecture", 64
  1432.         Set oLocator = CreateObject("Wbemscripting.SWbemLocator")
  1433.         Set objWMI = oLocator.ConnectServer("","root\cimv2","","",,,,oContext)
  1434.         On Error Goto 0
  1435.  
  1436.         Set dicNetworkConnections = CreateObject("Scripting.Dictionary")
  1437.         dicNetworkConnections.CompareMode = TextCompare
  1438.         Set oBDDUtility = Nothing
  1439.         Set oSupportedPlatforms = Nothing
  1440.  
  1441.         isHTML = FALSE
  1442.         isWSH = FALSE
  1443.         isMSHTA = FALSE
  1444.         isCScript = FALSE
  1445.         isWScript = FALSE
  1446.         set oMSHTA = nothing
  1447.    
  1448.        
  1449.         on error resume next
  1450.             isHTML = IsObject(window.location)
  1451.             isWSH = IsObject(WScript)
  1452.         on error goto 0
  1453.  
  1454.         If isHTML Then
  1455.             isMSHTA = document.all.tags("Application").length > 0
  1456.             On error resume next
  1457.             set oMSHTA = document.all.tags("Application")(0)
  1458.             if window.location.hostname <> "" then
  1459.                 sScriptDir = oFSO.GetParentFolderName( unescape("\\" & window.location.hostname & window.location.pathname ) )
  1460.             else
  1461.                 sScriptDir = oFSO.GetParentFolderName( unescape(window.location.pathname) )
  1462.             end if
  1463.             On error goto 0
  1464.  
  1465.         ElseIf isWSH Then
  1466.             isCScript = ucase(right(WScript.FullName,len("Xscript.exe"))) = "CSCRIPT.EXE"
  1467.             isWScript = ucase(right(WScript.FullName,len("Xscript.exe"))) = "WSCRIPT.EXE"
  1468.             sScriptDir = oFSO.GetParentFolderName(WScript.ScriptFullName)
  1469.  
  1470.         End if
  1471.  
  1472.  
  1473.         If Mid(sScriptDir, 2, 2) = ":\" then
  1474.  
  1475.             ' Look to see if this is a mapped drive
  1476.  
  1477.             On Error Resume Next
  1478.             Set arrDrives = oNetwork.EnumNetworkDrives
  1479.             If Err then
  1480.                 On Error Goto 0
  1481.                 oLogging.CreateEntry "ERROR - Network is unavailable: " & Err.Description & " (" & Err.Number & ")", LogTypeError
  1482.             Else
  1483.                 On Error Goto 0
  1484.                 For i = 0 to arrDrives.Count - 1 Step 2
  1485.                     If arrDrives.Item(i) = UCase(Left(sScriptDir,2)) then
  1486.                         If Len(sScriptDir) > 3 then
  1487.                             sScriptDir = arrDrives.Item(i+1) & Mid(sScriptDir, 3)
  1488.                         Else
  1489.                             sScriptDir = arrDrives.Item(i+1)
  1490.                         End if
  1491.                         Exit For
  1492.                     End if
  1493.                 Next
  1494.             End if
  1495.             On Error Goto 0
  1496.  
  1497.         End if
  1498.  
  1499.  
  1500.         ' By default, set a flag to cache the local root path
  1501.  
  1502.         bCacheLocalRootPath = True
  1503.  
  1504.  
  1505.         ' Record times for heartbeat events
  1506.  
  1507.         startTime = Now
  1508.         lastHearbeat = startTime
  1509.  
  1510.     End Sub
  1511.  
  1512.  
  1513.     ' ***  Public methods ***
  1514.  
  1515.     Public Sub PrepareEnvironment
  1516.  
  1517.         Dim sArg
  1518.  
  1519.         Set oLogging = New Logging
  1520.         Set oEnvironment = New Environment
  1521.         Set oStrings = New Strings
  1522.         Set oFileHandling = New FileHandling
  1523.  
  1524.         set Arguments = GetArguments
  1525.  
  1526.  
  1527.         ' Loop through all the parameters and turn them into environment variables.  Enforce debug values.
  1528.  
  1529.         On Error Resume Next
  1530.  
  1531.         For each sArg in Arguments
  1532.             If UCase(sArg) = "DEBUG" then
  1533.                 If UCase(Arguments(sArg)) = "TRUE" or UCase(Arguments(sArg)) = "FALSE" then
  1534.                     oLogging.CreateEntry "'debug' parameter was specified.", LogTypeInfo
  1535.                 Else
  1536.                     oLogging.CreateEntry "Invalid 'debug' parameter specified: " & Arguments(sArg), LogTypeError
  1537.                     WScript.Quit Failure
  1538.                 End if
  1539.                 oEnvironment.Item(sArg) = UCase(Arguments(sArg))
  1540.             Else
  1541.                 oEnvironment.Item(sArg) = Arguments(sArg)
  1542.             End if
  1543.         Next
  1544.  
  1545.         On Error Goto 0
  1546.         Err.Clear
  1547.  
  1548.  
  1549.         ' Log the version
  1550.  
  1551.         oLogging.CreateEntry "Microsoft Deployment Toolkit version: " & Version, LogTypeInfo
  1552.  
  1553.  
  1554.         ' Log where the SMSTS.LOG can be found
  1555.  
  1556.         If oEnvironment.Item("_SMSTSLogPath") <> "" then
  1557.             oEnvironment.SetDAT "SMSTSLogPath_Cache", oEnvironment.Item("_SMSTSLogPath")
  1558.             oLogging.CreateEntry "The task sequencer log is located at " & oEnvironment.Item("_SMSTSLogPath") & "\SMSTS.LOG.  For task sequence failures, please consult this log.", LogTypeInfo
  1559.         End if
  1560.  
  1561.  
  1562.         ' Set a default for debug (if necessary)
  1563.  
  1564.         If oEnvironment.Item("Debug") = "" then
  1565.             oEnvironment.Item("Debug") = "FALSE"
  1566.         End if
  1567.  
  1568.  
  1569.         If UCase(oEnvironment.Item("Debug")) = "TRUE" then
  1570.             oLogging.Debug = True
  1571.         Else
  1572.             oLogging.Debug = False
  1573.         End if
  1574.        
  1575.         If oEnvironment.Item("SLShareDynamicLogging") <> "" then
  1576.        
  1577.             If oEnvironment.Item("UserID") <> "" and oEnvironment.Item("UserDomain") <> "" and oEnvironment.Item("UserPassword") <> "" then
  1578.  
  1579.                 If oFSO.FolderExists( LogPath ) then
  1580.  
  1581.                     oLogging.CreateEntry "Write all logging text to " & oEnvironment.Item("SLShareDynamicLogging") , LogTypeInfo
  1582.                     ValidateConnection oEnvironment.Item("SLShareDynamicLogging")
  1583.                     oUtility.VerifyPathExists oEnvironment.Item("SLShareDynamicLogging")
  1584.                    
  1585.                     If not oFSO.FolderExists(oEnvironment.Item("SLShareDynamicLogging")) then
  1586.                         oLogging.CreateEntry "An invalid SLShareDynamicLogging value of " & oEnvironment.Item("SLShareDynamicLogging") & " was specified.", LogTypeWarning
  1587.                     Else
  1588.                         oLogging.NetworkLogging = oEnvironment.Item("SLShareDynamicLogging")
  1589.                     End if
  1590.                    
  1591.                 End if
  1592.        
  1593.             End if
  1594.            
  1595.         End if
  1596.        
  1597.  
  1598.     End Sub
  1599.  
  1600.     ' This function converts the string representation of a version "xx.xx.xx.xx" to int
  1601.     ' The function captures the version major/minor and build major/minor into Utility class variables.
  1602.     ' It can be accessed via properties Utility.VersionMajor and Utility.VersionMinor
  1603.     ' e.g.
  1604.     '   1. GetMajorMinorVersion("10.0.12.1234") this will capture
  1605.     '       Utility.VersionMajor  = 10 and Utility.VersionMinor = 0 (BuildMajor and BuildMinor are not yet exposed as properties but the function still captures it)
  1606.     '   2. GetMajorMinorVersion("10.110")
  1607.     '       Utility.VersionMajor  = 10 and Utility.VersionMinor = 110 (no BuildMajor and BuildMinor)
  1608.     ' in case of invalid string representation of version (e.g. GetMajorMinorVersion("Thisisfun") function will set values to Int.Max (32767)  
  1609.     Public Function GetMajorMinorVersion(sVersion)
  1610.         Dim length
  1611.         Dim splitArray
  1612.         splitArray = Split(sVersion,".")
  1613.         length = UBound(splitArray)
  1614.         If length >=0 then
  1615.             Select case length
  1616.             Case 1
  1617.                 iVersionMinor = CInt(splitArray(1))
  1618.            
  1619.             Case 2
  1620.                 iVersionMinor = CInt(splitArray(1))
  1621.                 iBuildNumber = CInt(splitArray(2))
  1622.             Case 3
  1623.                 iVersionMinor = CInt(splitArray(1))
  1624.                 iBuildNumber = CInt(splitArray(2))
  1625.                 iRevision = CInt(splitArray(3))
  1626.             Case Else  
  1627.                 iVersionMinor = 32767
  1628.                 iBuildNumber = 32767
  1629.                 iRevision = 32767  
  1630.             End select
  1631.             iVersionMajor = CInt(splitArray(0))            
  1632.         Else
  1633.             iVersionMajor = 32767  'Int.Max for VbScript is 32767
  1634.             iVersionMinor = 32767
  1635.             iBuildNumber = 32767
  1636.             iRevision = 32767
  1637.         End if
  1638.     End Function
  1639.  
  1640.         ' This function retrieves MSXML DOM document using MSXML2.DomDocument.6.0
  1641.        ' If it cannot load tries to get from MSXML2.DOMDocument.3.0
  1642.     Public Function GetMSXMLDOMDocument
  1643.                 On Error Resume Next
  1644.                 Set GetMSXMLDOMDocument = CreateObject("MSXML2.DOMDocument.6.0")
  1645.                 If Err Then
  1646.                         Set GetMSXMLDOMDocument = CreateObject("MSXML2.DOMDocument")
  1647.                 End If
  1648.                 On Error Goto 0
  1649.         End Function
  1650.  
  1651.     Private Function GetArguments
  1652.    
  1653.         Dim RegExObj
  1654.         Dim Match
  1655.  
  1656.         set RegExObj = New RegExp
  1657.         RegExObj.Global = TRUE
  1658.         RegExObj.Multiline = TRUE
  1659.         RegExObj.IgnoreCase = TRUE
  1660.         RegExObj.Pattern = "\/([^\ ""\:\=]+)(?:(?:[\:\=]""([^""]+)"")|(?:[\:\=]([^\ ""]+)))?"
  1661.        
  1662.         if isWSH then
  1663.             set GetArguments = wscript.arguments.Named
  1664.  
  1665.         elseif isMSHTA and (not oMSHTA is nothing) then
  1666.  
  1667.             Set GetArguments = CreateObject("Scripting.Dictionary")
  1668.             GetArguments.CompareMode = vbTextCompare
  1669.            
  1670.             for each Match in RegExObj.Execute(oMSHTA.CommandLine)
  1671.                 If not isempty(Match.submatches(0)) then
  1672.                     if not GetArguments.Exists(Match.submatches(0)) then
  1673.                         GetArguments.Add Match.submatches(0), Match.submatches(1) & Match.submatches(2)
  1674.                     End if
  1675.                 End if
  1676.             next
  1677.  
  1678.         elseif IsHTML then
  1679.             Set GetArguments = CreateObject("Scripting.Dictionary")
  1680.             GetArguments.CompareMode = vbTextCompare
  1681.            
  1682.             for each Match in oStrings.ForceAsArray( window.location.search,"&")
  1683.                 If Instr(1,Match,"=",vbTextCompare) <> 0 then
  1684.                     If not GetArguments.Exists(left(Match,Instr(1,Match,"=",vbTextCompare)-1)) then
  1685.                         GetArguments.Add left(Match,Instr(1,Match,"=",vbTextCompare)-1), mid(Match,Instr(1,Match,"=",vbTextCompare)+1)
  1686.                     End if             
  1687.                 End if
  1688.             next
  1689.            
  1690.         else
  1691.             Set GetArguments = CreateObject("Scripting.Dictionary")
  1692.             GetArguments.CompareMode = vbTextCompare
  1693.  
  1694.         end if
  1695.     End function
  1696.  
  1697.  
  1698.     Function GetPA
  1699.         GetPA = Replace(oShell.Environment("PROCESS")("Processor_Architecture"),"amd64","x64",1,-1,vbTextCompare)
  1700.     end function
  1701.  
  1702.  
  1703.     Public Function RunNewInstanceEx ( sClassName, sClassInstance, sMain )
  1704.         Dim oScriptClass
  1705.         Dim iScriptRc
  1706.        
  1707.         ' Disable On Error Resume next for advanced debugging
  1708.        
  1709.         If not oUtility.Arguments.Exists("DebugCapture") then
  1710.             On Error Resume next
  1711.         End if
  1712.        
  1713.  
  1714.         execute "Set " & sClassInstance & " = New " & sClassName
  1715.         TestAndFail SUCCESS, 5400, "Create object: Set " & sClassInstance & " = New " & sClassName
  1716.  
  1717.         If oUtility.Arguments.Exists("TestHook") then
  1718.  
  1719.             ' Hook for Unit Test code. Allows us to run Unit Tests without modification of the Original script.
  1720.  
  1721.             oLogging.CreateEntry "Run Test Script [" & oUtility.Arguments.Item("TestHook") & "]...", LogTypeInfo
  1722.             Execute oFSO.OpenTextFile(oUtility.Arguments.Item("TestHook")).ReadAll
  1723.             oLogging.CreateEntry "Finished with Test Script! iScriptRc = " & iScriptRc, LogTypeInfo
  1724.  
  1725.         End if
  1726.  
  1727.         ' Standard execution, call the main function in the created class.
  1728.  
  1729.         iScriptRc =  eval(sMain)
  1730.         ProcessResults iScriptRc
  1731.  
  1732.  
  1733.         Wscript.quit iScriptRc
  1734.  
  1735.     end function
  1736.    
  1737.     Function ConvertBooleanToString(bValue)
  1738.  
  1739.         Dim iRetVal
  1740.  
  1741.         iRetVal = Failure
  1742.            
  1743.         If bValue = -1 Then
  1744.             iRetVal = "True"
  1745.         ElseIf bValue = 0 Then
  1746.             iRetVal = "False"
  1747.         End If
  1748.  
  1749.         ConvertBooleanToString = iRetVal
  1750.  
  1751.     End Function
  1752.  
  1753.  
  1754.     Sub ResetLocalRootPath
  1755.         sLocalRootPath = empty
  1756.     End sub
  1757.  
  1758.     Property Get CacheLocalRootPath
  1759.         CacheLocalRootPath = bCacheLocalRootPath
  1760.     End Property
  1761.    
  1762.     Property Let CacheLocalRootPath(bNew)
  1763.         bCacheLocalRootPath = bNew
  1764.     End Property
  1765.  
  1766.     Public Property Get VersionMajor
  1767.         VersionMajor = iVersionMajor
  1768.     End Property
  1769.    
  1770.     Public Property Get VersionMinor
  1771.         VersionMinor = iVersionMinor
  1772.     End Property
  1773.    
  1774.     Public Property Get BuildNumber
  1775.         BuildNumber = iBuildNumber
  1776.     End Property
  1777.    
  1778.     Public Property Get RevisionNumber
  1779.         RevisionNumber = iRevision
  1780.     End Property
  1781.    
  1782.     Property Get LocalRootPath
  1783.  
  1784.         Dim sFallBack
  1785.  
  1786.         If bCacheLocalRootPath and (not IsEmpty(sLocalRootPath)) then
  1787.            
  1788.             LocalRootPath = sLocalRootPath ' Cache the value. Enumeration of Drives can be time expensive.
  1789.             Exit property
  1790.  
  1791.         End if
  1792.  
  1793.         If oEnvironment.GetOSDV4("_SMSTSBootImageID") <> "" then
  1794.             LocalRootPath = oEnvironment.GetOSDV4("_SMSTSMDataPath")
  1795.         Else
  1796.             LocalRootPath = ""
  1797.  
  1798.             If oEnv("SystemDrive") = "X:" then
  1799.                 ' We're in PE
  1800.                 sFallBack = "X:\MININT"
  1801.             Else
  1802.                 ' We're in a full OS
  1803.                 sFallBack = "C:\MININT"
  1804.             End if
  1805.         End if
  1806.  
  1807.         ' --------------------------------------------
  1808.         If LocalRootPath = "" or IsEmpty(LocalRootPath) then
  1809.             For each oDrive in oFSO.Drives
  1810.                 If oDrive.DriveType = 2 and oDrive.DriveLetter<>"X" then
  1811.                     If oDrive.IsReady Then
  1812.  
  1813.                         If OFSO.FolderExists(oDrive.DriveLetter & ":\MININT\SMSOSD\OSDLOGS") then
  1814.                             LocalRootPath = oDrive.DriveLetter & ":\MININT"
  1815.                             Exit For
  1816.                         End if
  1817.                    
  1818.                         If oFSO.FolderExists(oDrive.DriveLetter & ":\_SMSTaskSequence") then
  1819.                             sFallBack = oDrive.DriveLetter & ":\MININT"
  1820.                         End if
  1821.                     End If
  1822.  
  1823.                 End if
  1824.             Next
  1825.             If LocalRootPath = "" or IsEmpty(LocalRootPath) then
  1826.                 LocalRootPath = sFallBack
  1827.             End if
  1828.  
  1829.         End if
  1830.  
  1831.  
  1832.         ' Make sure the root path exists
  1833.  
  1834.         oUtility.VerifyPathExists LocalRootPath
  1835.  
  1836.  
  1837.         ' Cache the value
  1838.  
  1839.         sLocalRootPath = LocalRootPath
  1840.  
  1841.     End Property
  1842.  
  1843.     Property Get BootDevice
  1844.    
  1845.         BootDevice = UCase(oShell.Regread("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SystemBootDevice"))
  1846.  
  1847.     End Property
  1848.  
  1849.  
  1850.     Property Get LogPath
  1851.  
  1852.         If oEnvironment.GetOSDV4("_SMSTSBootImageID") <> "" then
  1853.             LogPath = oEnvironment.GetOSDV4("_SMSTSLogPath")
  1854.         Else
  1855.             LogPath = LocalRootPath & "\SMSOSD\OSDLOGS"
  1856.         End if
  1857.         oUtility.VerifyPathExistsEx LogPath, False
  1858.  
  1859.     End Property
  1860.  
  1861.  
  1862.     Property Get StatePath
  1863.  
  1864.         Dim sBasePath
  1865.  
  1866.         ' Always use the root of the drive.
  1867.  
  1868.         sBasePath = "\"
  1869.  
  1870.  
  1871.         ' We want to store user state on the same volume as the OS.
  1872.  
  1873.         If oEnv("SystemDrive") <> "X:" then
  1874.             StatePath = oEnv("SystemDrive") & sBasePath & "StateStore"
  1875.         Else
  1876.             ' We're offline, so try to use OSDWinPEWinDir, which should be set before reaching here
  1877.  
  1878.             If oFSO.FolderExists(oEnvironment.Item("OSDWinPEWinDir")) then
  1879.  
  1880.                 ' Use the drive that OSDWinPEWinDir points to
  1881.  
  1882.                 StatePath = Left(oEnvironment.Item("OSDWinPEWinDir"), 2) & sBasePath & "StateStore"
  1883.  
  1884.             Else
  1885.                 ' Fallback logic - put the folder on the local root path
  1886.  
  1887.                 StatePath = Left(LocalRootPath, 2) & sBasePath & "StateStore"
  1888.  
  1889.             End if
  1890.         End if
  1891.  
  1892.     End Property
  1893.  
  1894.  
  1895.     Property Get ScriptName
  1896.  
  1897.         On Error Resume Next
  1898.         ScriptName = oFSO.GetBaseName(Wscript.ScriptName)
  1899.         If Err then
  1900.             ScriptName = oFSO.GetBaseName(Unescape(window.location.pathname))
  1901.         End if
  1902.         On Error Goto 0
  1903.  
  1904.     End Property
  1905.  
  1906.  
  1907.     Property Get ScriptDir
  1908.  
  1909.         ScriptDir = sScriptDir
  1910.  
  1911.     End Property
  1912.  
  1913.  
  1914.     Public Function ReadIni(file, section, item)
  1915.  
  1916.         Dim line, equalpos, leftstring, ini
  1917.  
  1918.         ReadIni = ""
  1919.         file = Trim(file)
  1920.         item = Trim(item)
  1921.  
  1922.         On Error Resume Next
  1923.         Set ini = oFSO.OpenTextFile( file, 1, False)
  1924.         If Err then
  1925.             Err.Clear
  1926.             Exit Function
  1927.         End if
  1928.         On Error Goto 0
  1929.  
  1930.         Do While (not ini.AtEndOfStream)
  1931.             line = ini.ReadLine
  1932.             line = oStrings.TrimAllWS(line)
  1933.             If LCase(line) = "[" & LCase(section) & "]" and (not ini.AtEndOfStream) Then
  1934.                 line = ini.ReadLine
  1935.                 line = oStrings.TrimAllWS(line)
  1936.                 Do While Left( line, 1) <> "["
  1937.                     'If InStr( 1, line, item & "=", 1) = 1 Then
  1938.                     equalpos = InStr(1, line, "=", 1 )
  1939.                     If equalpos > 0 Then
  1940.                         leftstring = Left(line, equalpos - 1 )
  1941.                         leftstring = oStrings.TrimAllWS(leftstring)
  1942.                         If LCase(leftstring) = LCase(item) Then
  1943.                             ReadIni = Mid( line, equalpos + 1 )
  1944.                             ReadIni = oStrings.TrimAllWS(ReadIni)
  1945.                             Exit Do
  1946.                         End If
  1947.                     End If
  1948.  
  1949.                     If ini.AtEndOfStream Then Exit Do
  1950.                     line = ini.ReadLine
  1951.                     line = oStrings.TrimAllWS(line)
  1952.                 Loop
  1953.                 Exit Do
  1954.             End If
  1955.         Loop
  1956.         ini.Close
  1957.  
  1958.     End Function
  1959.  
  1960.     Public Sub WriteIni( file, section, item, myvalue )
  1961.  
  1962.         Dim in_section, section_exists, item_exists, wrote, itemtrimmed
  1963.         Dim read_ini, write_ini, temp_ini, linetrimmed, line, equalpos
  1964.         Dim leftstring
  1965.  
  1966.         in_section = False
  1967.         section_exists = False
  1968.         item_exists = ( ReadIni( file, section, item ) <> "" )
  1969.         wrote = False
  1970.         file = Trim(file)
  1971.         itemtrimmed = Trim(item)
  1972.         myvalue = Trim(myvalue)
  1973.  
  1974.         temp_ini = oFSO.GetParentFolderName(file) & "\" & oFSO.GetTempName
  1975.  
  1976.         Set read_ini = oFSO.OpenTextFile( file, 1, True, False )
  1977.         Set write_ini = oFSO.CreateTextFile( temp_ini, False)
  1978.  
  1979.         While read_ini.AtEndOfStream = False
  1980.             line = read_ini.ReadLine
  1981.             linetrimmed = Trim(line)
  1982.             If wrote = False Then
  1983.                 If LCase(line) = "[" & LCase(section) & "]" Then
  1984.                     section_exists = True
  1985.                     in_section = True
  1986.                 ElseIf InStr( line, "[" ) = 1 Then
  1987.                     in_section = False
  1988.                 End If
  1989.             End If
  1990.  
  1991.             If in_section Then
  1992.                 If itemtrimmed = "" then
  1993.                     ' Do nothing: we want to wipe the section
  1994.                 ElseIf item_exists = False Then
  1995.                     write_ini.WriteLine line
  1996.                     If myvalue <> "" then
  1997.                         write_ini.WriteLine item & "=" & myvalue
  1998.                     End if
  1999.                     wrote = True
  2000.                     in_section = False
  2001.                 Else
  2002.                     equalpos = InStr(1, line, "=", 1 )
  2003.                     If equalpos > 0 Then
  2004.                         leftstring = Left(line, equalpos - 1 )
  2005.                         leftstring = Trim(leftstring)
  2006.                         If LCase(leftstring) = LCase(item) Then
  2007.                             If myvalue <> "" then
  2008.                                 write_ini.WriteLine itemtrimmed & "=" & myvalue
  2009.                             End if
  2010.                             wrote = True
  2011.                             in_section = False
  2012.                         End If
  2013.                     End If
  2014.                     If Not wrote Then
  2015.                         write_ini.WriteLine line
  2016.                     End If
  2017.                 End If
  2018.             Else
  2019.                 write_ini.WriteLine line
  2020.             End If
  2021.         Wend
  2022.  
  2023.         If section_exists = False and itemtrimmed <> "" Then ' section doesn't exist
  2024.             write_ini.WriteLine
  2025.             write_ini.WriteLine "[" & section & "]"
  2026.             If myvalue <> "" then
  2027.                 write_ini.WriteLine itemtrimmed & "=" & myvalue
  2028.             End if
  2029.         End If
  2030.  
  2031.         read_ini.Close
  2032.         write_ini.Close
  2033.         If oFSO.FileExists(file) then
  2034.             oFSO.DeleteFile file, True
  2035.         End if
  2036.         oFSO.CopyFile temp_ini, file, true
  2037.         oFSO.DeleteFile temp_ini, True
  2038.  
  2039.     End Sub
  2040.  
  2041.     Public Function Sections(file)
  2042.         Dim oContents
  2043.         Dim line, equalpos, leftstring, ini
  2044.  
  2045.         Set oContents = CreateObject("Scripting.Dictionary")
  2046.         file = Trim(file)
  2047.  
  2048.         On Error Resume Next
  2049.         Set ini = oFSO.OpenTextFile( file, 1, False)
  2050.         If Err then
  2051.             Err.Clear
  2052.             Exit Function
  2053.         End if
  2054.         On Error Goto 0
  2055.  
  2056.         Do While ini.AtEndOfStream = False
  2057.             line = ini.ReadLine
  2058.             line = Trim(line)
  2059.             If Left(line,1) = "[" then
  2060.                 equalpos = Instr(line, "]")
  2061.                 leftstring = Mid(line, 2, equalpos - 2)
  2062.                 oContents.Add leftstring, ""
  2063.             End if
  2064.         Loop
  2065.  
  2066.         Set Sections = oContents
  2067.  
  2068.     End Function
  2069.  
  2070.     Public Function SectionContents(file, section)
  2071.         Dim oContents
  2072.         Dim line, equalpos, leftstring, ini
  2073.  
  2074.         Set oContents = CreateObject("Scripting.Dictionary")
  2075.         file = Trim(file)
  2076.         section = Trim(section)
  2077.  
  2078.         On Error Resume Next
  2079.         Set ini = oFSO.OpenTextFile( file, 1, False)
  2080.         If Err then
  2081.             Err.Clear
  2082.             Exit Function
  2083.         End if
  2084.         On Error Goto 0
  2085.  
  2086.         Do While ini.AtEndOfStream = False
  2087.             line = ini.ReadLine
  2088.             line = Trim(line)
  2089.             If LCase(line) = "[" & LCase(section) & "]" Then
  2090.                 line = ini.ReadLine
  2091.                 line = Trim(line)
  2092.                 Do While Left( line, 1) <> "["
  2093.                     'If InStr( 1, line, item & "=", 1) = 1 Then
  2094.                     equalpos = InStr(1, line, "=", 1 )
  2095.                     If equalpos > 0 Then
  2096.                         leftstring = Left(line, equalpos - 1 )
  2097.                         leftstring = Trim(leftstring)
  2098.                         oContents(leftstring) = Trim(Mid(line, equalpos + 1 ))
  2099.                     End If
  2100.  
  2101.                     If ini.AtEndOfStream Then Exit Do
  2102.                     line = ini.ReadLine
  2103.                     line = Trim(line)
  2104.                 Loop
  2105.                 Exit Do
  2106.             End If
  2107.         Loop
  2108.         ini.Close
  2109.         Set SectionContents = oContents
  2110.  
  2111.     End Function
  2112.  
  2113.  
  2114.     Function RegReadEx ( sRegValue, bError )
  2115.  
  2116.         on error resume next
  2117.         RegReadEx = oShell.Regread( sRegValue )
  2118.         If bError then
  2119.             TestAndLog not isempty(RegReadEx),  "ReadRead(" & sRegValue & ")"
  2120.         End if
  2121.         on error goto 0
  2122.  
  2123.     End function
  2124.  
  2125.     Function RegWriteEx ( sKey, sValue, bError )
  2126.  
  2127.         on error resume next
  2128.         if VarType(sValue) = vbString then
  2129.             RegWriteEx = oShell.RegWrite ( sKey, sValue, "REG_SZ"  )
  2130.         elseif VarType(sValue) = vbInteger or VarType(sValue) = vbLong or VarType(sValue) = vbBoolean then
  2131.             RegWriteEx = oShell.RegWrite ( sKey, sValue, "REG_DWORD" )
  2132.         end if
  2133.  
  2134.         If bError then
  2135.             TestAndLog (err = 0), "RegWriteEx( " & sKey & " , " & sValue & " , REG_Type )"
  2136.         End if
  2137.         on error goto 0
  2138.  
  2139.     End function
  2140.  
  2141.  
  2142.     Function RegRead( sRegValue )
  2143.         RegRead = RegReadEx(sRegValue, True)
  2144.     end Function
  2145.  
  2146.     Function RegWrite ( sKey, sValue )
  2147.         RegWrite = RegWriteEx(sKey, sValue, True)
  2148.     end Function
  2149.    
  2150.     Function SafeSleep ( iTime )
  2151.         On error resume next
  2152.         WScript.Sleep iTime
  2153.         On error goto 0
  2154.     End function
  2155.  
  2156.     ' ---------------------------------------------------------------
  2157.  
  2158.     Function RunCommandLog( oExec, fExternalHook, iLimit )
  2159.  
  2160.         Dim HeartbeatStart
  2161.         Dim iMinutes
  2162.         Dim iHeartBeat
  2163.         Dim iLastProgress
  2164.         Dim iResult
  2165.  
  2166.         ' Initialize the last heartbeat time (start the timer) and interval
  2167.  
  2168.         HeartbeatStart = Now
  2169.         iLastProgress = 0
  2170.         iResult = SUCCESS
  2171.  
  2172.         ' Main Processing Loop
  2173.         do while oExec.Status = 0
  2174.  
  2175.             ' See if it is time for a heartbeat
  2176.             iMinutes = DateDiff("n", HeartbeatStart, now )
  2177.             If iMinutes >= iLimit and iLimit <> -1 and VarType(iLimit) = 2 then
  2178.                 oLogging.CreateEvent 41009, LogTypeError, "Command has been running for " & CStr(iMinutes) & " minutes (process ID " & oExec.ProcessID & "). Now over limit!", Array(iMinutes)
  2179.                 RunCommandLog = False
  2180.                 exit function
  2181.             End if
  2182.             Heartbeat "ZTI Heartbeat: command has been running for " & CStr(iMinutes) & " minutes (process ID " & oExec.ProcessID & ")"
  2183.  
  2184.             If IsNull(fExternalHook) then
  2185.                 SafeSleep 100
  2186.             Else
  2187.                 SafeSleep 1
  2188.                 If VarType(fExternalHook) = 9 then
  2189.                     iResult = fExternalHook(oExec, iLastProgress)  ' fExternal Hook is a GetRef( function )
  2190.                 ElseIf VarType(fExternalHook) = 8 then
  2191.                     iResult = execute( fExternalHook )  ' fExternalHook is a string function
  2192.                 Else
  2193.                     iResult = StandardConsoleProcessing(oExec, iLastProgress) ' Do standard processing
  2194.                 End if
  2195.  
  2196.                 If iResult <> SUCCESS then
  2197.                     Exit do
  2198.                 End if
  2199.             End if
  2200.  
  2201.         loop
  2202.  
  2203.  
  2204.         If IsNull(fExternalHook)  or iResult <> SUCCESS then
  2205.             SafeSleep 100
  2206.         Else
  2207.             ' Jump to the end of the sub-progress if started
  2208.             If not IsEmpty(iLastProgress) and iLastProgress > 9 and iLastProgress < 91 then
  2209.                 oLogging.ReportProgress "process ID " & oExec.ProcessID & " Finished ", 100
  2210.             End if
  2211.  
  2212.             If VarType(fExternalHook) = 9 then
  2213.                 iResult = fExternalHook(oExec, iLastProgress)  ' fExternal Hook is a GetRef( function )
  2214.             ElseIf VarType(fExternalHook) = 8 then
  2215.                 iResult = execute( fExternalHook )  ' fExternalHook is a string function
  2216.             Else
  2217.                 iResult = StandardConsoleProcessing(oExec, iLastProgress) ' Do standard processing
  2218.             End if
  2219.  
  2220.         End if
  2221.  
  2222.         ' Return the exit code to the caller
  2223.         oLogging.CreateEntry "Return code from command = " & oExec.ExitCode, LogTypeInfo
  2224.         RunCommandLog = oExec.ExitCode
  2225.  
  2226.     End function
  2227.  
  2228.  
  2229.     Function Heartbeat(sMessage)
  2230.         Dim iMinutes
  2231.  
  2232.         If DateDiff("n", lastHeartbeat, Now ) >= 5 then
  2233.             lastHeartbeat = Now
  2234.             iMinutes = DateDiff("n", startTime, lastHeartbeat)
  2235.             oLogging.CreateEvent 41003, LogTypeInfo, sMessage, Array(iMinutes)
  2236.         End if
  2237.     End function
  2238.  
  2239.  
  2240.     Function  StandardConsoleProcessing ( oExec, byRef iLastProgress )
  2241.         Dim sLines
  2242.         Dim sLine
  2243.         Dim oMatch
  2244.  
  2245.         StandardConsoleProcessing = SUCCESS
  2246.  
  2247.         Do Until oExec.StdOut.atEndOfStream
  2248.  
  2249.             sLines = oExec.StdOut.ReadLine
  2250.             if vartype(sLines) = 8 then
  2251.                 For each sLine in split(sLines,vbNewLine)
  2252.                     If asc(mid(sline,1,1)) = 0 then
  2253.                         sLine = replace(sLine,chr(0),"") ' Quick and dirty Unicode to ANSI fix.
  2254.                     End if
  2255.                     oLogging.CreateEntry "  Console > " & sLine, LogTypeInfo
  2256.  
  2257.                     if oExec.Status = 0 then
  2258.                         ' If the output contains a percentage, then interpret it a status.
  2259.                        
  2260.                         ' Check for DISM-style progress
  2261.                         Set oMatch = oRegEx.GetRegExMatches("([01]?[0-9]?[0-9])\.[0-9]\%",sLine)
  2262.                         If oMatch.Count > 0 then
  2263.                             iLastProgress = cint(oMatch(oMatch.Count -1).SubMatches(0))
  2264.                             oLogging.ReportProgress sLine, iLastProgress
  2265.                         Else
  2266.                             ' Check for "other" percentage
  2267.                             set oMatch = oRegEx.GetRegExMatches("([01]?[0-9]?[0-9]) ?\%",sLine)
  2268.                             If oMatch.Count > 0 then
  2269.                                 iLastProgress = cint(oMatch(oMatch.Count -1).SubMatches(0))
  2270.                                 oLogging.ReportProgress sLine, iLastProgress
  2271.                             End if
  2272.                         End if
  2273.                     End if
  2274.                 Next
  2275.             End if
  2276.             if oExec.Status = 0 then
  2277.                 Exit Function
  2278.             End if
  2279.  
  2280.         Loop
  2281.  
  2282.         if oExec.Status <> 0 then
  2283.             StandardConsoleProcessing = FAILURE
  2284.         Else
  2285.  
  2286.             do until oExec.StdErr.atEndOfStream
  2287.                 sLines = oExec.StdErr.ReadAll
  2288.                 if vartype(sLine) = 8 then
  2289.                     For each sLine in split(sLines,vbNewLine)
  2290.                         If asc(mid(sline,1,1)) = 0 then
  2291.                             sLine = replace(sLine,chr(0),"") ' Quick and dirty Unicode to ANSI fix.
  2292.                         End if
  2293.                         oLogging.CreateEntry "  Console # " & sLine, LogTypeError
  2294.                     Next
  2295.                 End if
  2296.             loop
  2297.  
  2298.         End if
  2299.  
  2300.     End Function
  2301.  
  2302.     Function StandardFileProcessing ( oExec, ByRef iLastProgress, sExternalLogFile )
  2303.         Dim oMatch
  2304.  
  2305.         If oExec.Status = 0 then
  2306.             If oFSO.FileExists(sExternalLogFile) then
  2307.                 set oMatch = oRegEx.GetRegExMatchesFromFile(sProgress,sExternalLogFile)
  2308.                 If oMatch.Count > 0 then
  2309.                     If cint(oMatch(oMatch.Count - 1).SubMatches(0)) > iLastProgress then
  2310.                         iLastProgress = cint(oMatch(oMatch.Count - 1).SubMatches(0))
  2311.                         oLogging.ReportProgress "Progress [" & sExternalLogFile & "] ...  " & iLastProgress & "%", iLastProgress
  2312.                         exit function
  2313.                     End if
  2314.                 End if
  2315.             End if
  2316.         End if
  2317.         oUtility.SafeSleep 100
  2318.  
  2319.     End function
  2320.  
  2321.  
  2322.     Function RunCommandStart(sCmd, aInput)
  2323.  
  2324.         Dim oExec
  2325.         Dim sLine
  2326.  
  2327.         ' Start the command
  2328.  
  2329.         oLogging.CreateEntry "About to run command: " & sCmd, LogTypeInfo
  2330.         Set oExec = oShell.Exec(sCmd)
  2331.  
  2332.         oLogging.CreateEntry "Command has been started (process ID " & oExec.ProcessID & ")", LogTypeInfo
  2333.  
  2334.         ' Log any input lines
  2335.  
  2336.         If isArray( aInput )  then
  2337.             For each sLine in aInput
  2338.                 RunCommandWrite oExec, sLine
  2339.             next
  2340.         End if
  2341.  
  2342.         set RunCommandStart = oExec
  2343.  
  2344.     End function
  2345.  
  2346.  
  2347.     Function RunCommandWrite( oExec, sCommand )
  2348.  
  2349.         If sCommand <> "" then
  2350.             oLogging.CreateEntry  "  Console + " & sCommand, LogTypeInfo
  2351.             oExec.stdIn.WriteLine sCommand
  2352.         End if
  2353.  
  2354.     End function
  2355.  
  2356.  
  2357.     Function RunCommandEx(sCmd, aInput, fExternalHook, iLimit )
  2358.  
  2359.         Dim oExec
  2360.  
  2361.         ' Start the command
  2362.         set oExec = RunCommandStart(sCmd, aInput)
  2363.         SafeSleep 500
  2364.  
  2365.         ' Wait for the results
  2366.         RunCommandEx = RunCommandLog (oExec, fExternalHook, iLimit )
  2367.  
  2368.     End function
  2369.  
  2370.     Function RunWithHeartbeat(sCmd)
  2371.             RunWithHeartbeat = RunCommandEx(sCmd, null, null, -1)
  2372.     End function
  2373.  
  2374.  
  2375.     Function RunWithConsoleLogging(sCmd)
  2376.         RunWithConsoleLogging = RunCommandEx(sCmd, empty, empty, -1)
  2377.     End function
  2378.  
  2379.     Function RunWithConsoleLoggingAndHidden(sCmd)
  2380.         Dim iRC
  2381.         Dim sScriptFile
  2382.  
  2383.         iRC = oUtility.FindFile( "ztiRunCommandHidden.wsf", sScriptFile )
  2384.         TestAndLog iRC, "Verify ztiRunCommandHidden.wsf is in the path"
  2385.         If iRC = Success then
  2386.             RunWithConsoleLoggingAndHidden = RunCommand ( "cscript.exe //nologo """ & sScriptFile & """ """ & sCmd & """", 0, True)
  2387.         Else
  2388.             oLogging.CreateEntry "Visible console fallback." , LogTypeInfo
  2389.             RunWithConsoleLoggingAndHidden = oUtility.RunWithConsoleLogging( sCmd )
  2390.         End if
  2391.     End function
  2392.  
  2393.     Function FindExeAndRunWithLogging( sCmd, sParameters )
  2394.  
  2395.         Dim iRC
  2396.         Dim sFoundFile
  2397.  
  2398.         iRC = oUtility.FindFile ( sCmd, sFoundFile )
  2399.         TestAndFail iRC, 5441, "FindFile: " & sCmd
  2400.  
  2401.         FindExeAndRunWithLogging = RunWithConsoleLogging( """" & sFoundFile & """ " & sParameters )
  2402.  
  2403.     End function
  2404.  
  2405.     Function FindExeAndRun( sCmd, sParameters )
  2406.  
  2407.         Dim iRC
  2408.         Dim sFoundFile
  2409.  
  2410.         iRC = oUtility.FindFile ( sCmd, sFoundFile )
  2411.         TestAndFail iRC, 5442, "FindFile: " & sCmd
  2412.  
  2413.         FindExeAndRun = RunWithHeartbeat( """" & sFoundFile & """ " & sParameters )
  2414.  
  2415.     End function
  2416.  
  2417.  
  2418.     Function RunCommand ( sCmd, iWindowStyle, bWaitOnReturn )
  2419.         oLogging.CreateEntry "About to run command: " & sCmd, LogTypeInfo
  2420.         RunCommand = oShell.Run ( sCmd, iWindowStyle, bWaitOnReturn )
  2421.         oLogging.CreateEntry "Command has returned: " & RunCommand, LogTypeInfo
  2422.     End Function
  2423.  
  2424.  
  2425.  
  2426.     Function ComputerName
  2427.  
  2428.         Dim re
  2429.         Dim sComputer
  2430.  
  2431.  
  2432.         Set re = New RegExp
  2433.  
  2434.  
  2435.         ' Figure out the computer name to include
  2436.  
  2437.         If oEnvironment.Item("_SMSTSMachineName") <> "" then
  2438.             If oEnvironment.Item("OSDCOMPUTERNAME") <> "" and Instr(oEnvironment.Item("OSDCOMPUTERNAME"),":") = 0 then
  2439.                 sComputer = oEnvironment.Item("OSDComputerName")
  2440.             Else
  2441.                 sComputer = oEnvironment.Item("_SMSTSMachineName")
  2442.             End If
  2443.         ElseIf oEnvironment.Item("OSDCOMPUTERNAME") <> "" and Instr(oEnvironment.Item("OSDCOMPUTERNAME"),":") = 0 then
  2444.             sComputer = oEnvironment.Item("OSDCOMPUTERNAME")
  2445.         ElseIf oEnvironment.Item("OSDNEWMACHINENAME") <> "" then
  2446.             oEnvironment.Item("OSDComputerName") = oEnvironment.Item("OSDNEWMACHINENAME")
  2447.             sComputer = oEnvironment.Item("OSDCOMPUTERNAME")
  2448.         ElseIf oEnvironment.Item("ComputerName") <> "" then
  2449.             oEnvironment.Item("OSDComputerName") = oEnvironment.Item("ComputerName")
  2450.             sComputer = oEnvironment.Item("OSDComputerName")
  2451.         ElseIf oEnvironment.Item("OSVersion") = "WinPE" and oEnvironment.Item("OSDCOMPUTERNAME") <> "" then
  2452.             sComputer = oEnvironment.Item("OSDCOMPUTERNAME")
  2453.             re.Pattern = ":"
  2454.             sComputer = re.Replace(sComputer, "")
  2455.         Else
  2456.             sComputer = oEnvironment.Item("HostName")
  2457.         End if
  2458.  
  2459.         ComputerName = oEnvironment.Substitute(sComputer)
  2460.  
  2461.     End Function
  2462.    
  2463.    
  2464.     Function FindFile(sFilename, sFoundPath)
  2465.  
  2466.         Dim iRetVal
  2467.         Dim sDir
  2468.  
  2469.  
  2470.         iRetVal = Failure
  2471.         sFoundPath = ""
  2472.  
  2473.  
  2474.         ' Look through the standard locations
  2475.  
  2476.         If oEnvironment.Item("DeployRoot") <> "" then
  2477.  
  2478.             For each sDir in Array("\", "\Tools\", "\Servicing\", "\Scripts\", "\Control\", "\Templates\", "\x86\", "\amd64\")
  2479.  
  2480.                 If oFSO.FileExists(oEnvironment.Item("DeployRoot") & sDir & sFileName) then
  2481.                     sFoundPath = oEnvironment.Item("DeployRoot") & sDir & sFileName
  2482.                     iRetVal = Success
  2483.                     Exit For
  2484.                 ElseIf oEnvironment.Item("Architecture") <> "" and oFSO.FileExists(oEnvironment.Item("DeployRoot") & sDir & oEnvironment.Item("Architecture") & "\" & sFileName) then
  2485.                     sFoundPath = oEnvironment.Item("DeployRoot") & sDir & oEnvironment.Item("Architecture") & "\" & sFileName
  2486.                     iRetVal = Success
  2487.                     Exit For
  2488.  
  2489.                 ' oEnvironment.Item("Architecture") *can* be blank, search in the %Processor_Architecture% directory.
  2490.                 ElseIf ucase(oEnv("Processor_Architecture")) = "AMD64" and oFSO.FileExists(oEnvironment.Item("DeployRoot") & sDir & "x64\" & sFileName) then
  2491.                     sFoundPath = oEnvironment.Item("DeployRoot") & sDir & "x64\" & sFileName
  2492.                     iRetVal = Success
  2493.                     Exit For
  2494.                 ElseIf oFSO.FileExists(oEnvironment.Item("DeployRoot") & sDir & oEnv("Processor_Architecture") & "\" & sFileName) then
  2495.                     sFoundPath = oEnvironment.Item("DeployRoot") & sDir & oEnv("Processor_Architecture") & "\" & sFileName
  2496.                     iRetVal = Success
  2497.                     Exit For
  2498.                 End if
  2499.  
  2500.             Next
  2501.  
  2502.         End if
  2503.         If sFoundPath <> "" then
  2504.             FindFile = iRetVal
  2505.             Exit Function
  2506.         End if
  2507.  
  2508.  
  2509.         ' Check resource root locations (normally OSD only)
  2510.  
  2511.         If oEnvironment.Item("ResourceRoot") <> "" and oEnvironment.Item("ResourceRoot") <> oEnvironment.Item("DeployRoot") then
  2512.  
  2513.             For each sDir in Array("\", "\Tools\", "\Servicing\", "\Scripts\", "\Templates\", "\Control\")
  2514.  
  2515.                 If oFSO.FileExists(oEnvironment.Item("ResourceRoot") & sDir & sFileName) then
  2516.                     sFoundPath = oEnvironment.Item("ResourceRoot") & sDir & sFileName
  2517.                     iRetVal = Success
  2518.                     Exit For
  2519.                 ElseIf oFSO.FileExists(oEnvironment.Item("ResourceRoot") & sDir & oEnvironment.Item("Architecture") & "\" & sFileName) then
  2520.                     sFoundPath = oEnvironment.Item("ResourceRoot") & sDir & oEnvironment.Item("Architecture") & "\" & sFileName
  2521.                     iRetVal = Success
  2522.                     Exit For
  2523.                 End if
  2524.  
  2525.             Next
  2526.  
  2527.         End if
  2528.         If sFoundPath <> "" then
  2529.             FindFile = iRetVal
  2530.             Exit Function
  2531.         End if
  2532.  
  2533.  
  2534.         ' Now look in the log directory, this directory, working directory, and SYSTEM32 directory
  2535.  
  2536.         If oFSO.FileExists(oUtility.LogPath & "\" & sFilename) then
  2537.             sFoundPath = oUtility.LogPath & "\" & sFilename
  2538.             iRetVal = Success
  2539.         ElseIf oFSO.FileExists(oUtility.ScriptDir & "\" & sFilename) then
  2540.             sFoundPath = oUtility.ScriptDir & "\" & sFilename
  2541.             iRetVal = Success
  2542.         ElseIf oFSO.FileExists(oUtility.LocalRootPath & "\" & sFileName) then
  2543.             sFoundPath = oUtility.LocalRootPath & "\" & sFileName
  2544.             iRetVal = Success
  2545.         ElseIf oFSO.FileExists(".\" & sFileName) then
  2546.             sFoundPath = oShell.CurrentDirectory & "\" & sFilename
  2547.             iRetVal = Success
  2548.         ElseIf oFSO.FileExists(oEnvironment.Substitute("%WINDIR%\SYSNATIVE\" & sFilename)) then
  2549.             sFoundPath = oEnvironment.Substitute("%WINDIR%\SYSNATIVE\" & sFilename)
  2550.             iRetVal = Success
  2551.         ElseIf oFSO.FileExists(oEnvironment.Substitute("%WINDIR%\SYSTEM32\" & sFilename)) then
  2552.             sFoundPath = oEnvironment.Substitute("%WINDIR%\SYSTEM32\" & sFilename)
  2553.             iRetVal = Success
  2554.         ElseIf oEnvironment.Item("OSDPACKAGEPATH") <> "" and oFSO.FileExists(oEnvironment.Item("OSDPACKAGEPATH") & "\" & sFilename) then
  2555.             sFoundPath = oEnvironment.Item("OSDPACKAGEPATH") & "\" & sFilename
  2556.             iRetVal = Success
  2557.         ElseIf oEnvironment.Item("_SMSTSPackagePath") <> "" and oFSO.FileExists(oEnvironment.Item("_SMSTSPackagePath") & "\" & sFilename) then
  2558.             sFoundPath = oEnvironment.Item("_SMSTSPackagePath") & "\" & sFilename
  2559.             iRetVal = Success
  2560.         ElseIf oFSO.FileExists(".\x86\" & sFileName) then
  2561.             sFoundPath = oShell.CurrentDirectory & "\x86\" & sFilename
  2562.             iRetVal = Success
  2563.         ElseIf oFSO.FileExists(".\x64\" & sFileName) then
  2564.             sFoundPath = oShell.CurrentDirectory & "\x64\" & sFilename
  2565.             iRetVal = Success
  2566.         ElseIf oFSO.FileExists(".\amd64\" & sFileName) then
  2567.             sFoundPath = oShell.CurrentDirectory & "\amd64\" & sFilename
  2568.             iRetVal = Success
  2569.         ElseIf oFSO.FileExists(sFileName) then
  2570.             sFoundPath = sFilename
  2571.             iRetVal = Success
  2572.         End if
  2573.  
  2574.         If iRetVal <> Success then
  2575.             oLogging.CreateEntry "FindFile: The file " & sFilename & " could not be found in any standard locations.", LogTypeInfo
  2576.         End if
  2577.  
  2578.         FindFile = iRetVal
  2579.  
  2580.     End Function
  2581.  
  2582.  
  2583.     Function FindMappedDrive(sServerUNC)
  2584.  
  2585.         Dim arrSplit
  2586.         Dim sServerShare, sServerName
  2587.         Dim arrDrives, i
  2588.  
  2589.  
  2590.         ' If the UNC isn't a UNC, just return the drive letter
  2591.  
  2592.         If Len(sServerUNC) < 3 then
  2593.             FindMappedDrive = ""
  2594.             EXIT FUNCTION
  2595.         End if
  2596.         If Mid(sServerUNC,2,2) = ":\" then
  2597.             FindMappedDrive = Left(sServerUNC, 2)
  2598.             EXIT FUNCTION
  2599.         End if
  2600.  
  2601.  
  2602.         ' Build the UNC
  2603.  
  2604.         If Instr(Mid(sServerUNC, 3), "\") <= 0 or Left(sServerUNC, 2) <> "\\" then
  2605.             FindMappedDrive = ""
  2606.             EXIT FUNCTION
  2607.         End if
  2608.         arrSplit = Split(Mid(sServerUNC,3), "\",2)
  2609.         sServerName = arrSplit(0)
  2610.         sServerShare = "\\" & sServerName & "\" & arrSplit(1)
  2611.  
  2612.  
  2613.         ' Look to see if this is a mapped drive
  2614.  
  2615.         On Error Resume Next
  2616.         Set arrDrives = oNetwork.EnumNetworkDrives
  2617.         If Err then
  2618.             FindMappedDrive = ""
  2619.             Exit Function
  2620.         Else
  2621.             On Error Goto 0
  2622.             For i = 0 to arrDrives.Count - 1 Step 2
  2623.                 If UCase(sServerShare) = UCase(arrDrives.Item(i+1)) and arrDrives.Item(i) <> "" then
  2624.                     FindMappedDrive = arrDrives.Item(i)
  2625.                     Exit Function
  2626.                 End if
  2627.             Next
  2628.         End if
  2629.         On Error Goto 0
  2630.  
  2631.         FindMappedDrive = ""
  2632.  
  2633.     End Function
  2634.  
  2635.  
  2636.     Function ValidateConnection(sServerUNC)
  2637.         ValidateConnection = ValidateConnectionEx(sServerUNC, False)
  2638.     End function
  2639.    
  2640.     Function GetNextNAACred(Index)
  2641.         Dim iMaxNumLength
  2642.         Dim sNumberAsString
  2643.         Dim sNAAName
  2644.         Dim sNAAPass
  2645.                
  2646.         iMaxNumLength = 3
  2647.         sNAAName = "_SMSTSReserved1-"
  2648.         sNAAPass = "_SMSTSReserved2-"
  2649.        
  2650.         If Index <= 0 Then
  2651.             sNumberAsString = "000"
  2652.         Else
  2653.             sNumberAsString = String(iMaxNumLength - Fix(Log(Fix(Index)) / Log(10)) - 1, "0") & CStr(Fix(Index))
  2654.         End If
  2655.        
  2656.         sNAAName = sNAAName & sNumberAsString
  2657.         sNAAPass = sNAAPass & sNumberAsString
  2658.        
  2659.         If oEnvironment.Item(sNAAName) <> "" AND oEnvironment.Item(sNAAPass) <> "" Then
  2660.             OEnvironment.Item("UserDomain") = Left(oEnvironment.Item(sNAAName),Instr(oEnvironment.Item(sNAAName),"\")-1)
  2661.             oEnvironment.Item("UserID")= Mid(oEnvironment.Item(sNAAName),Instr(oEnvironment.Item(sNAAName),"\")+1)
  2662.             oEnvironment.Item("UserPassword")=oEnvironment.Item(sNAAPass)
  2663.            
  2664.             GetNextNAACred = True
  2665.         Else
  2666.             GetNextNAACred = False
  2667.         End if
  2668.     End Function
  2669.    
  2670.     Function ValidateConnectionEx(sServerUNC, bForceConnection)
  2671.  
  2672.         Dim iRetVal
  2673.         Dim arrSplit
  2674.         Dim sServerShare, sServerName, sFoundDrive
  2675.         Dim sOSDConnectToUNC, sRIPInfo, sCmd
  2676.         Dim sWizardHTA, sUserID
  2677.         Dim sCurrentServerName, i
  2678.  
  2679.         ' Make sure a UNC is specified
  2680.  
  2681.         If sServerUNC = "" then
  2682.             oLogging.CreateEntry "WARNING - Unable to validation connection because a blank UNC was specified.", LogTypeWarning
  2683.             ValidateConnectionEx = Failure
  2684.             EXIT FUNCTION
  2685.         End if
  2686.         If Mid(sServerUNC,2,2) = ":\" then
  2687.             oLogging.CreateEntry "Using a local or mapped drive, no connection is required.", LogTypeInfo
  2688.             ValidateConnectionEx = Success
  2689.             EXIT FUNCTION
  2690.         End if
  2691.  
  2692.         oLogging.CreateEntry "Validating connection to " & sServerUNC, LogTypeInfo
  2693.         iRetVal = ValidateNetworkConnectivity
  2694.         If iRetVal <> Success then
  2695.  
  2696.             'blow up
  2697.             ValidateConnectionEx = Failure
  2698.             Exit Function
  2699.         End IF
  2700.  
  2701.  
  2702.         ' See if we've already connected
  2703.  
  2704.         If bForceConnection then
  2705.             ' When forcing a connection, map all the way down to the specified folder
  2706.             arrSplit = Split(Mid(sServerUNC,3), "\", 2)
  2707.         Else
  2708.             ' When not forcing, split into more chunks so we only get server and share
  2709.             arrSplit = Split(Mid(sServerUNC,3), "\")
  2710.         End if
  2711.         sServerName = arrSplit(0)
  2712.         sServerShare = "\\" & sServerName & "\" & arrSplit(1)
  2713.  
  2714.         oLogging.CreateEntry "Mapping server share: " & sServerShare, LogTypeInfo
  2715.        
  2716.         ' This isn't necessary if we're trying to connect to the current DP, so check that.
  2717.         If Left(oUtility.ScriptDir, 2) = "\\" then
  2718.  
  2719.             arrSplit = Split(Mid(oUtility.ScriptDir, 3), "\")
  2720.             sCurrentServerName = arrSplit(0)
  2721.             If UCase(sServerName) = UCase(sCurrentServerName) then
  2722.  
  2723.                 oLogging.CreateEntry "Already connected to server " & sServerName & " as that is where this script is running from.", LogTypeInfo
  2724.                 If bForceConnection then
  2725.  
  2726.                     ' We want a mapped drive in this case, without credentials because we are already connected
  2727.  
  2728.                     If MapNetworkDrive(sServerShare, "", "") <> Success then
  2729.                         oLogging.CreateEntry "Unable to map a drive to the deployment share.", LogTypeInfo
  2730.                     End if
  2731.  
  2732.                 End if
  2733.  
  2734.                 ValidateConnectionEx = Success
  2735.                 EXIT FUNCTION
  2736.  
  2737.             End if
  2738.  
  2739.         End if
  2740.  
  2741.  
  2742.  
  2743.         ' Now see if there is already a server connection.
  2744.         ' We may wish to use bForceConnection if we *Require* the Drive letter,
  2745.         '   even though the computer may be connected to the sever via another share.
  2746.         If dicNetworkConnections.Exists(sServerName) and not bForceConnection then
  2747.             oLogging.CreateEntry "Already connected to server " & sServerName, LogTypeInfo
  2748.             ValidateConnectionEx = Success
  2749.             EXIT FUNCTION
  2750.         End if
  2751.  
  2752.  
  2753.         'Map the SCCM user variables to the CS.INI variables
  2754.         GetNextNAACred 0 'Attempt to get first NAA info
  2755.  
  2756.         '  It is possible that the server allows anonymous connections, skip if the share is readable.
  2757.         'if oFso.FolderExists(sServerName) then
  2758.         '   oLogging.CreateEntry "Already connected to server " & sServerName, LogTypeInfo
  2759.         '   ValidateConnectionEx = Success
  2760.         '   EXIT FUNCTION
  2761.         'end if
  2762.  
  2763.         ' If no credentials are available, prompt. (Only works in WinPE)
  2764.  
  2765.         If oEnvironment.Item("UserID") = "" or oEnvironment.Item("UserPassword") = "" or (  oEnvironment.Item("UserDomain") = "" and _
  2766.             instr(1,oEnvironment.Item("UserID"),"\",vbTextCompare) = 0 and instr(1,oEnvironment.Item("UserID"),"@",vbTextCompare) = 0 ) then
  2767.  
  2768.             ' Find the HTA that prompts for credentials
  2769.  
  2770.             iRetVal = FindFile("Wizard.hta", sWizardHTA)
  2771.             If iRetVal <> Success then
  2772.                 oLogging.CreateEntry "ERROR - Unable to find Wizard.hta, so it is impossible to prompt for credentials.", LogTypeError
  2773.                 ValidateConnectionEx = Failure
  2774.                 Exit Function
  2775.             End if
  2776.  
  2777.             ' Execute the HTA
  2778.  
  2779.             oShell.Run "mshta.exe """ & sWizardHTA & """ /NotWizard /LeaveShareOpen /ValidateAgainstUNCPath:""" & sServerShare & """ /Definition:Credentials_ENU.xml", 1, true
  2780.  
  2781.             ' See if the values are populated now
  2782.  
  2783.             If oEnvironment.Item("UserID") = "" then
  2784.                 oLogging.CreateEntry "ERROR - no credentials were returned from LTICredentials.hta, so no connection is possible.", LogTypeError
  2785.                 ValidateConnectionEx = Failure
  2786.                 Exit Function
  2787.             End if
  2788.  
  2789.         End if
  2790.  
  2791.  
  2792.         ' Map a drive
  2793.        
  2794.         Dim iTryIteration
  2795.         Dim bAnotherNAA
  2796.         iTryIteration = 1
  2797.         bAnotherNAA = True
  2798.        
  2799.         Do 
  2800.             If oEnvironment.Item("UserDomain") <> "" then
  2801.                 sUserID = oEnvironment.Item("UserDomain") & "\" & oEnvironment.Item("UserID")
  2802.             Else
  2803.                 sUserID = oEnvironment.Item("UserID")
  2804.             End if
  2805.  
  2806.             For i = 1 to 5
  2807.                 If MapNetworkDrive(sServerShare, sUserID, oEnvironment.Item("UserPassword")) = Success then
  2808.                     Exit for
  2809.                 End If
  2810.  
  2811.                 oLogging.CreateEntry "Unable to connect to " & sServerShare & ".  Sleeping for " & CStr(i * 5) & " seconds.", LogTypeInfo
  2812.                 On error Resume next
  2813.                 WScript.Sleep i * 5000
  2814.                 on error goto 0
  2815.             Next
  2816.  
  2817.             If IsNetworkDriveMapped(sServerShare) = True Then Exit Do
  2818.            
  2819.             'After 5 failures, try another account
  2820.             bAnotherNAA = GetNextNAACred(iTryIteration)
  2821.             iTryIteration = iTryIteration + 1
  2822.                
  2823.             If Not bAnotherNAA Then
  2824.                 oLogging.CreateEntry "ERROR - Unable to map a network drive to " & sServerShare & ".", LogTypeError
  2825.                 ValidateConnectionEx = Failure
  2826.                 Exit Function
  2827.             End If
  2828.            
  2829.         Loop While bAnotherNAA = True
  2830.  
  2831.         ' Record the mapped drive
  2832.  
  2833.         oLogging.CreateEntry "Successfully established connection using supplied credentials.", LogTypeInfo
  2834.         If not dicNetworkConnections.Exists(sServerName) then
  2835.             dicNetworkConnections.Add sServerName, sServerShare
  2836.         End if
  2837.  
  2838.         iRetVal = Success
  2839.  
  2840.  
  2841.         ValidateConnectionEx = iRetVal
  2842.  
  2843.     End Function
  2844.  
  2845.  
  2846.     Function ValidateNetworkConnectivity
  2847.  
  2848.         Dim Entity, ID, oAdapter, oAdapter2, colAdapters, colAdapters2, sIPConnectionMetric, sWirelessConnectionMetric
  2849.         Dim bValidIP
  2850.  
  2851.         ' Check for networkadapters present
  2852.  
  2853.         bValidIP = True
  2854.         If objWMI.ExecQuery("select * from win32_NetworkAdapter where Installed = true and adaptertypeid = 0").Count = 0 then
  2855.             oLogging.CreateEntry "No networking adapters found, The network drivers for your device are not present",LogTypeError
  2856.             ValidateNetworkConnectivity = Failure
  2857.             exit function
  2858.    
  2859.         End if
  2860.  
  2861.  
  2862.         'Check for IP address
  2863.  
  2864.         Set colAdapters = objWMI.ExecQuery("select * from win32_NetworkAdapterConfiguration where IPEnabled=True")
  2865.  
  2866.         For Each oAdapter in colAdapters
  2867.             If oAdapter.DHCPEnabled = TRUE Then
  2868.                 If oAdapter.DHCPServer = "255.255.255.255" Then
  2869.                     bValidIP = False
  2870.                
  2871.                 Else
  2872.                     bValidIP = True
  2873.                     Exit For
  2874.                 End if
  2875.                
  2876.             Else
  2877.                 oLogging.CreateEntry "DHCP is not enabled, assuming static IP address", LogTypeInfo
  2878.                 bValidIP = True
  2879.                 Exit For
  2880.             End if
  2881.         Next
  2882.  
  2883.         If bValidIP <> True Then
  2884.             'No IP Address, do an ipconfig /renew
  2885.             oShell.Run "ipconfig /renew",0,true
  2886.             on error resume next
  2887.             wscript.sleep 5000
  2888.             on error goto 0
  2889.             Set colAdapters2 = objWMI.ExecQuery("select * from win32_NetworkAdapterconfiguration where IPEnabled = True")
  2890.             For Each oAdapter2 in colAdapters2
  2891.                 If oAdapter2.DHCPEnabled = TRUE Then
  2892.                     If oAdapter2.DHCPServer = "255.255.255.255" Then
  2893.                         oLogging.CreateEntry "IP Address could not be obtained",LogTypeError
  2894.                         ValidateNetworkConnectivity = Failure
  2895.                         Exit Function
  2896.                     Else
  2897.                         Exit for
  2898.                     End if
  2899.                 End if
  2900.             Next
  2901.         End If
  2902.  
  2903.         'Check for wireless connectivity
  2904.  
  2905.         Set colAdapters = objWMI.ExecQuery("select * from win32_NetworkAdapterconfiguration where IPEnabled = True")
  2906.         For Each oAdapter in colAdapters
  2907.             If Instr(UCase(oAdapter.Caption),"WIRELESS") = 0 Then
  2908.                 If oAdapter.IPConnectionMetric < sIPConnectionMetric Or sIPConnectionMetric = "" Then
  2909.                     sIPConnectionMetric = oAdapter.IPConnectionMetric
  2910.                 End If
  2911.             End IF
  2912.            
  2913.             If Instr(UCase(oAdapter.Caption),"WIRELESS") Then
  2914.                 sWirelessConnectionMetric = oAdapter.IPConnectionMetric
  2915.            
  2916.        
  2917.             End If
  2918.        
  2919.         Next
  2920.        
  2921.         If sIPConnectionMetric = "" Then
  2922.             oLogging.CreateEntry "No physical adapters present, cannot deploy over wireless", LogTypeError
  2923.             ValidatenetworkConnectivity = Failure
  2924.             Exit Function
  2925.         End IF
  2926.  
  2927.  
  2928.         'TODO Check for VPN connectivity
  2929.  
  2930.         ValidateNetworkConnectivity = Success
  2931.  
  2932.     End Function
  2933.  
  2934.  
  2935.     Function IsNetworkDriveMapped(sShare)
  2936.         IsNetworkDriveMapped = False
  2937.        
  2938.         If IsEmpty(sShare) Or IsNull(sShare) Or TypeName(sShare) = "Nothing" Then
  2939.             oLogging.CreateEntry "Specified network path is null or invalid.", LogTypeError
  2940.             Exit Function
  2941.         End if
  2942.    
  2943.         Dim i
  2944.         Dim arrDrives
  2945.        
  2946.         On Error Resume Next
  2947.         Set arrDrives = oNetwork.EnumNetworkDrives
  2948.        
  2949.         If Err then
  2950.             oLogging.CreateEntry "Unable to enumerate network drives (is the network initialized?): " & Err.Description & " (" & Err.Number & ")", LogTypeWarning
  2951.         Else
  2952.  
  2953.             ' Find any previous connections (skip connections without drive letters)
  2954.  
  2955.             For i = 0 to arrDrives.Count - 1 Step 2
  2956.                 If UCase(sShare) = UCase(arrDrives(i+1)) and arrDrives(i) <> "" then
  2957.                     IsNetworkDriveMapped = True
  2958.                     oLogging.CreateEntry "Found Existing UNC Path " & arrDrives(i) & " = " & sShare , LogTypeInfo
  2959.  
  2960.                     Exit function
  2961.                 End if
  2962.             Next
  2963.  
  2964.         End if
  2965.     End Function
  2966.    
  2967.     ' For Backwards Compatiblity
  2968.     Function MapNetworkDrive (sShare, sDomID, sDomPwd )
  2969.  
  2970.         ' Make sure networking is initialized
  2971.         If IsNetworkDriveMapped(sShare) Then
  2972.             MapNetworkDrive = Success
  2973.             Exit Function
  2974.         End If
  2975.        
  2976.         If Len(MapNetworkDriveEx (sShare, sDomID, sDomPwd, LogTypeError )) = 2 then
  2977.             MapNetworkDrive = Success
  2978.         Else
  2979.             MapNetworkDrive = Failure
  2980.         End if
  2981.     End function
  2982.  
  2983.  
  2984.     '
  2985.     ' maps a drive letter to the sShare UNC path.
  2986.     '   Returns the drive letter example: "C:", otherwise returns an error string!
  2987.     '   sDomID and sDomPwd can be EMPTY.
  2988.     '
  2989.     Function MapNetworkDriveEx (sShare, sDomID, sDomPwd, iLogType )
  2990.  
  2991.         Dim sDrive
  2992.         Dim HasError
  2993.         Dim ErrDesc
  2994.         Dim i
  2995.        
  2996.  
  2997.  
  2998.         On Error Goto 0
  2999.  
  3000.  
  3001.         ' Find the first available drive letter
  3002.  
  3003.         For sDrive = asc("Z") to asc("C") step -1
  3004.  
  3005.             On Error Resume Next
  3006.             If sDomID <> "" and sDomPwd <> "" then
  3007.                 oNetwork.MapNetworkDrive  chr(sDrive)&":", sShare, False, sDomID, sDomPwd
  3008.             Else
  3009.                 oNetwork.MapNetworkDrive  chr(sDrive)&":", sShare, False
  3010.             End if
  3011.             HasError = err.number
  3012.             ErrDesc = err.Description
  3013.             On Error Goto 0
  3014.  
  3015.             Select case HasError
  3016.             Case 0          ' No Error, SUCCESS
  3017.                 MapNetworkDriveEx = chr(sDrive)&":"
  3018.                 oLogging.CreateEntry "Mapped Network UNC Path " & MapNetworkDriveEx & "  = " & sShare , LogTypeInfo
  3019.                 Exit function
  3020.             Case &h80070055 ' The local device name is already in use.
  3021.             Case &h800704B2 ' The local device name has a remembered connection to another network resource.
  3022.             ' Case &h800704C3 ' Multiple connections to a server or shared resource by the same user, using more than one user name, are not allowed.
  3023.             ' Case &h8007052E ' Logon failure: unknown user name or bad password.          
  3024.             Case Else
  3025.                 oLogging.CreateEntry "Unable to connect to share: " & ErrDesc & "( 0x" & hex(HasError) & " ) , trying to connect without username. ", LogTypeInfo
  3026.                 Err.Clear
  3027.                 On Error Resume Next
  3028.                 oNetwork.MapNetworkDrive chr(sDrive)&":", sShare, False
  3029.                 HasError = err.number
  3030.                 ErrDesc = err.Description
  3031.                 On Error Goto 0
  3032.                 If HasError <> 0 Then
  3033.  
  3034.                     ' There was a some kind of fatal error.
  3035.                     If ErrDesc <> "" then
  3036.                         MapNetworkDriveEx = ErrDesc
  3037.                     Else
  3038.                         MapNetworkDriveEx = "Unable to map UNC Path " & sShare & " :" & "( 0x" & hex(HasError) & " ) "
  3039.                     End if
  3040.                     oLogging.CreateEntry MapNetworkDriveEx & "", iLogType
  3041.                     Exit function
  3042.                 Else
  3043.                     MapNetworkDriveEx = chr(sDrive)&":"
  3044.                     Exit Function
  3045.                 End If     
  3046.             End select
  3047.  
  3048.         Next
  3049.  
  3050.         MapNetworkDriveEx = "Unable to map UNC Path " & sShare & " : No available local device names! "
  3051.         oLogging.CreateEntry MapNetworkDriveEx , iLogType
  3052.  
  3053.     End function
  3054.  
  3055.  
  3056.     Public Function VerifyPathExistsEx(strPath, bAdjustSD)
  3057.         Dim oHelper, sSDDL, oLogicalFile, oDescriptor
  3058.         If strPath = "" then
  3059.             VerifyPathExistsEx = True
  3060.             Exit Function
  3061.         End if
  3062.         If oFSO.FolderExists(strPath) then
  3063.             VerifyPathExistsEx = true
  3064.             Exit Function
  3065.         Else
  3066.             VerifyPathExists oFSO.GetParentFolderName(strPath)
  3067.             On Error Resume Next
  3068.             oFSO.CreateFolder strPath
  3069.            
  3070.             'Set Permissions if it is not a UNC path
  3071.             If Left(strPath, 2) <> "\\" and bAdjustSD Then
  3072.                 strPath = Replace(strPath, "\", "\\")
  3073.  
  3074.                 Set oHelper = objWMI.Get("Win32_SecurityDescriptorHelper")
  3075.  
  3076.                 sSDDL = "O:BAG:SYD:PAI(A;OICI;FA;;;BA)(A;OICI;FA;;;SY)"
  3077.  
  3078.                 oHelper.SDDLToWin32SD sSDDL, oDescriptor
  3079.                 Set oLogicalFile = objWMI.Get("Win32_LogicalFileSecuritySetting.Path='" & strPath & "'")
  3080.                 TestAndLog oLogicalFile.SetSecurityDescriptor(oDescriptor), "Set security on folder " & strPath
  3081.                
  3082.             End If
  3083.             On Error Goto 0
  3084.         End if
  3085.     End function
  3086.    
  3087.     Public Function VerifyPathExists(strPath)
  3088.         VerifyPathExists = VerifyPathExistsEx(strPath, false)
  3089.     End Function
  3090.  
  3091.  
  3092.     Function GetAllFixedDrives(bReturnOnlyBootable)
  3093.  
  3094.         Dim oWMIDiskPart
  3095.         Dim oDiskPart
  3096.         Dim oDisk
  3097.  
  3098.         oLogging.CreateEntry "ZTIUtility!GetAllFixedDrives (" & bReturnOnlyBootable & ")", LogTypeInfo
  3099.  
  3100.         for each oWMIDiskPart in AllDiskPart
  3101.             set oDiskPart = new ZTIDiskPartition
  3102.             set oDiskPart.DiskPart = oWMIDiskPart
  3103.             set oDisk = oDiskPart.GetDiskObject
  3104.             If oDisk.IsOSReady("0.0.0.0") then
  3105.                 GetAllFixedDrives = GetAllFixedDrives & " " & oDiskPart.Drive
  3106.             End if
  3107.         next
  3108.  
  3109.         oLogging.CreateEntry "ZTIUtility!GetAllFixedDrives = " & GetAllFixedDrives, LogTypeInfo
  3110.  
  3111.         GetAllFixedDrives = split(trim(GetAllFixedDrives)," ")
  3112.  
  3113.     End function
  3114.  
  3115.     '
  3116.     ' Create an XMLDOM Object
  3117.     '
  3118.     Function CreateXMLDOMObjectEx( sFileName )
  3119.    
  3120.         Dim bRetVal
  3121.  
  3122.         on error resume next
  3123.        
  3124.         Set CreateXMLDOMObjectEx = nothing
  3125.         Set CreateXMLDOMObjectEx = oUtility.GetMSXMLDOMDocument
  3126.         TestAndFail not (CreateXMLDOMObjectEx is nothing), 5490, "Create MSXML2.DOMDocument."
  3127.        
  3128.         CreateXMLDOMObjectEx.Async = FALSE
  3129.  
  3130.         If sFileName <> "" then
  3131.        
  3132.             oLogging.CreateEntry "CreateXMLDOMObjectEx(" & sFileName & ")", LogTypeVerbose
  3133.             bRetVal = CreateXMLDOMObjectEx.Load (sFileName )
  3134.             TestAndLog bRetVal, "CreateXMLDOMObjectEx...Length = " & CreateXMLDOMObjectEx.documentElement.childNodes.Length
  3135.             With CreateXMLDOMObjectEx.ParseError
  3136.                 If .errorCode <> 0 then
  3137.                     oLogging.CreateEntry "File: " & sFileName & " Line: " & .Line & " - " & .Reason & " - " & .SrcText, LogTypeWarning
  3138.                 End if
  3139.             End with
  3140.            
  3141.         End if
  3142.        
  3143.         on error goto 0
  3144.  
  3145.     End function
  3146.    
  3147.  
  3148.     ' Create an XMLDOM Object, do not return if there is a parse error.
  3149.     Function CreateXMLDOMObjectSafe( sFileName )
  3150.    
  3151.         Set CreateXMLDOMObjectSafe = CreateXMLDOMObjectEx( sFileName )
  3152.         TestAndFail CreateXMLDOMObjectSafe.ParseError.ErrorCode, 5495, "Create MSXML2.DOMDocument  .ParseErr.ErrCode."
  3153.        
  3154.     End function
  3155.    
  3156.  
  3157.    
  3158.     Function CreateXMLDOMObject
  3159.         Set CreateXMLDOMObject = CreateXMLDOMObjectEx( empty )
  3160.     End function
  3161.  
  3162.  
  3163.     ' Load an XML file via FindFile
  3164.     Function LoadConfigFile( sConfigFile )
  3165.  
  3166.         Set LoadConfigFile = LoadConfigFileEx( sConfigFile, false )
  3167.  
  3168.     End function
  3169.    
  3170.    
  3171.     ' Load an XML file via FindFile, do not return if there is any error.
  3172.     Function LoadConfigFileSafe( sConfigFile )
  3173.    
  3174.         Set LoadConfigFileSafe = LoadConfigFileEx( sConfigFile, TRUE )
  3175.  
  3176.     End function
  3177.    
  3178.  
  3179.     ' Load an XML file via FindFile, do not return if there is any error.
  3180.     Function LoadConfigFileEx( sConfigFile, bMustSucceed )
  3181.    
  3182.         Dim sFoundFile
  3183.         Dim iRetVal
  3184.  
  3185.         iRetVal = oUtility.FindFile( sConfigFile , sFoundFile)
  3186.         If bMustSucceed then
  3187.             TestAndFail iRetVal, 5496, "LoadControlFile.FindFile: " & sConfigFile
  3188.             set LoadConfigFileEx = CreateXMLDOMObjectSafe (sFoundFile)
  3189.         Else
  3190.             set LoadConfigFileEx = CreateXMLDOMObjectEx (sFoundFile)
  3191.         End if
  3192.  
  3193.     End function
  3194.  
  3195.  
  3196.     Function BDDUtility
  3197.  
  3198.         Dim sBDDUtility
  3199.         Dim iRetval
  3200.         Dim sProc
  3201.  
  3202.  
  3203.         ' Already retrieved an instance?  Return it.
  3204.         If not (oBDDUtility is Nothing) then
  3205.             Set BDDUtility = oBDDUtility
  3206.             Exit Function
  3207.         End if
  3208.  
  3209.  
  3210.         ' Already registered? Call Routine.
  3211.         on error resume next
  3212.         Set oBDDUtility = CreateObject("Microsoft.BDD.Utility")
  3213.         on error goto 0
  3214.  
  3215.         If not (oBDDUtility is Nothing) then
  3216.             Set BDDUtility = oBDDUtility
  3217.             Exit Function
  3218.         End if
  3219.  
  3220.  
  3221.         ' Find each Microsoft.BDD.Utility.dll file, and copy locally if over the network.
  3222.         for each sProc in array("x86","x64")
  3223.  
  3224.             If not oFSO.FileExists(oEnv("TEMP") & "\Tools\" & sProc & "\Microsoft.BDD.Utility.dll") then
  3225.  
  3226.                 iRetVal = FindFile( sProc & "\Microsoft.BDD.Utility.dll", sBDDUtility)
  3227.                 oLogging.CreateEntry "FindFile(...\Microsoft.BDD.Utility.dll)  Result : " & iRetVal, LogTypeInfo
  3228.  
  3229.                 If left(sBDDUtility,2) = "\\" then
  3230.                     oUtility.VerifyPathExistsEx oEnv("TEMP") & "\Tools\" & sProc , false
  3231.                     oFileHandling.CopyFile sBDDUtility, oEnv("TEMP") & "\Tools\" & sProc & "\", True
  3232.                 End if
  3233.  
  3234.             End if
  3235.            
  3236.             If oFSO.FileExists(oEnv("TEMP") & "\Tools\" & sProc & "\Microsoft.BDD.Utility.dll") then
  3237.                 sBDDUtility = oEnv("TEMP") & "\Tools\" & sProc & "\Microsoft.BDD.Utility.dll"
  3238.             End if
  3239.  
  3240.             ' Register the DLL
  3241.             oLogging.CreateEntry "RUN: regsvr32.exe /s """ & sBDDUtility & """", LogTypeInfo
  3242.             oShell.Run "regsvr32.exe /s """ & sBDDUtility & """", 0, true ' Always returns 0 - Success
  3243.  
  3244.         next
  3245.  
  3246.  
  3247.  
  3248.         ' Create an instance
  3249.  
  3250.         on error resume next
  3251.         Set oBDDUtility = CreateObject("Microsoft.BDD.Utility")
  3252.         TestAndLog not oBDDUtility is nothing, "CreateObject(Microsoft.BDD.Utility)"
  3253.         on error goto 0
  3254.        
  3255.         Set BDDUtility = oBDDUtility
  3256.  
  3257.     End Function
  3258.  
  3259.     Private Sub SetIfChanged(sVar, sVal)
  3260.         If oEnvironment.Item(sVar) <> sVal then
  3261.             oEnvironment.Item(sVar) = sVal
  3262.         End if
  3263.     End Sub
  3264.  
  3265.     Sub SetTaskSequenceProperties(tsID)
  3266.  
  3267.         Dim oTaskSequences
  3268.         Dim oTaskSequence
  3269.         Dim oOperatingSystems
  3270.         Dim oOS
  3271.         Dim oImageLang
  3272.         Dim sImageLang
  3273.         Dim oLanguage
  3274.         Dim sImagePath
  3275.         Dim oWDSServer
  3276.         Dim sWDSServer
  3277.         Dim objTmp
  3278.         Dim oTS
  3279.         Dim oOSGUID
  3280.         Dim oDestinationDisk,oDestinationPartition,ODestinationLogicalDrive
  3281.         Dim sSourcePath
  3282.  
  3283.  
  3284.         ' If there is task sequence ID set, get the properties
  3285.  
  3286.         If tsID <> "" then
  3287.  
  3288.             ' Get the task sequence record
  3289.  
  3290.             tsID = Ucase(tsID)
  3291.  
  3292.             Set oTaskSequences = oUtility.CreateXMLDOMObjectEx(oEnvironment.Item("DeployRoot") & "\Control\TaskSequences.xml")
  3293.             Set oTaskSequence = oTaskSequences.selectSingleNode("//ts[ID='" & tsID & "']")
  3294.             If oTaskSequence is Nothing then
  3295.                 oLogging.CreateEntry "ERROR: Invalid task sequence ID " & tsID & " specified", LogTypeError
  3296.                 Exit Sub
  3297.             End if
  3298.  
  3299.  
  3300.             ' Set the simple build properties
  3301.  
  3302.             oEnvironment.Item("TaskSequenceName") = oUtility.SelectSingleNodeString(oTaskSequence,"Name")
  3303.             oEnvironment.Item("TaskSequenceVersion") = oUtility.SelectSingleNodeStringEx(oTaskSequence,"Version", False)
  3304.             oEnvironment.Item("TaskSequenceTemplate") = oUtility.SelectSingleNodeStringEx(oTaskSequence,"TaskSequenceTemplate", False)
  3305.  
  3306.  
  3307.             ' Blank out any previous values        
  3308.  
  3309.             SetIfChanged "ImageIndex", ""
  3310.             SetIfChanged "ImageSize", ""
  3311.             SetIfChanged "ImageFlags", ""
  3312.             SetIfChanged "ImageBuild", ""
  3313.             SetIfChanged "InstallFromPath", ""
  3314.             SetIfChanged "ImageMemory", ""
  3315.             SetIfChanged "ImageProcessor", ""
  3316.             SetIfChanged "OSGUID", ""
  3317.             SetIfChanged "IsOSUpgrade", ""
  3318.  
  3319.  
  3320.             ' Load the TS.XML
  3321.  
  3322.             Set oTS = oUtility.CreateXMLDOMObjectEx(oEnvironment.Item("DeployRoot") & "\Control\" & tsID & "\TS.xml")
  3323.  
  3324.  
  3325.             ' Determine the deployment type
  3326.  
  3327.             'If (oTS.SelectSingleNode("//step[@type='BDD_InstallOS']") is nothing) and (oTS.SelectSingleNode("//step[@type='BDD_UpgradeOS']") is nothing) then
  3328.             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
  3329.                 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
  3330.                 oEnvironment.Item("OSGUID")=""
  3331.                 If not (oTS.SelectSingleNode("//group[@name='State Restore']") is nothing) then
  3332.                     oEnvironment.Item("DeploymentType") = "StateRestore"
  3333.                 ElseIf oEnvironment.Item("TaskSequenceTemplate") <> "ClientReplace.xml" and oTS.SelectSingleNode("//step[@name='Capture User State']") is nothing then
  3334.                     oEnvironment.Item("DeploymentType") = "CUSTOM"
  3335.                 Else
  3336.                     oEnvironment.Item("DeploymentType") = "REPLACE"
  3337.                     oEnvironment.Item("ImageProcessor") = Ucase(oEnvironment.Item("Architecture"))
  3338.                 End if
  3339.  
  3340.             Elseif oEnvironment.Item("OSVERSION")="WinPE" Then
  3341.  
  3342.                 oEnvironment.Item("DeploymentType") = "NEWCOMPUTER"    
  3343.  
  3344.             Else
  3345.  
  3346.                 oLogging.CreateEntry "Task Sequence contains a LTIApply.wsf step, and is not running within WinPE.", LogTypeInfo
  3347.                 If oTS.SelectSingleNode("//globalVarList/variable[@name='IsOSUpgrade']") is nothing then
  3348.                     oEnvironment.Item("DeploymentType") = "REFRESH"
  3349.                 Else
  3350.                     oEnvironment.Item("DeploymentType") = "UPGRADE"
  3351.                     oEnvironment.Item("IsOSUpgrade") = "1"
  3352.                 End if
  3353.  
  3354.             End if
  3355.  
  3356.             If oEnvironment.Item("IsOSUpgrade") = "" then
  3357.                 oEnvironment.Item("IsOSUpgrade") = "0"
  3358.             End if
  3359.  
  3360.  
  3361.             ' Get the OS details
  3362.  
  3363.             Set oOSGUID = oTS.SelectSingleNode("//globalVarList/variable[@name='OSGUID']")
  3364.             If not (oOSGUID is Nothing) then
  3365.  
  3366.                 ' Get the OS record
  3367.  
  3368.                 oEnvironment.Item("OSGUID") = oOSGUID.text
  3369.                 Set oOperatingSystems = oUtility.CreateXMLDOMObjectEx(oEnvironment.Item("DeployRoot") & "\Control\OperatingSystems.xml")
  3370.                 Set oOS = oOperatingSystems.selectSingleNode("//os[@guid='" & oOSGUID.text & "']")
  3371.                 If oOS is Nothing then
  3372.                     oLogging.CreateEntry "ERROR: Invalid OS GUID " & oOSGUID.text & " specified for task sequence " & tsID & " specified", LogTypeInfo
  3373.                     Exit Sub
  3374.                 End if
  3375.  
  3376.  
  3377.                 ' Set the simple OS properties
  3378.  
  3379.                 oEnvironment.Item("ImageIndex") = oUtility.SelectSingleNodeString(oOS,"ImageIndex")
  3380.                 oEnvironment.Item("ImageSize") = oUtility.SelectSingleNodeString(oOS,"Size")
  3381.                 on error resume next
  3382.                 oEnvironment.Item("ImageFlags") = oOS.selectSingleNode("Flags").text
  3383.                 on error goto 0
  3384.                 oEnvironment.Item("ImageBuild") = oUtility.SelectSingleNodeString(oOS,"Build")
  3385.                 oEnvironment.Item("ImageProcessor") = oUtility.SelectSingleNodeString(oOS,"Platform")
  3386.  
  3387.  
  3388.                 ' Get the languages
  3389.  
  3390.                 Set oImageLang = oOS.selectNodes("Language")
  3391.                 sImageLang = ""
  3392.                 If not (oImageLang is Nothing) then
  3393.                     For each oLanguage in oImageLang
  3394.                         sImageLang = sImageLang & oLanguage.text & vbTab
  3395.                     Next
  3396.                 End if
  3397.                 If right(sImageLang,1) = vbTab then
  3398.                     sImageLang = Left(sImageLang, Len(sImageLang)-1)  ' Remove trailing tab
  3399.                 End if
  3400.                 oEnvironment.ListItem("ImageLanguage") = split(sImageLang, vbTab)
  3401.  
  3402.  
  3403.                 ' Set the image path
  3404.  
  3405.                 If oOS.selectSingleNode("ImageFile") is nothing then
  3406.                     sImagePath = "."
  3407.                 Else
  3408.                     sImagePath = oOS.selectSingleNode("ImageFile").Text
  3409.                     If sImagePath = "" and left(oEnvironment.Item("ImageBuild"),1) = "5" then
  3410.                         sImagePath = "."
  3411.                     End if
  3412.                 End if
  3413.  
  3414.                 If Left(sImagePath, 1) = "." then
  3415.  
  3416.                     ' See if this is a WDS image
  3417.  
  3418.                     Set oWDSServer = oOS.selectSingleNode("WDSServer")
  3419.                     If not (oWDSServer is Nothing) then
  3420.                         sWDSServer = oWDSServer.Text
  3421.                     End if
  3422.  
  3423.  
  3424.                     ' Make sure that's where we want to pull it from
  3425.  
  3426.                     If sWDSServer <> "" then
  3427.                         If oEnvironment.Item("WDSServer") <> "" then
  3428.                             sWDSServer = oEnvironment.Item("WDSServer")
  3429.                         End if
  3430.                     End if
  3431.  
  3432.  
  3433.                     ' Set the actual image path
  3434.  
  3435.                     If sWDSServer <> "" then
  3436.                         sImagePath = "\\" & sWDSServer & "\REMINST" & Mid(sImagePath, 2)
  3437.                     Else
  3438.                         sImagePath = oEnvironment.Item("DeployRoot") & Mid(sImagePath, 2)
  3439.                     End if
  3440.  
  3441.                 End if
  3442.  
  3443.                 oLogging.CreateEntry "InstallFromPath: " & sImagePath, LogTypeInfo
  3444.                 oEnvironment.Item("InstallFromPath") = oFileHandling.NormalizePath(sImagePath)
  3445.  
  3446.                 sSourcePath = oUtility.SelectSingleNodeString(oOS,"Source")
  3447.                 If Left(sSourcePath, 1) = "." then
  3448.                     sSourcePath = oEnvironment.Item("DeployRoot") & Mid(sSourcePath, 2)
  3449.                 End if
  3450.                 oLogging.CreateEntry "SourcePath: " & sSourcePath, LogTypeInfo
  3451.                 oEnvironment.Item("SourcePath") = sSourcePath
  3452.  
  3453.             End if
  3454.  
  3455.         End if
  3456.  
  3457.     End Sub
  3458.  
  3459.  
  3460.     Function IsSupportedPlatform(sPlatform)
  3461.  
  3462.         Dim iRetVal
  3463.         Dim sSupportedPlatforms
  3464.         Dim oPlatformNode
  3465.         Dim oNode
  3466.         Dim oResults
  3467.         Dim oResult
  3468.         Dim bFound
  3469.  
  3470.  
  3471.         ' Special case: check for Windows PE
  3472.  
  3473.         If oEnvironment.Item("OSVersion") = "WinPE" then
  3474.  
  3475.             If sPlatform = "Windows PE" then
  3476.                 IsSupportedPlatform = true
  3477.             Else
  3478.                 IsSupportedPlatform = false
  3479.             End if
  3480.  
  3481.             Exit Function
  3482.         End if
  3483.  
  3484.  
  3485.         ' Load the XML file if not yet loaded
  3486.  
  3487.  
  3488.         If oSupportedPlatforms is Nothing then
  3489.  
  3490.             iRetVal = oUtility.FindFile("ZTISupportedPlatforms.xml", sSupportedPlatforms)
  3491.             Set oSupportedPlatforms = CreateXMLDOMObjectEx(sSupportedPlatforms)
  3492.  
  3493.         End if
  3494.  
  3495.  
  3496.         ' Find the selected platform
  3497.  
  3498.         Set oPlatformNode = oSupportedPlatforms.SelectSingleNode("//SupportedPlatform[@name='" & sPlatform & "']")
  3499.         If oPlatformNode is Nothing then
  3500.             oLogging.CreateEntry "Platform " & sPlatform & " is not found.", LogTypeInfo
  3501.             IsSupportedPlatform = False
  3502.             Exit Function
  3503.         End if
  3504.  
  3505.  
  3506.         ' Check each of the expressions.  If any don't return a record, return false
  3507.  
  3508.         For each oNode in oPlatformNode.SelectNodes("Expression")
  3509.  
  3510.             bFound = false
  3511.             Set oResults = objWMI.ExecQuery(oNode.Text)
  3512.             For each oResult in oResults
  3513.                 bFound = true
  3514.                 Exit For
  3515.             Next
  3516.  
  3517.             If not bFound then
  3518.                 oLogging.CreateEntry "Condition " & oNode.Text & " not satisfied, platform " & sPlatform & " is not supported.", LogTypeInfo
  3519.                 IsSupportedPlatform = False
  3520.                 Exit Function
  3521.             End if
  3522.  
  3523.         Next
  3524.  
  3525.  
  3526.         ' All conditions satisfied, return true
  3527.  
  3528.         oLogging.CreateEntry "Platform " & sPlatform & " is supported on this computer.", LogTypeInfo
  3529.         IsSupportedPlatform = True
  3530.  
  3531.     End Function
  3532.  
  3533.  
  3534.     Function SetTagForDrive( sDriveLetter, sTagVariable )
  3535.  
  3536.         Dim oDiskPart
  3537.         oLogging.CreateEntry "Set the Tag variable: " & sTagVariable, LogTypeInfo
  3538.         oEnvironment.Item(sTagVariable) = ""
  3539.         For each oDiskPart in objWMI.ExecQuery( "SELECT * FROM Win32_LogicalDisk WHERE DeviceID = '" & left(sDriveLetter,2) & "'" )
  3540.             oEnvironment.Item(sTagVariable) = "SELECT * FROM Win32_LogicalDisk WHERE Size = '" & oDiskPart.Size & "' and VolumeName = '" & oDiskPart.VolumeName & "' and VolumeSerialNumber = '" & oDiskPart.VolumeSerialNumber & "'"
  3541.             exit For
  3542.         next
  3543.  
  3544.     End function
  3545.  
  3546.     Function GetDriveFromTag ( sTagVariable )
  3547.  
  3548.         Dim oDiskPart
  3549.         oLogging.CreateEntry "Search for Drive: " & sTagVariable & "  " & oEnvironment.Item(sTagVariable), LogTypeInfo
  3550.         For each oDiskPart in objWMI.ExecQuery( oEnvironment.Item(sTagVariable) )
  3551.             oLogging.CreateEntry "Found Drive: " & oDiskPart.DeviceID, logTypeInfo
  3552.             GetDriveFromTag = left(oDiskPart.DeviceID,2)
  3553.             Exit For
  3554.         next
  3555.  
  3556.     End function
  3557.  
  3558.  
  3559.     Function ClearRelativeDriveLetters
  3560.  
  3561.         oLogging.CreateEntry "If there is a drive letter defined, make sure we clear it now so we can *force* recalcutation.", logTypeInfo
  3562.         oEnvironment.Item("OSDTargetDriveCache") = "DIRTY"
  3563.  
  3564.     End function
  3565.  
  3566.     Function ForceRelativeDriveReCalc
  3567.  
  3568.         oLogging.CreateEntry "We can no longer assume any information on drive letters, reset everything!.", logTypeInfo
  3569.         ClearRelativeDriveLetters
  3570.         If oEnvironment.Item("TargetPartitionIdentifier") <> "" Then
  3571.             oEnvironment.Item("TargetPartitionIdentifier") = "DIRTY"
  3572.         End if
  3573.  
  3574.     End function
  3575.  
  3576.  
  3577.     Function GetOSTargetDriveLetterEx( bRequired )
  3578.  
  3579.         Dim oDiskPart
  3580.         Dim bDiskPartFound
  3581.  
  3582.  
  3583.         ' First check to see if the full OS is running
  3584.         If oEnv("SystemDrive") <> "X:" then
  3585.  
  3586.             ' We are not running within WinPE, Drive Letter may be easy to determine.
  3587.             If ucase(oEnvironment.Item("DestinationOSRefresh")) = "OKTOUSEOTHERDISKANDPARTITION" and ucase(oEnvironment.Item("DeploymentType")) = "REFRESH" and ucase(oEnvironment.Item("PHASE")) <> "STATERESTORE" then
  3588.                 oLogging.CreateEntry "It is possible that the Existing SystemRoot is not the Destiation Drive", logTypeInfo
  3589.             Else
  3590.  
  3591.                 oLogging.CreateEntry "TargetOS is the current SystemDrive", logTypeInfo
  3592.                 GetOSTargetDriveLetterEx = left(oEnv("SystemDrive"),2)
  3593.                 exit function     ' Easy case, exit now!
  3594.             End if
  3595.  
  3596.         End if
  3597.  
  3598.  
  3599.         ' We may wish to use some advanced Disk Partitioning Routines from ZTIDIskPart.vbs. Check availabiltiy.
  3600.         On error resume next
  3601.         bDiskPartFound = false
  3602.         bDiskPartFound = not isempty(ZTIDiskPart_Script)
  3603.         on error goto 0
  3604.  
  3605.  
  3606.         If oEnvironment.Item("OriginalPartitionIdentifier") <> "" and ucase(oEnvironment.Item("DestinationOSRefresh")) <> "OKTOUSEOTHERDISKANDPARTITION" Then
  3607.  
  3608.             oLogging.CreateEntry "OriginalPartitionIdentifier is set, find disk: " & oEnvironment.Item("OriginalPartitionIdentifier"), logTypeInfo
  3609.             GetOSTargetDriveLetterEx = GetDriveFromTag ( "OriginalPartitionIdentifier" )
  3610.  
  3611.  
  3612.         ElseIf oEnvironment.Item("OSDTargetDriveCache") <> "" and oEnvironment.Item("OSDTargetDriveCache") <> "DIRTY" and Ucase(oUtility.ScriptName) <> "ZTIDISKPART" Then
  3613.  
  3614.             oLogging.CreateEntry "OSDTargetDriveCache was determined earlier : " & oEnvironment.Item("OSDTargetDriveCache"), logTypeInfo
  3615.             GetOSTargetDriveLetterEx = left(oEnvironment.Item("OSDTargetDriveCache") ,2)
  3616.  
  3617.  
  3618.         ElseIf oEnvironment.Item("TargetPartitionIdentifier") <> "" and oEnvironment.Item("TargetPartitionIdentifier") <> "DIRTY" Then
  3619.  
  3620.             oLogging.CreateEntry "TargetPartitionIdentifier is set, find disk: " & oEnvironment.Item("TargetPartitionIdentifier"), logTypeInfo
  3621.             GetOSTargetDriveLetterEx = GetDriveFromTag ( "TargetPartitionIdentifier" )
  3622.  
  3623.  
  3624.         ElseIf oEnvironment.Item("DeploymentMethod") <> "SCCM" then
  3625.  
  3626.             '
  3627.             '  Litetouch Scenarios:
  3628.             '
  3629.  
  3630.             If ucase(oEnvironment.Item("DestinationOSInstallType")) = "BYDRIVELETTER" and oEnvironment.Item("DestinationOSDriveLetter") <> "" then
  3631.  
  3632.                 oLogging.CreateEntry "DestinationOSInstallType = BYDRIVELETTER (Generally not recomended scenario, drive letters *can* change between reboots).", LogTypeInfo
  3633.                 GetOSTargetDriveLetterEx = left(oEnvironment.Item("DestinationOSDriveLetter") ,1) & ":"
  3634.  
  3635.  
  3636.             ElseIf ucase(oEnvironment.Item("DestinationOSInstallType")) = "BYVARIABLE" and oEnvironment.IndirectItem("DestinationOSVariable") <> "" then
  3637.  
  3638.                 oLogging.CreateEntry "Found: DestinationOSVariable: " & oEnvironment.IndirectItem("DestinationOSVariable"), LogTypeInfo
  3639.                 GetOSTargetDriveLetterEx = left(oEnvironment.IndirectItem("DestinationOSVariable") ,2)
  3640.  
  3641.  
  3642.             Elseif bDiskPartFound then
  3643.  
  3644.                 ' Uses functions within ztidiskutility.vbs
  3645.  
  3646.                 If ucase(oEnvironment.Item("DestinationOSInstallType")) = "NEXTPARTITION" then
  3647.  
  3648.                     oLogging.CreateEntry "Found: DestinationOSInstallType = NEXTPARTITION ", LogTypeInfo
  3649.                     GetOSTargetDriveLetterEx = left(GetFirstPossibleSystemDrive,2)
  3650.  
  3651.                 ElseIf (ucase(oEnvironment.Item("DestinationOSInstallType")) = "BYDISKPARTITION" or oEnvironment.Item("DestinationOSInstallType") = "" ) and isnumeric(oEnvironment.Item("DestinationDisk")) and isnumeric(oEnvironment.Item("DestinationPartition")) then
  3652.  
  3653.                     oLogging.CreateEntry "DestinationOSInstallType = BYDISKPARTITION", LogTypeInfo
  3654.                     oLogging.CreateEntry "Found: DestinationDisk: " & oEnvironment.Item("DestinationDisk"), LogTypeInfo
  3655.                     oLogging.CreateEntry "Found: DestinationPartition: " & oEnvironment.Item("DestinationPartition"), LogTypeInfo
  3656.  
  3657.                     set oDiskPart = new ZTIDiskPartition
  3658.                     oDiskPart.SetDiskPart oEnvironment.Item("DestinationDisk"), oEnvironment.Item("DestinationPartition")
  3659.                     If isEmpty( oDiskPart.oWMIDiskPart ) then
  3660.                         oLogging.CreateEntry "No partition Found!", logTypeInfo
  3661.                     ElseIf IsEmpty(oDiskPart.Drive) then
  3662.                         oLogging.CreateEntry "No drive mapped to Disk Partition: " & oDIskPart.oWMIDiskPart.Path_, logTypeInfo
  3663.                     Else
  3664.                         oLogging.CreateEntry "Disk Size : " & FormatLargeSize( oDiskPart.oWMIDiskPart.Size ), logTypeInfo
  3665.                         oLogging.CreateEntry "Min Size : " &  FormatLargeSize(GetMinimumDiskPartitionSizeMB * 1000 * 1000) , logTypeInfo
  3666.  
  3667.                         If (oDiskPart.oWMIDiskPart.Size /1000 /1000) < (GetMinimumDiskPartitionSizeMB) and 1 = cint(oEnvironment.Item("DestinationPartition")) then
  3668.                             oLogging.CreateEntry "Partition is set too small, assume BDEPartition and recover.", logTypeInfo
  3669.  
  3670.                             set oDiskPart = new ZTIDiskPartition
  3671.                             oDiskPart.SetDiskPart oEnvironment.Item("DestinationDisk"), 2
  3672.                             If isEmpty( oDiskPart.oWMIDiskPart ) then
  3673.                                 oLogging.CreateEntry "No partition Found!", logTypeInfo
  3674.                             ElseIf IsEmpty(oDiskPart.Drive) then
  3675.                                 oLogging.CreateEntry "No drive mapped to Disk Partition: " & oDIskPart.oWMIDiskPart.Path_, logTypeInfo
  3676.                             Else
  3677.                                 oLogging.CreateEntry "Disk Size : " & FormatLargeSize( oDiskPart.oWMIDiskPart.Size ), logTypeInfo
  3678.                                 oLogging.CreateEntry "Min Size : " &  FormatLargeSize(GetMinimumDiskPartitionSizeMB * 1000 * 1000) , logTypeInfo
  3679.  
  3680.                                 If (oDiskPart.oWMIDiskPart.Size /1000 /1000) > (GetMinimumDiskPartitionSizeMB) then
  3681.                                     GetOSTargetDriveLetterEx = left(oDiskPart.Drive,2)
  3682.                                     oEnvironment.Item("DestinationPartition") = "2"
  3683.                                 End if
  3684.                             End if
  3685.  
  3686.                         Else
  3687.                             GetOSTargetDriveLetterEx = left(oDiskPart.Drive,2)
  3688.                         End if
  3689.                     End if
  3690.  
  3691.                 End if
  3692.  
  3693.                 If isempty(GetOSTargetDriveLetterEx) then
  3694.  
  3695.                     oLogging.CreateEntry "Unable to yield a target Partition (Special Recovery option for Litetouch).", logTypeInfo
  3696.                     If AllDiskDrives.Count = 1 then
  3697.                         oLogging.CreateEntry "There is only one disk, so assume that this is the Destination disk.", logTypeInfo
  3698.                         GetOSTargetDriveLetterEx = left(GetFirstPossibleSystemDrive,2)
  3699.                     End if
  3700.  
  3701.                 End if
  3702.  
  3703.             End if
  3704.  
  3705.  
  3706.         Else
  3707.        
  3708.             '
  3709.             '  SCCM Scenarios:
  3710.             '
  3711.  
  3712.             If oEnvironment.Item("_SMSTSMediaType") = "OEMMedia" and oEnvironment.Item("OSDUseAlreadyDeployedImage") = "TRUE" then
  3713.  
  3714.                 oLogging.CreateEntry "Prestaged media deployment, use data path drive.", LogTypeInfo
  3715.                 GetOSTargetDriveLetterEx = Left(oEnvironment.Item("_SMSTSMDataPath"), 2)
  3716.  
  3717.             ElseIf  oEnvironment.Item("OSDTargetDrive") <> "" Then
  3718.  
  3719.                 oLogging.CreateEntry "OSDTargetDrive is set, find disk: " &  oEnvironment.Item("OSDTargetDrive"), logTypeInfo
  3720.                 GetOSTargetDriveLetterEx = Left(oEnvironment.Item("OSDTargetDrive"), 2)
  3721.  
  3722.  
  3723.             ElseIf oEnvironment.Item("OSDisk") <> "" Then
  3724.  
  3725.                 oLogging.CreateEntry "OSDisk is set, find disk: " &  oEnvironment.Item("OSDisk"), logTypeInfo
  3726.                 GetOSTargetDriveLetterEx = Left(oEnvironment.Item("OSDisk") ,2)
  3727.  
  3728.  
  3729.             ElseIf oEnvironment.Item("OSDTemporaryDrive") <> "" Then
  3730.  
  3731.                 oLogging.CreateEntry "OSDTemporaryDiskDrive is set. Most likely a early setup scenario.", logTypeInfo
  3732.                 GetOSTargetDriveLetterEx = Left(oEnvironment.Item("OSDTemporaryDrive"), 2)
  3733.  
  3734.                 ' Hard Exit
  3735.                 Exit function
  3736.  
  3737.             End if
  3738.  
  3739.  
  3740.         End if
  3741.  
  3742.  
  3743.         If IsEmpty(GetOSTargetDriveLetterEx) then
  3744.  
  3745.             oLogging.CreateEntry "DestinationDisk and Partition did not yield a target Partition.", logTypeInfo
  3746.             If bRequired then
  3747.                 oLogging.ReportFailure "Unable to determine Destination Disk, Partition, and/or Drive. See BDD.LOG for more information.", 5456
  3748.             End if
  3749.  
  3750.         Else
  3751.  
  3752.             ' Cache the Deployment drive if found
  3753.             oEnvironment.Item("OSDTargetDriveCache") = GetOSTargetDriveLetterEx
  3754.             oEnvironment.Item("OSDisk") = GetOSTargetDriveLetterEx
  3755.  
  3756.             ' Cache the Partition if not set already.
  3757.             If oEnvironment.Item("TargetPartitionIdentifier") = "" then
  3758.                 SetTagForDrive left(GetOSTargetDriveLetterEx,2), "TargetPartitionIdentifier"
  3759.             End if
  3760.  
  3761.             oLogging.CreateEntry "Found GetOSTargetDriveLetterEx: " & GetOSTargetDriveLetterEx, logTypeVerbose
  3762.  
  3763.         End if
  3764.  
  3765.  
  3766.     End function
  3767.  
  3768.  
  3769.     Function DeterminePartition
  3770.         oLogging.CreateEntry "DeterminePartition is deprecated.", logTypeDeprecated
  3771.         If true then
  3772.             DeterminePartition = false
  3773.         Else
  3774.             ' Legacy solution
  3775.             ReCalculateDestinationDiskAndPartition (true)
  3776.             DeterminePartition = true
  3777.         End if
  3778.     End function
  3779.  
  3780.     Function ReCalculateDestinationDiskAndPartition ( bRequired )
  3781.  
  3782.         Dim sDriveLetter
  3783.         Dim oDiskPart
  3784.         Dim bDiskPartFound
  3785.  
  3786.         ' We may wish to use some advanced Disk Partitioning Routines from ZTIDIskPart.vbs. Check availabiltiy.
  3787.         On error resume next
  3788.         bDiskPartFound = false
  3789.         bDiskPartFound = not isempty(ZTIDiskPart_Script)
  3790.         on error goto 0
  3791.  
  3792.         sDriveLetter = GetOSTargetDriveLetterEx(bRequired)
  3793.  
  3794.         If bRequired then
  3795.             TestAndFail bDiskPartFound , 5452, "Verify ZTIDiskPArt is loaded"
  3796.             set oDiskPart = new ZTIDiskPartition
  3797.             oDiskPart.Drive = sDriveLetter
  3798.             TestAndFail not isEmpty(oDiskPart.Drive),5451, "Verify oDiskPart.Drive is found!"
  3799.             oEnvironment.Item("DestinationDisk") = oDiskPart.Disk
  3800.             oEnvironment.Item("DestinationPartition") = oDiskPart.Partition
  3801.         ElseIf bDiskPartFound then
  3802.             set oDiskPart = new ZTIDiskPartition
  3803.             oDiskPart.Drive = sDriveLetter
  3804.             If not isEmpty(oDiskPart.Drive) then
  3805.                 oEnvironment.Item("DestinationDisk") = oDiskPart.Disk
  3806.                 oEnvironment.Item("DestinationPartition") = oDiskPart.Partition
  3807.             Else
  3808.                 oLogging.CreateEntry "Drive not found: " & sDriveLetter, LogTypeINfo
  3809.             End if
  3810.         Else
  3811.             oLogging.CreateEntry "ZTIDiskPart_Script not found ", LogTypeINfo
  3812.         End if
  3813.  
  3814.     End function
  3815.  
  3816.     Function GetOSTargetDriveLetter
  3817.  
  3818.         GetOSTargetDriveLetter = GetOSTargetDriveLetterEx(true)
  3819.  
  3820.     End function
  3821.  
  3822.  
  3823.     Function SelectSingleNodeString( oXMLDomNode, sXPath )
  3824.         SelectSingleNodeString = SelectSingleNodeStringEx(oXMLDomNode, sXPath, True )
  3825.     End function
  3826.  
  3827.     Function SelectSingleNodeStringEx( oXMLDomNode, sXPath, bError )
  3828.  
  3829.         If bError then
  3830.             'TestAndLog not oXMLDomNode is nothing, "verify oXMLDomNode is object."
  3831.         End if
  3832.         If not oXMLDomNode.SelectSingleNode(sXPath) is nothing then
  3833.             SelectSingleNodeStringEx = oXMLDomNode.SelectSingleNode(sXPath).Text
  3834.         Else
  3835.             If bError then
  3836.                 oLogging.CreateEntry "SelectSingleNodeString(" & sXPath & ") Missing Node.", LogTypeWarning
  3837.             End if
  3838.             SelectSingleNodeStringEx = ""
  3839.         End if
  3840.  
  3841.     End function
  3842.  
  3843.     Function SelectNodesSafe ( oXMLDomNode, sXPath )
  3844.         set SelectNodesSafe = SelectNodesSafeEx ( oXMLDomNode, sXPath, True )
  3845.     End function
  3846.  
  3847.     Function SelectNodesSafeEx ( oXMLDomNode, sXPath, bError )
  3848.  
  3849.         If bError then
  3850.             'TestAndLog not oXMLDomNode is nothing, "verify oXMLDomNode is object."
  3851.         End if
  3852.         set SelectNodesSafeEx = oXMLDomNode.SelectNodes(sXPath)
  3853.         If SelectNodesSafeEx is nothing then
  3854.             If bError then
  3855.                 oLogging.CreateEntry "SelectNodesSafeEx(" & sXPath & ") Missing Node.", LogTypeWarning
  3856.             End if
  3857.             set SelectNodesSafeEx = CreateObject("Scripting.Dictionary")  ' Empty object
  3858.         End if
  3859.  
  3860.     End function
  3861.  
  3862.     Function FindSysprepAnswerFile
  3863.        
  3864.         Dim sSysprepInf
  3865.         Dim sBuildPath
  3866.         Dim iRetVal
  3867.         Dim sBootDrive
  3868.        
  3869.         iRetVal = SUCCESS
  3870.         If oEnvironment.Item("TaskSequenceID") = "" Then
  3871.             oLogging.CreateEntry "The TaskSequenceID is blank, possibly a misconfigured customsettings.ini or task sequence",LogTypeWarning
  3872.         End If
  3873.  
  3874.         sBuildPath = oEnvironment.Item("DeployRoot") & "\Control\" & oEnvironment.Item("TaskSequenceID")
  3875.         If not oFSO.FolderExists(sBuildPath) then
  3876.             sBuildPath = oEnvironment.Item("DeployRoot")
  3877.  
  3878.         End if
  3879.  
  3880.         sBootDrive = oUtility.GetOSTargetDriveLetterEx(false)
  3881.         if sBootDrive = "" then
  3882.             oLogging.CreateEntry "Destination Logical Drive was not specificed, defaulting to #:\", LogTypeInfo
  3883.             sBootDrive = "#:"  ' Unknown Boot Drive
  3884.         End if
  3885.  
  3886.  
  3887.         oLogging.CreateEntry "Looking for Sysprep.inf in " & sBootDrive & "\sysprep\Sysprep.inf", LogTypeInfo
  3888.        
  3889.         If oFSO.FileExists(oEnvironment.Item("OSDAnswerFilePathSysprep")) Then
  3890.                
  3891.             FindSysprepAnswerFile = iRetVal
  3892.             Exit Function
  3893.        
  3894.         ElseIf oFSO.FileExists(sBootDrive & "\sysprep\Sysprep.inf") then
  3895.  
  3896.             sSysprepInf = sBootDrive & "\sysprep\Sysprep.inf"
  3897.             oLogging.CreateEntry "Found Sysprep.inf at " & sSysprepInf & ".", LogTypeInfo
  3898.  
  3899.         ElseIf oFSO.FileExists("x:\sysprep\Sysprep.inf") then
  3900.  
  3901.             sSysprepInf = "x:\sysprep\Sysprep.inf"
  3902.             oLogging.CreateEntry "Found Sysprep.inf at " & sSysprepInf & ".", LogTypeInfo
  3903.  
  3904.         ElseIf oFSO.FileExists(sBuildPath & "\Sysprep.inf") then
  3905.  
  3906.             ' Copy it locally
  3907.  
  3908.             sSysprepInf = sBootDrive & "\sysprep\Sysprep.inf"
  3909.             oLogging.CreateEntry "Found Sysprep.inf at " & sBuildPath & "\Sysprep.inf, will copy to " & sSysprepInf, LogTypeInfo
  3910.  
  3911.             If not oFSO.FolderExists(sBootDrive & "\Sysprep") then
  3912.                 oFSO.CreateFolder sBootDrive & "\Sysprep"
  3913.             End if
  3914.  
  3915.             oFSO.CopyFile sBuildPath & "\Sysprep.inf", sSysprepInf
  3916.             oFSO.GetFile(sSysprepInf).Attributes = 0
  3917.             oLogging.CreateEntry "Copied " & sBuildPath & "\Sysprep.inf to " & sBootDrive & "\sysprep", LogTypeInfo
  3918.         ElseIf oEnvironment.Item("OSDTargetSystemDrive")<> "" and oFSO.FileExists(oEnvironment.Item("OSDTargetSystemDrive") & "\sysprep\sysprep.inf") then
  3919.            
  3920.             sSysprepInf = oEnvironment.Item("OSDTargetSystemDrive") & "\sysprep\sysprep.inf"
  3921.             oLogging.CreateEntry "Found Sysprep.inf at " & sSysprepInf & ".", LogTypeInfo
  3922.  
  3923.         Else
  3924.             oLogging.CreateEntry "The sysprep.inf file was not found.", LogTypeInfo
  3925.         End if
  3926.        
  3927.         oEnvironment.Item("OSDAnswerFilePathSysprep") = sSysprepInf
  3928.        
  3929.         FindSysprepAnswerFile = iRetVal
  3930.  
  3931.    
  3932.     End Function
  3933.    
  3934.     Function FindUnattendAnswerFile
  3935.        
  3936.         Dim sUnattendXML, sUnattendTxt
  3937.         Dim sBuildPath
  3938.         Dim iRetVal
  3939.        
  3940.         iRetVal = SUCCESS
  3941.         If oEnvironment.Item("TaskSequenceID") = "" Then
  3942.             oLogging.CreateEntry "The TaskSequenceID is blank, possibly a misconfigured customsettings.ini or task sequence",LogTypeWarning
  3943.         End If
  3944.  
  3945.         sBuildPath = oEnvironment.Item("DeployRoot") & "\Control\" & oEnvironment.Item("TaskSequenceID")
  3946.         If not oFSO.FolderExists(sBuildPath) then
  3947.             sBuildPath = oEnvironment.Item("DeployRoot")
  3948.  
  3949.         End if
  3950.  
  3951.         If oFSO.FileExists(sBuildPath & "\Unattend.txt") then
  3952.  
  3953.             ' Copy it locally
  3954.  
  3955.             sUnattendTxt = oUtility.LocalRootPath & "\unattend.txt"
  3956.             oLogging.CreateEntry "Found Unattend.txt at " & sBuildPath & "\Unattend.txt, will copy to " & sUnattendTxt, LogTypeInfo
  3957.  
  3958.             oFSO.CopyFile sBuildPath & "\Unattend.txt", sUnattendTxt, true
  3959.             oFSO.GetFile(sUnattendTxt).Attributes = 0
  3960.             oLogging.CreateEntry "Copied " & sBuildPath & "\Unattend.txt to " & sUnattendTxt, LogTypeInfo
  3961.  
  3962.         ElseIf oFso.FileExists(oEnvironment.Item("OSDAnswerFilePath")) and Instr(1,oEnvironment.Item("OSDAnswerFilePath"),".txt",vbTextCompare) > 0 then
  3963.             sUnattendTxt = oEnvironment.Item("OSDAnswerFilePath")
  3964.             oLogging.CreateEntry "Found unattend.txt at " & sUnattendTxt,LogTypeInfo
  3965.         Else
  3966.             oLogging.CreateEntry "The unattend.txt file was not found.", LogTypeInfo
  3967.         End if
  3968.  
  3969.  
  3970.         ' First see if there is already a local unattend.xml.  If not, copy one.
  3971.  
  3972.        
  3973.         If oFSO.FileExists(Left(oUtility.LocalRootPath, 2) & "\Windows\Panther\unattend\unattend.xml") then
  3974.  
  3975.            
  3976.             sUnattendXml = Left(oUtility.LocalRootPath, 2) & "\Windows\Panther\unattend\unattend.xml"
  3977.             oLogging.CreateEntry "Found existing unattend.xml at " & sUnattendXml, LogTypeInfo
  3978.  
  3979.         ElseIf oFSO.FileExists(oUtility.LocalRootPath & "\unattend.xml") then
  3980.  
  3981.            
  3982.             sUnattendXml = oUtility.LocalRootPath & "\unattend.xml"
  3983.             oLogging.CreateEntry "Found existing unattend.xml at " & sUnattendXml, LogTypeInfo
  3984.  
  3985.         ElseIf oFSO.FileExists(sBuildPath & "\Unattend.xml") then
  3986.            
  3987.             sUnattendXml = oUtility.LocalRootPath & "\Unattend.xml"
  3988.  
  3989.             oLogging.CreateEntry "Found unattend.xml at " & sBuildPath & "\Unattend.xml, will copy to " & sUnattendXml, LogTypeInfo
  3990.             oFSO.CopyFile sBuildPath & "\Unattend.xml", sUnattendXml, true
  3991.             oLogging.CreateEntry "Copied " & sBuildPath & "\Unattend.xml to " & sUnattendXml, LogTypeInfo
  3992.             oFSO.GetFile(sUnattendXml).Attributes = 0
  3993.  
  3994.         ElseIf oFso.FileExists(oEnvironment.Item("OSDAnswerFilePath")) and Instr(1,oEnvironment.Item("OSDAnswerFilePath"),".xml",vbTextCompare) >0 then
  3995.  
  3996.             sUnattendXML= oEnvironment.Item("OSDAnswerFilePath")
  3997.             oLogging.CreateEntry "Found existing unattend.xml at " & sUnattendXml, LogTypeInfo
  3998.  
  3999.         Else
  4000.  
  4001.             sUnattendXml = ""
  4002.             oLogging.CreateEntry "File " & sBuildPath & "\Unattend.xml does not exist, unable to copy", LogTypeInfo
  4003.  
  4004.         End if
  4005.        
  4006.         If sUnattendTxt <> "" AND sUnattendXML <> "" Then
  4007.             oLogging.CreateEntry "Found an unattend.xml and an unattend.txt file, Invalid configuration", LogTypeError
  4008.             iRetVal = FAILURE
  4009.             FindUnattendAnswerFile = iRetVal
  4010.             Exit Function
  4011.         ElseIf sUnattendTxt <> "" AND sUnattendXML = "" Then
  4012.             oEnvironment.Item("OSDAnswerFilePath") = sUnattendTxt
  4013.         ElseIF sUnattendXML <> "" AND sUnattendTxt = "" Then
  4014.             oEnvironment.Item("OSDAnswerFilePath") = sUnattendXML
  4015.         Else
  4016.             oLogging.CreateEntry "No answer file could be found",LogTypeWarning
  4017.         End If
  4018.        
  4019.         FindUnattendAnswerFile = iRetVal
  4020.        
  4021.    
  4022.     End Function
  4023.    
  4024.     Function IsHighEndSKUEx( sSKU )
  4025.    
  4026.         ' Windows Ultimate/Enterprise and Server SKU's allow for some
  4027.         ' higher-end features, like Bitlocker and Multiple Language Packs.
  4028.        
  4029.         select case (ucase(trim(sSKU)))
  4030.             case "ULTIMATE", "ULTIMATEE", "ULTIMATEN"
  4031.                 IsHighEndSKUEx = TRUE
  4032.             case "ENTERPRISE", "ENTERPRISEN", "ENTERPRISES", "ENTERPRISESN"
  4033.                 IsHighEndSKUEx = TRUE
  4034.             case "PROFESSIONAL", "PROFESSIONALN"
  4035.                 IsHighEndSKUEx = TRUE
  4036.             case "EDUCATION", "EDUCATIONN"
  4037.                 IsHighEndSKUEx = TRUE
  4038.             case "HYPERV"
  4039.                 IsHighEndSKUEx = TRUE
  4040.             case "PRERELEASE"
  4041.                 IsHighEndSKUEx = TRUE
  4042.             case else
  4043.                 If Instr(1, ucase(trim(sSKU)), "SERVER", vbTextCompare) > 0 then
  4044.                     IsHighEndSKUEx = TRUE
  4045.                 Else
  4046.                     IsHighEndSKUEx = FALSE
  4047.                 End if
  4048.         End Select
  4049.        
  4050.     End function
  4051.    
  4052.     Function IsHighEndSKU
  4053.         TestAndLog oEnvironment.Item("OSSKU") <> "", "Verify %OSSKU% is defined."
  4054.         IsHighEndSKU = IsHighEndSKUEx( oEnvironment.Item("OSSKU") )
  4055.     End function
  4056.  
  4057.  
  4058.     Function InternetFileDownload(sInternetURL, sDest)
  4059.         Dim oInternetBuffer
  4060.         Dim oADODB
  4061.  
  4062.         ' Assume failure
  4063.  
  4064.         InternetFileDownload = false
  4065.  
  4066.  
  4067.         ' Create the web request using ADO
  4068.  
  4069.         Set oADODB = CreateObject("ADODB.Stream")
  4070.         Set oInternetBuffer = CreateObject("Msxml2.XmlHttp")
  4071.         oInternetBuffer.open "GET", sInternetURL, false
  4072.         On Error Resume Next
  4073.         oInternetBuffer.send ""
  4074.         On Error Goto 0
  4075.  
  4076.  
  4077.         ' Check that the request is completed (ReadyState=4).  If it isn't, log it as a warning (will likely fail below
  4078.         ' because the status won't be 200).
  4079.  
  4080.         If oInternetBuffer.ReadyState = 4 then
  4081.             oLogging.CreateEntry "Status: " & oInternetBuffer.Status & " " & sInternetURL, LogTypeInfo
  4082.         Else
  4083.             oLogging.CreateEntry "Ready State : " & oInternetBuffer.ReadyState & " " & sInternetURL, LogTypeWarning
  4084.         End if
  4085.  
  4086.  
  4087.         ' If the status indicates a successful download, save the file to the specified path
  4088.  
  4089.         If oInternetBuffer.Status = 200 then
  4090.             If oADODB.State <> 0 then ADODB.Close
  4091.             oADODB.Type = 1 '(1=binary,2=Text)
  4092.             oADODB.Mode = 3 '(1=Read,2=Write,3=RW)
  4093.             oADODB.Open
  4094.             oADODB.Write oInternetBuffer.ResponseBody
  4095.             oADODB.SaveToFile sDest, 2
  4096.             oADODB.Close
  4097.  
  4098.             InternetFileDownload = True
  4099.         End if
  4100.  
  4101.     End function
  4102.  
  4103. End Class
  4104.  
  4105.  
  4106. '
  4107. '  Common String Processing Routines
  4108. '
  4109. Class Strings
  4110.  
  4111.  
  4112.     Function isNullOrEmpty( sString )
  4113.  
  4114.         isNullOrEmpty = false
  4115.         If isEmpty(sString) or isNull(sString) then
  4116.             isNullOrEmpty = True
  4117.         ElseIf VarType(sString) = 8 then
  4118.             isNullOrEmpty = (sString = "")
  4119.         End if
  4120.  
  4121.     End function
  4122.  
  4123.     ' Create a delimited list of items.
  4124.     Sub AddToList(byref List, Item, Delimiter)  
  4125.         if isempty(list) then
  4126.             List = cstr(item)
  4127.         else
  4128.             list = list & delimiter & cstr(Item)
  4129.         end if
  4130.     end Sub
  4131.  
  4132.     ' Display a Hex value with width
  4133.     Function HexWidth ( Value, Width  )
  4134.         HexWidth = right( "00000000" & hex ( value  ), Width)
  4135.     end Function
  4136.  
  4137.     ' Display a Hex value with width
  4138.     Function HexWidthByte ( Value, Width  )
  4139.         HexWidthByte = right( "00000000" & hex ( ascb( value  ) ), Width )
  4140.     end Function
  4141.  
  4142.     Function IsWhiteSpace (MyChar)
  4143.         ' Whitespace defined as vtTab[9], vbLF[10], vbVerticalTab[11], vbFormFeed[12], vbCr[13]
  4144.         IsWhiteSpace = MyChar = " " or ( MyChar >= chr(9) and MyChar <= chr(13) ) or MyChar = chr(160)
  4145.         end Function
  4146.  
  4147.     Function TrimAllWS( MyString )
  4148.         TrimAllWS = MyString
  4149.         While len(TrimAllWS) > 0 and IsWhiteSpace(left(TrimAllWS,1))
  4150.             TrimAllWS = Mid(TrimAllWS,2)
  4151.         wend
  4152.         While len(TrimAllWS) > 0 and IsWhiteSpace(right(TrimAllWS,1))
  4153.             TrimAllWS = Mid(TrimAllWS,1,len(TrimAllWS)-1)
  4154.         wend  
  4155.     end Function
  4156.  
  4157.     Function RightAlign( MyString, Width )
  4158.         RightAlign = Right( Space(Width) & MyString, Width )
  4159.     end Function
  4160.  
  4161.     Function LeftAlign( MyString, Width )
  4162.         LeftAlign = Left( MyString & Space(Width), Width )
  4163.     end Function
  4164.  
  4165.     '
  4166.     ' Force a value to a string format.
  4167.     '   Non-printable types will return empty.
  4168.     '
  4169.     Function ForceAsString ( InputVar )
  4170.         dim InputType, Item
  4171.        
  4172.         InputType = VarType(InputVar)
  4173.  
  4174.         if isObject(InputVar) or isNull(InputVar) or isEmpty(InputVar) then
  4175.             ForceAsString = ""
  4176.        
  4177.         elseif InputType = vbError or InputType = vbVariant or InputType = vbDataObject then
  4178.             ForceAsString = ""
  4179.            
  4180.         elseif InputType = ( vbArray or vbByte ) then
  4181.             for item = 1 to LenB( InputVar )
  4182.                 AddToList ForceAsString, ForceAsString( HexWidthByte(midb(InputVar,Item,1),2) ), ""
  4183.             next
  4184.  
  4185.         elseif isArray(InputVar) then
  4186.             for each item in InputVar        
  4187.                 AddToList ForceAsString, ForceAsString(Item), " "   ' recurse
  4188.             next    
  4189.            
  4190.         elseif InputType = vbByte then
  4191.             ForceAsString = HexWidthByte(InputVar,2)
  4192.            
  4193.         else
  4194.             ForceAsString = cstr(InputVar)
  4195.            
  4196.         end if
  4197.     end Function
  4198.  
  4199.     '
  4200.     ' Given a variant, will ensure the Function returns an array
  4201.     '
  4202.     ' Parameters:
  4203.     '   InputVar - Variable to convert to an array
  4204.     '   sDelimiter - OPTIONAL delimiter to force spliting in the array
  4205.     '       If sDelimiter is empty or blank, Function will return an array of 1 element.
  4206.     ' Notes
  4207.  
  4208.     Function ForceAsArray( InputVar, sDelimiter )
  4209.         dim i
  4210.  
  4211.         if isArray(InputVar) then        
  4212.             ForceAsArray = InputVar
  4213.            
  4214.         elseif VarType(InputVar) = vbObject then
  4215.             redim newarray(InputVar.Count-1)
  4216.             for i = 0 to InputVar.Count-1
  4217.                 newarray(i) = InputVar(i)        
  4218.             next
  4219.             ForceAsArray = NewArray
  4220.            
  4221.         elseif VarType(InputVar) = vbString and VarType(sDelimiter) = vbString then
  4222.             ForceAsArray = split(InputVar,sDelimiter, -1, vbTextCompare )
  4223.            
  4224.         else
  4225.             ForceAsArray = array(InputVar)
  4226.            
  4227.         end if
  4228.  
  4229.     end Function
  4230.    
  4231.    
  4232.     Function GenerateRandomGUID
  4233.         GenerateRandomGUID = left( CreateObject("Scriptlet.TypeLib").GUID, 38 )
  4234.     end Function
  4235.    
  4236.     ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  4237.     '
  4238.     '  Base64 Functions
  4239.     '
  4240.  
  4241.     Function BASE64_TABLE
  4242.         BASE64_TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
  4243.     End function
  4244.  
  4245.     Function SafeAsc ( sPlainText, pos )
  4246.         if VarType(sPlainText) = (vbArray or vbByte) then
  4247.             SafeAsc =  cint(midb(sPlainText, pos + 1 , 1))
  4248.         elseif (pos + 1) <= len(sPlainText) then
  4249.             SafeAsc = asc(mid(sPlainText, pos + 1, 1))
  4250.         else
  4251.             SafeAsc = 0
  4252.         end if
  4253.     End Function
  4254.  
  4255.     Function SafeEnc( n, x )
  4256.         SafeEnc = mid(BASE64_TABLE, ((n\(2^x)) and 63) + 1,1)
  4257.     End Function
  4258.  
  4259.     Function base64Encode( sPlainText )
  4260.         Dim i, n
  4261.  
  4262.         if 0 < len(sPlainText) then
  4263.             for i = 0 to len(sPlainText) - 1 step 3
  4264.                 ' Add a new line ...
  4265.                 if i > 0  and i mod 57  = 0 then
  4266.                     base64Encode = base64Encode & vbNewLine
  4267.                 end if
  4268.                 ' three 8-bit characters become one 24-bit number
  4269.                 n = (SafeAsc(sPlainText,i)*&h10000 + SafeAsc(sPlainText,i+1)*&h100 + SafeAsc(sPlainText,i+2))
  4270.  
  4271.                 ' the 24-bit number becomes four 6-bit numbers
  4272.                 base64Encode = base64Encode & SafeEnc( n, 18 ) & SafeEnc( n, 12 ) & SafeEnc( n, 6 ) & SafeEnc( n, 0 )
  4273.             next
  4274.         end if
  4275.  
  4276.         ' Pad Text at End of String
  4277.         n = (3-(len(sPlainText)mod 3)) mod 3
  4278.         base64Encode = left ( base64Encode, len(base64Encode) - n ) + string( n, "=" )
  4279.  
  4280.     End Function
  4281.  
  4282.     Function SafeDecode( s, i, x )
  4283.         SafeDecode = ( InStr(1, BASE64_TABLE, mid(s,i,1), vbBinaryCompare) - 1) * (2 ^ x)
  4284.     End Function
  4285.  
  4286.     Function base64Decode( sEncodedText )
  4287.  
  4288.         Dim sEncText
  4289.         Dim regex
  4290.         Dim p, i, n
  4291.  
  4292.         ' Remove all non base64 text
  4293.         set regex = new RegExp
  4294.  
  4295.  
  4296.         regex.pattern = "[^=" & BASE64_TABLE & "]"
  4297.         regex.global = true
  4298.  
  4299.         sEncText = regex.Replace(sEncodedText,"")
  4300.         sEncText = replace( sEncText, vbLF, "")
  4301.         sEncText = replace( sEncText, vbCR, "")
  4302.  
  4303.         ' Verify String is in Base64 format (multiple of 4 chars)
  4304.         if len(sEncText) mod 4 <> 0 then
  4305.             oLogging.CreateEntry "Variable is not a valid string (not Base64 Format)", LogTypeInfo
  4306.             base64Decode = ""          
  4307.             exit function
  4308.         end if
  4309.  
  4310.         if right(sEncText,2) = "==" then
  4311.             p = 2
  4312.         elseif right(sEncText,1) = "=" then
  4313.             p = 1
  4314.         end if
  4315.         sEncText = left(sEncText,len(sEncText)-p) & string(p,"A")
  4316.  
  4317.         for i = 1 to len(sEncText) step 4
  4318.             ' Convert four 6-bit numbers into one 24 bit value
  4319.             n = SafeDecode(sEncText,i+3,0) + SafeDecode(sEncText,i+2,6) + SafeDecode(sEncText,i+1,12) + SafeDecode(sEncText,i+0,18)
  4320.  
  4321.             ' Convert the 24-bit value back into three 8-bit values.
  4322.             base64Decode = base64Decode & chr( (n \ (2^16)) and 255 ) & chr( (n \ (2^8)) and 255 ) & chr( n and 255 )
  4323.  
  4324.         next
  4325.  
  4326.         ' Trim off any excess space.
  4327.         base64Decode = left(base64Decode,len(base64Decode)-p)
  4328.     End Function
  4329.  
  4330.  
  4331.  
  4332. End Class
  4333.  
  4334.  
  4335. Class FileHandling
  4336.  
  4337.  
  4338.     Function RemoveFolder(sPath)
  4339.         RemoveFolder = RemoveFolderEx (sPath, TRUE)
  4340.     End Function
  4341.    
  4342.     Function RemoveFolderEx(sPath, bLogging )
  4343.  
  4344.         Dim oFile, oFolder
  4345.  
  4346.         If bLogging then
  4347.             oLogging.CreateEntry "Remove Folder: " & sPath, LogTypeInfo
  4348.         End if
  4349.  
  4350.         ' Make sure the folder exists
  4351.  
  4352.         If not oFSO.FolderExists(sPath) then
  4353.             Exit Function
  4354.         End if
  4355.  
  4356.  
  4357.         ' First try to remove any files
  4358.         on error resume next
  4359.         For each oFile in oFSO.GetFolder(sPath).Files
  4360.             DeleteFileEx oFile.Path, bLogging
  4361.         Next
  4362.         On Error Goto 0
  4363.  
  4364.         ' Then take care of subfolders
  4365.         on error resume next
  4366.         For each oFolder in oFSO.GetFolder(sPath).Subfolders
  4367.             RemoveFolderEx oFolder.Path, bLogging
  4368.         Next
  4369.         On Error Goto 0
  4370.  
  4371.         ' Now try to remove the folder
  4372.         On Error Resume Next
  4373.         oFSO.DeleteFolder sPath, true
  4374.         If bLogging then
  4375.             TestAndLog Err = 0, "Delete Folder: " & sPath
  4376.         End if
  4377.         RemoveFolderEx = Err
  4378.         Err.Clear
  4379.         On Error Goto 0
  4380.  
  4381.     End Function
  4382.    
  4383.     Function DeleteFile(sFile)
  4384.         DeleteFile = DeleteFileEx ( sFile, TRUE )
  4385.     End function
  4386.    
  4387.     Function DeleteFileEx(sFile, bLogging)
  4388.    
  4389.         If bLogging then
  4390.             oLogging.CreateEntry "Delete File: " & sFile, LogTypeInfo
  4391.         End if
  4392.         On Error Resume Next
  4393.         oFSO.DeleteFile sFile, TRUE
  4394.         If bLogging then
  4395.             TestAndLog Err = 0, "Delete File: " & sFile
  4396.         End if
  4397.         DeleteFileEx = Err
  4398.         Err.Clear
  4399.         On Error Goto 0
  4400.        
  4401.     End function
  4402.    
  4403.     Function MoveFile(sFile,sDest)
  4404.         MoveFile = MoveFileEx(sFile,sDest,True)
  4405.     End function
  4406.    
  4407.     Function MoveFileEx(sFile,sDest,bLogging)
  4408.    
  4409.         If bLogging then
  4410.             oLogging.CreateEntry "Move File: " & sFile & " to " & sDest , LogTypeInfo
  4411.         End if
  4412.         On Error Resume Next
  4413.         oFSO.MoveFile sFile, sDest
  4414.         If bLogging then
  4415.             TestAndLog Err = 0, "Move File: " & sFile & " to " & sDest     
  4416.         End if
  4417.         MoveFileEx = Err
  4418.         Err.Clear
  4419.         On Error Goto 0
  4420.        
  4421.     End function
  4422.    
  4423.     Function CopyFile(sFile,sDest, bOverwrite)
  4424.         CopyFile = CopyFileEx(sFile,sDest, bOverwrite,True)
  4425.     End function
  4426.  
  4427.     Function CopyFileEx(sFile,sDest, bOverwrite,bLogging)
  4428.    
  4429.         If bLogging then
  4430.             oLogging.CreateEntry "Copy File: " & sFile & " to " & sDest , LogTypeInfo
  4431.         End if
  4432.         On Error Resume Next
  4433.         oFSO.CopyFile sFile, sDest, bOverwrite
  4434.         If bLogging then
  4435.             TestAndLog Err = 0, "Copy File: " & sFile & " to " & sDest     
  4436.         End if
  4437.         CopyFileEx = Err
  4438.         Err.Clear
  4439.         On Error Goto 0
  4440.        
  4441.     End function
  4442.    
  4443.     Function CopyFolder (sSource, sDest, bOverwrite)
  4444.         CopyFolder = CopyFolderEx(sSource, sDest, bOverwrite, True)
  4445.     End function
  4446.    
  4447.     Function CopyFolderEx (sSource, sDest, bOverwrite,bLogging)
  4448.    
  4449.         If bLogging then
  4450.             oLogging.CreateEntry "Copy Folder: " & sSource & " to " & sDest , LogTypeInfo
  4451.         End if
  4452.         On Error Resume Next
  4453.         oFSO.CopyFolder  sSource, sDest, bOverwrite
  4454.         If bLogging then
  4455.             TestAndLog Err = 0, "Copy Folder: " & sSource & " to " & sDest     
  4456.         End if
  4457.         CopyFolderEx = Err
  4458.         Err.Clear
  4459.         On Error Goto 0
  4460.        
  4461.     End function
  4462.    
  4463.     Function MoveFolder (sSource, sDest )
  4464.         MoveFolder = MoveFolderEx (sSource, sDest, True )
  4465.     End function
  4466.    
  4467.     Function MoveFolderEx (sSource, sDest, bLogging )
  4468.  
  4469.         If bLogging then
  4470.             oLogging.CreateEntry "Move Folder " & sSource & " to " &  sDest , LogTypeInfo
  4471.         End if
  4472.         On Error Resume Next
  4473.         oFSO.MoveFolder sSource,sDest
  4474.         If bLogging then
  4475.             TestAndLog Err = 0, "Move Folder " & sSource & " to " &  sDest
  4476.         End if
  4477.         MoveFolderEx = Err
  4478.         Err.Clear
  4479.         On Error Goto 0
  4480.  
  4481.     End function
  4482.  
  4483.     Function NormalizePath( Path )
  4484.         NormalizePath = oFSO.GetAbsolutePathName (Path )
  4485.     End function
  4486.  
  4487.     Function GetTempFile
  4488.         GetTempFile = oFso.BuildPath( GetTempFolder, oFSO.GetTempName )
  4489.     End function
  4490.  
  4491.     Function GetTempFileEx(sExt)
  4492.         GetTempFileEx = oFso.BuildPath( GetTempFolder, oFSO.GetBaseName(oFSO.GetTempName) & "." & sExt )
  4493.     End function
  4494.  
  4495.     Function GetTempFolder
  4496.         GetTempFolder = oFSO.GetSpecialFolder(2) 'TemporaryFolder
  4497.     End function
  4498.  
  4499.     Function GetWindowsFolder
  4500.         GetWindowsFolder = oFSO.GetSpecialFolder(0) 'WindowsFolder
  4501.     End function
  4502.  
  4503.     Function CheckFileVersion ( sFileName, sMinVersion )
  4504.         ' Returns True if the sFileName is the sMinVersion or greater, False if less, or not found.
  4505.  
  4506.         Dim sFoundFile
  4507.         Dim sMSIVer
  4508.         Dim sMSIVer2
  4509.         Dim i
  4510.  
  4511.         CheckFileVersion = oUtility.FindFile(sFileName, sFoundFile) = SUCCESS
  4512.         TestAndLog CheckFileVersion, "FindFile (" & sFileName & ")"
  4513.  
  4514.         If CheckFileVersion then
  4515.             sMSIVer = split(oFSO.GetFileVersion(sFoundFile),".")
  4516.             sMSIVer2 = split(sMinVersion,".")
  4517.  
  4518.             i = 0
  4519.             do while CheckFileVersion and ( i <= ubound(sMSIVer) ) and ( i <= ubound(sMSIVer2) )
  4520.                 If sMSIVer(i) <> sMSIVer2(i) then
  4521.                     CheckFileVersion = clng(sMSIVer(i)) >= clng(sMSIVer2(i))
  4522.                     exit do
  4523.                 End if
  4524.                 i = i + 1
  4525.             Loop
  4526.  
  4527.             oLogging.CreateEntry sFileName & " version: [ " & join(sMSIVer,".") & " | " & sMinVersion & " ].   Is version found? " & ( CheckFileVersion ), LogTypeInfo
  4528.         Else
  4529.             oLogging.CreateEntry sFileName & " Not found! Needs upgrade.  " & ( CheckFileVersion ), LogTypeInfo
  4530.  
  4531.         End if
  4532.  
  4533.     End function
  4534.  
  4535. End Class
  4536.  
  4537.  
  4538. '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  4539. '
  4540. ' Regular Expression Helper functions
  4541. '    http://msdn.microsoft.com/en-us/library/6wzad2b2(VS.85).aspx
  4542. '
  4543. ' Usage:
  4544. '  for each Match in oRegEx.GetRegExMatchesFromFile( "\[([^\]]*)\]","c:\boot.ini" )
  4545. '     Wscript.echo "Match: " & Match
  4546. '  next
  4547. '
  4548.  
  4549. dim g_oRegEx
  4550. Function oRegEx
  4551.     if isempty(g_oRegEx) then
  4552.         set g_oRegEx = new clsRegEx
  4553.     end if
  4554.     set oRegEx = g_oRegEx
  4555. end Function
  4556.  
  4557. class clsRegEx
  4558.  
  4559.     Private Function ReadEntireFile( sFileName )
  4560.         ' TestAndLog oFSO.FileExists(sFileName), "File Test: " & sFileName
  4561.         ReadEntireFile = oFSO.OpenTextFile(sFileName, ForReading, FALSE ).ReadAll
  4562.     End function
  4563.  
  4564.     private Function RegExObj ( SearchPattern, IgnoreCase, IsGlobal )
  4565.         set RegExObj = New RegExp
  4566.         RegExObj.Global = IsGlobal
  4567.         RegExObj.Multiline = TRUE
  4568.         RegExObj.IgnoreCase = IgnoreCase
  4569.         RegExObj.Pattern = SearchPattern
  4570.     end Function
  4571.  
  4572.     Function GetRegExMatches ( SearchPattern, Buffer )
  4573.         set GetRegExMatches = RegExObj ( SearchPattern, TRUE, TRUE ).Execute(Buffer)
  4574.     end Function
  4575.  
  4576.     Function TestRegEx ( SearchPattern, Buffer )
  4577.         TEstRegEx = RegExObj ( SearchPattern, TRUE, TRUE ).Test(Buffer)
  4578.     end Function
  4579.  
  4580.     Function ReplaceRegEx ( SearchPattern, ReplacementString, Buffer )
  4581.         ReplaceRegEx = RegExObj ( SearchPattern, TRUE, TRUE ).Replace(Buffer, ReplacementString)
  4582.     end Function
  4583.  
  4584.     Function GetRegExMatchesFromFile ( SearchPattern, FileName )
  4585.         set GetRegExMatchesFromFile = GetRegExMatches ( SearchPattern, ReadEntireFile(FileName) )
  4586.     end Function
  4587.  
  4588.     Function TestRegExFromFile ( SearchPattern, FileName )
  4589.         TestRegExFromFile = TestRegEx ( SearchPattern, ReadEntireFile(FileName) )
  4590.     end Function
  4591.  
  4592.     Function ReplaceRegExFromFile ( SearchPattern, ReplacementString, FileName )
  4593.         ReplaceRegExFromFile = ReplaceRegEx ( SearchPattern, ReplacementString, ReadEntireFile(FileName) )
  4594.     end Function
  4595.  
  4596.     Function FindStrInFile( SearchStr, FileName )
  4597.         FindStrInFile = InStr(1, ReadEntireFile( sFileName ), SearchStr, vbTextCompare)
  4598.     end Function
  4599.  
  4600.  
  4601. end class
Add Comment
Please, Sign In to add comment