543 lines
14 KiB
Plaintext
543 lines
14 KiB
Plaintext
' // ***************************************************************************
|
|
' //
|
|
' // Copyright (c) Microsoft Corporation. All rights reserved.
|
|
' //
|
|
' // Microsoft Deployment Toolkit Solution Accelerator
|
|
' //
|
|
' // File: WizUtility.vbs
|
|
' //
|
|
' // Version: 6.3.8456.1000
|
|
' //
|
|
' // Purpose: Common Utility functions used by wizard UI Scripts
|
|
' //
|
|
' // ***************************************************************************
|
|
|
|
|
|
Function BrowseForFolder(sDefaultValue)
|
|
Dim iRetVal
|
|
|
|
|
|
iRetVal = Success
|
|
|
|
' Workaround for BrowseForFolder problem when called from an HTA: sometimes it doesn't show up.
|
|
|
|
oEnvironment.Item("DefaultFolderPath") = sDefaultValue
|
|
iRetVal = oShell.Run("wscript.exe """ & oUtility.ScriptDir & "\LTIGetFolder.wsf""", 1, true)
|
|
If iRetVal = 0 then
|
|
BrowseForFolder = oEnvironment.Item("FolderPath")
|
|
Else
|
|
BrowseForFolder = sDefaultValue
|
|
End if
|
|
|
|
|
|
End Function
|
|
|
|
|
|
|
|
'
|
|
' Call a VBScript and handle the errors
|
|
'
|
|
|
|
Function DisplayErrorIfAny ( sStatement )
|
|
Dim sError
|
|
|
|
If Err.Number = 0 then
|
|
Exit function
|
|
End if
|
|
|
|
'sError = sError & "Use Ctrl-C to copy the text of this message to the clipboard!" & vbNewLine
|
|
sError = sError & "A VBScript Runtime Error has occurred: " & vbNewLine & vbNewLine
|
|
sError = sError & "Error: " & Err.Number & " = " & Err.Description & vbNewLine & vbNewLine
|
|
sError = sError & "VBScript Code:" & vbNewLine & "-------------------" & vbNewLine
|
|
sError = sError & left(sStatement,800)
|
|
|
|
oLogging.CreateEntry sError ,LogTypeError
|
|
|
|
If oLogging.Debug then
|
|
sError = sError & vbNewLine & "-------------------" & vbNewLine
|
|
sError = sError & "Do you wish to attempt debugging on this script?"
|
|
DisplayErrorIfAny = MsgBox ( sError, vbYesNo , "VBScript Runtime Error" ) = vbYes
|
|
Else
|
|
Alert sError
|
|
DisplayErrorIfAny = FALSE
|
|
End if
|
|
|
|
End function
|
|
|
|
|
|
Function ExecuteWithErrorHandling ( statements )
|
|
Dim RunAgain
|
|
|
|
RunAgain = FALSE
|
|
|
|
On error resume Next
|
|
Err.Clear
|
|
ExecuteGlobal statements
|
|
ExecuteWithErrorHandling = err.number = 0
|
|
|
|
RunAgain = DisplayErrorIfAny (statements)
|
|
On error goto 0
|
|
|
|
If RunAgain then
|
|
ExecuteGlobal statements
|
|
End if
|
|
|
|
End function
|
|
|
|
|
|
Function EvalWithErrorHandling ( fn )
|
|
|
|
RunAgain = FALSE
|
|
|
|
On error resume Next
|
|
Err.Clear
|
|
EvalWithErrorHandling = eval(fn)
|
|
EvalWIthErrorHandling = EvalWIthErrorHandling and (err.number = 0)
|
|
|
|
RunAgain = DisplayErrorIfAny (fn)
|
|
On error goto 0
|
|
|
|
If RunAgain then
|
|
EvalWithErrorHandling = eval(fn)
|
|
End if
|
|
|
|
End function
|
|
|
|
|
|
'
|
|
' Create an XML Document Node with assoticated Elements and Attributes
|
|
'
|
|
' Parameters:
|
|
' oXMLDoc - XML DOM object ( Created from MSXML2.DOMDocument )
|
|
' oTargetNode - XML Document Element where the element is created
|
|
' sNodeName - Name of the Element Created
|
|
' oAttributes - VBScript Dictionary object containing a list of XML Attributes to add
|
|
' oElements - VBScript Dictionary object containing a list of XML Elements to add
|
|
'
|
|
' Example Usage:
|
|
' dim xmlDoc, oAttributes, oElements
|
|
' set oAttributes = CreateObject("Scripting.Dictionary")
|
|
' set oElements = CreateObject("Scripting.Dictionary")
|
|
' Set xmlDoc = CreateXMLDOMObject
|
|
'
|
|
' xmlDoc.Load "c:\SomeFile.xml" or xmlDoc.appendChild xmlDoc.createElement("MyRootElement")
|
|
'
|
|
' oAttributes.Add "guid", left( CreateObject("Scriptlet.TypeLib").GUID, 38 ) ' Strip trailing NULL's
|
|
' oElements.Add "Name","BuildName.value"
|
|
' oElements.Add "Version","1.0"
|
|
'
|
|
' CreateXMLNode xmlDoc, xmlDoc.documentElement, "MyElement", oAttributes, oElements
|
|
'
|
|
' xmlDoc.Save "c:\SomeFile.xml"
|
|
'
|
|
|
|
Function CreateXMLNode ( xmlDoc, oTargetNode, sNodeName, oAttributes , oElements)
|
|
|
|
Dim Key, oElement, oNodeRoot
|
|
|
|
Set oNodeRoot = xmlDoc.createElement(sNodeName)
|
|
|
|
For each key in oAttributes
|
|
If IsEmpty(key) then
|
|
Exit For
|
|
End if
|
|
oNodeRoot.setAttribute key, oAttributes.Item(key)
|
|
Next
|
|
|
|
For each key in oElements.Keys
|
|
If isempty(key) then exit for
|
|
Set oElement = xmlDoc.createElement(key)
|
|
oElement.text = oElements.Item(key)
|
|
oNodeRoot.appendChild oElement
|
|
Next
|
|
|
|
oTargetNode.appendChild oNodeRoot
|
|
|
|
End function
|
|
|
|
|
|
'
|
|
' hide/unhide an DHTML element
|
|
'
|
|
Sub HideUnhide ( oHTMLElement, isVisible )
|
|
|
|
If isVisible then
|
|
oHTMLElement.style.display = "inline"
|
|
Else
|
|
oHTMLElement.style.display = "none"
|
|
End if
|
|
|
|
End sub
|
|
|
|
|
|
'
|
|
' Copy Files to a folder
|
|
'
|
|
' More information:
|
|
' http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/reference/objects/folder/copyhere.asp
|
|
'
|
|
' WARNING: There is no way to tell if the user hits the Cancel Button during copy.
|
|
'
|
|
' Parameters:
|
|
' Source - Item or items to copy. Can be a file name string, a FolderItem object, or a FolderItems object.
|
|
' sDestDir - Target Destination Directory. If missing then this procedure will create the directory.
|
|
' Flags - Copy Flags for CopyHere (Typical settings: 2048 or 16 ===> 2064 ):
|
|
' CleanFirst - Clean the directory first.
|
|
'
|
|
Sub CopyFileWithProgressEx ( Source , sDestDir, Flags, CleanFirst )
|
|
|
|
Dim objFolder, hr
|
|
|
|
If CleanFirst and oFso.FolderExists( sDestDir ) then
|
|
oFSO.DeleteFolder sDestDir
|
|
End if
|
|
|
|
' Open the Destination Directory (Create if missing)
|
|
oUtility.VerifyPathExists sDestDir
|
|
Set objFolder = CreateObject("Shell.Application").NameSpace(sDestDir)
|
|
|
|
If objFolder is nothing then
|
|
Err.Raise 507,,"Destination Folder not set: " & sDestDir
|
|
Exit sub
|
|
End if
|
|
|
|
objFolder.CopyHere Source, Flags
|
|
Set objFolder = nothing
|
|
|
|
End sub
|
|
|
|
|
|
Sub CopyFileWithProgress ( Source , sDestDir )
|
|
' Common Settings
|
|
' 16 Respond with "Yes to All" for any dialog box that is displayed.
|
|
' 2048 Version 4.71. Do not copy the security attributes of the file.
|
|
CopyFileWithProgressEx Source , sDestDir, 2064, TRUE
|
|
End sub
|
|
|
|
'
|
|
' Tests a filename for invalid characters.
|
|
'
|
|
Function IsValidFileName (FileName)
|
|
|
|
Dim regEx
|
|
|
|
Set regEx = New RegExp
|
|
regEx.Pattern = "[\x00-\x1F\<\>\:\""\/\\\|\%\*\?\']" 'Strict Subset
|
|
IsValidFileName = (not regEx.Test ( FileName )) and (trim(FileName) <> "") and len(trim(FileName)) <= 253
|
|
|
|
Select Case UCase(Trim(FileName))
|
|
Case "CON", "AUX", "COM1", "COM2", "COM3", "COM4", "LPT1", "LPT2", "LPT3", "PRN", "NUL"
|
|
IsValidFileName = FALSE
|
|
End select
|
|
|
|
End function
|
|
|
|
|
|
Function IsValidPath (FilePath)
|
|
|
|
Dim regEx
|
|
|
|
Set regEx = New RegExp
|
|
regEx.Pattern = "[\x00-\x1F\<\>\""\%\*\?\']" 'Strict Subset
|
|
IsValidPath = (not regEx.Test ( FilePath )) and (trim(FilePath) <> "") and len(trim(FilePath)) <= 253
|
|
|
|
End function
|
|
|
|
|
|
Function IsValidComputerName ( OSDComputerName )
|
|
|
|
Dim regEx
|
|
Set regEx = New RegExp
|
|
regEx.Pattern = "[^a-zA-Z0-9\-\_]" 'Strict Subset
|
|
' regEx.Pattern = "[^a-zA-Z0-9\!\@\#\$\%\^\&\'\)\(\.\-\_\{\}\~ ]" ' SetComputerName compliant
|
|
IsValidComputerName = not regEx.Test ( OSDComputerName ) and len(OSDComputerName) <= 15
|
|
|
|
End function
|
|
|
|
|
|
|
|
Sub AddToList(byref List, Item, Delimiter)
|
|
oStrings.AddToList List,Item,Delimiter
|
|
End sub
|
|
|
|
Function ForceAsString ( InputVar )
|
|
ForceAsString = oStrings.ForceAsString ( InputVar )
|
|
End function
|
|
|
|
Function IsWhiteSpace (MyChar)
|
|
IsWhiteSpace = oStrings.IsWhiteSpace(MyChar)
|
|
End function
|
|
|
|
|
|
Function TrimAllWS( MyString )
|
|
TrimAllWS = oStrings.TrimAllWS( MyString )
|
|
End function
|
|
|
|
|
|
'
|
|
' Validate Credentials against either a Domain or a UNC Disk Resource
|
|
' Function will return TRUE if successfull, otherwise it will return an ERROR string!
|
|
'
|
|
Function CheckCredentials(sValidateUNC, sUserName, sDomain, sPassword)
|
|
|
|
Dim sFullUserName
|
|
Dim sJustUserName
|
|
Dim sUserObjectPath
|
|
Dim oWinNT
|
|
Dim oDomain ' As IADsDomain
|
|
Dim sDriveLetter
|
|
|
|
|
|
sFullUserName = sUserName
|
|
If sDomain <> "" then
|
|
sFullUserName = sDomain & "\" & sFullUserName
|
|
End if
|
|
|
|
|
|
If sValidateUNC = "" then
|
|
|
|
If oEnvironment.Item("ValidateAgainstUNCPath") <> "" then
|
|
sValidateUNC = oEnvironment.Item("ValidateAgainstUNCPath")
|
|
Else
|
|
|
|
sValidateUNC = oEnvironment.Item("DeployRoot")
|
|
For Each oDomain in objWMI.InstancesOf("Win32_ComputerSystem")
|
|
if oDomain.DomainRole = 1 or oDomain.DomainRole = 3 or oDomain.DomainRole = 4 or oDomain.DomainRole = 5 then
|
|
oLogging.CreateEntry "Computer is part of a domain, valiadate against domain.", LogTypeInfo
|
|
sValidateUNC = ""
|
|
End if
|
|
next
|
|
|
|
End if
|
|
|
|
End if
|
|
|
|
|
|
If sValidateUNC <> "" then
|
|
|
|
'
|
|
' Validate the credentials against an actual UNC disk resource
|
|
'
|
|
|
|
sDriveLetter = oUtility.MapNetworkDriveEx (sValidateUNC, sFullUserName, sPassword, LogTypeInfo )
|
|
|
|
If len(sDriveLetter) = 2 then
|
|
If bLeaveShareOpen <> TRUE and ucase(sValidateUNC) <> ucase(oEnvironment.Item("DeployRoot")) then
|
|
oNetwork.RemoveNetworkDrive sDriveLetter
|
|
End if
|
|
CheckCredentials = TRUE
|
|
Else
|
|
CheckCredentials = sDriveLetter ' If not a drive letter, then this is an error string
|
|
End if
|
|
|
|
Else
|
|
|
|
CheckCredentials = CheckCredentialsAD( "", sUserName, sDomain, sPassword)
|
|
|
|
End if
|
|
|
|
If CheckCredentials <> TRUE then
|
|
oLogging.CreateEntry "Credentials Script: " & CheckCredentials, LogTypeInfo
|
|
Exit function
|
|
End if
|
|
|
|
oEnvironment.Item("UserCredentials") = Cstr(TRUE)
|
|
|
|
If bDoNotSaveParameters = TRUE then
|
|
window.close
|
|
CheckCredentials = FALSE
|
|
End if
|
|
|
|
End Function
|
|
|
|
'
|
|
' Validate Credentials against a Domain
|
|
' Function will return TRUE if successfull, otherwise it will return an ERROR string!
|
|
'
|
|
Function CheckCredentialsAD(sJoinDomain, sUserName, sDomain, sPassword)
|
|
|
|
Dim sFullUserName
|
|
Dim sJustUserName
|
|
Dim sUserObjectPath
|
|
Dim oWinNT
|
|
Dim oDomain ' As IADsDomain
|
|
Dim sDriveLetter
|
|
Dim sJoinDomainNew
|
|
|
|
sJoinDomainNew = sJoinDomain
|
|
|
|
|
|
sFullUserName = sUserName
|
|
If sDomain <> "" then
|
|
sFullUserName = sDomain & "\" & sFullUserName
|
|
End if
|
|
|
|
|
|
'
|
|
' Validate the credentials against a domain or computer server using Active Directory authentication.
|
|
'
|
|
|
|
' The credentials can be in the form "BillG", "redmond\BillG", or "BillG@Microsoft.Com". Cleanup for use.
|
|
|
|
sJustUserName = sUserName
|
|
If Instr(1,sJustUserName,"@") <> 0 then
|
|
' Username is in form: BillG@redmond.corp.Microsoft.com, remove domain.
|
|
sJustUserName = left(sJustUserName, instr(1,sJustUserName,"@") - 1)
|
|
ElseIf instr(1,sJustUserName,"\") <> 0 then
|
|
' Username is in form: redmond\BillG, remove domain.
|
|
sJustUserName = mid(sJustUserName, instr(1,sJustUserName,"\") + 1 )
|
|
End if
|
|
|
|
On Error Resume Next
|
|
Set oWinNT = GetObject("WinNT:")
|
|
If Err then
|
|
If oEnvironment.Item("OSVersion") = "WinPE" then
|
|
oLogging.CreateEntry "Unable to verify domain credentials in Windows PE since ADSI is not available", LogTypeInfo
|
|
CheckCredentialsAD = TRUE
|
|
Err.Clear
|
|
Exit Function
|
|
Else
|
|
CheckCredentialsAD = Err.Description & " (" & Hex(Err.Number) & ")"
|
|
Exit Function
|
|
End if
|
|
End if
|
|
|
|
|
|
|
|
If sJoinDomainNew = "" then
|
|
sJoinDomainNew = sDomain
|
|
ElseIf Instr(1, sUserName, "\") <> 0 then
|
|
sJoinDomainNew = left(sUserName, instr(1, sUserName, "\") - 1)
|
|
ElseIf Instr(1, sUserName, "@") <> 0 then
|
|
sJoinDomainNew = mid(sJustUserName, instr(1,sJustUserName,"@") + 1 )
|
|
End if
|
|
|
|
|
|
' 1 = ADS_SECURE_AUTHENTICATION
|
|
Set oDomain = oWinNT.OpenDSObject("WinNT://" & sJoinDomainNew & "/" & sJustUserName & ",user" , sFullUserName, sPassword, 1 )
|
|
|
|
|
|
|
|
If Err.Number = &h80070035 then
|
|
CheckCredentialsAD = "Network path not found (80070035)"
|
|
ElseIf Err.Number = &H8007054B then
|
|
CheckCredentialsAD = "Domain could not be contacted (8007054B)"
|
|
ElseIf Err.Number = &h8007052E then
|
|
CheckCredentialsAD = "User ID or password is invalid (8007052E)"
|
|
ElseIf Err.Number = &h800708AD then
|
|
CheckCredentialsAD = "User ID is not valid (800708AD)"
|
|
ElseIf Err then
|
|
CheckCredentialsAD = Err.Description & " (" & Hex(Err.Number) & ")"
|
|
ElseIf oDomain is nothing then
|
|
CheckCredentialsAD = "Domain validation failed - " & Err.Description & " (" & Err.Number & ")"
|
|
Else
|
|
Err.Clear
|
|
CheckCredentialsAD = TRUE
|
|
End if
|
|
On error goto 0
|
|
|
|
If CheckCredentialsAD <> TRUE then
|
|
oLogging.CreateEntry "Credentials Script: " & CheckCredentialsAD, LogTypeInfo
|
|
Exit function
|
|
End if
|
|
|
|
oEnvironment.Item("UserCredentials") = Cstr(TRUE)
|
|
|
|
If bDoNotSaveParameters = TRUE then
|
|
window.close
|
|
CheckCredentialsAD = FALSE
|
|
End if
|
|
|
|
End Function
|
|
|
|
Function GetDomainDefault
|
|
Dim oComputer
|
|
|
|
|
|
' Get Local Domain
|
|
|
|
GetDomainDefault = ""
|
|
if oEnvironment.Item("UserDomain") <> "" then
|
|
GetDomainDefault = oEnvironment.Item("USERDOMAIN")
|
|
else
|
|
On Error Resume Next
|
|
For each oComputer in objWMI.InstancesOf("Win32_ComputerSystem")
|
|
If oComputer.DomainRole <> 0 then
|
|
GetDomainDefault = oComputer.Domain
|
|
End if
|
|
Next
|
|
On Error Goto 0
|
|
end if
|
|
|
|
End Function
|
|
|
|
|
|
Function GetDestDisk
|
|
|
|
' Preference search order is: oProperties, oEnvironment/CS.INI , and TS.XML ( DefaultDestinationXxx )
|
|
GetDestDisk = Property("DestinationDisk")
|
|
If GetDestDisk = "" then
|
|
GetDestDisk = Property("DefaultDestinationDisk")
|
|
End if
|
|
If GetDestDisk = "" then
|
|
GetDestDisk = "0"
|
|
End if
|
|
|
|
End function
|
|
|
|
Function GetDestPart
|
|
|
|
' Preference search order is: oProperties, oEnvironment/CS.INI , and TS.XML ( DefaultDestinationXxx )
|
|
GetDestPart = Property("DestinationPartition")
|
|
If GetDestPart = "" then
|
|
GetDestPart = Property("DefaultDestinationPartition")
|
|
End if
|
|
If GetDestPart = "" then
|
|
GetDestPart = "1"
|
|
End if
|
|
|
|
End function
|
|
|
|
Function HasGoodDestDisk( sDestDisk )
|
|
|
|
Dim oDisk, oDisks
|
|
|
|
Set oDisks = objWMI.ExecQuery("Select index from Win32_DiskDrive where MediaType like 'Fixed%hard disk%'")
|
|
|
|
HasGoodDestDisk = False
|
|
For Each oDisk in oDisks
|
|
If Cstr(oDisk.Index) = sDestDisk Then
|
|
oLogging.CreateEntry "Validated Disk exists", LogTypeInfo
|
|
HasGoodDestDisk = True
|
|
exit for
|
|
End If
|
|
Next
|
|
|
|
End function
|
|
|
|
Function HasGoodDestPart ( sDestDisk, sDestPart )
|
|
|
|
Dim sDestDrive
|
|
|
|
HasGoodDestPart = true
|
|
If Property("DeploymentType") = "REFRESH" Then
|
|
|
|
sDestDrive = oUtility.DetermineDriveFromDiskPart( sDestDisk, sDestPart )
|
|
HasGoodDestPart = sDestDrive = oEnv("SystemDrive")
|
|
oLogging.CreateEntry "oUtility.DetermineDriveFromDiskPart( " & sDestDisk& ", " & sDestPart& " ) = " & sDestDrive, LogTypeInfo
|
|
|
|
End if
|
|
|
|
End function
|
|
|
|
|
|
Function RmPropIfFound( Prop )
|
|
|
|
If oProperties.Exists(Prop) then
|
|
oProperties.Remove(Prop)
|
|
End if
|
|
|
|
End function
|
|
|
|
|