Files

307 lines
11 KiB
XML

<job id="ZTIVHDCreate">
<script language="VBScript" src="ZTIUtility.vbs"/>
<script language="VBScript" src="ZTIDiskUtility.vbs"/>
<script language="VBScript">
' // ***************************************************************************
' //
' // Copyright (c) Microsoft Corporation. All rights reserved.
' //
' // Microsoft Deployment Toolkit Solution Accelerator
' //
' // File: ZTIVHDCreate.wsf
' //
' // Version: 6.3.8456.1000
' //
' // Purpose: Create a local VHD file, and mount as a disk.
' //
' // Variables:
' // VHDInputVariable [ Input ] - Name of Variable containing the target for the VHD file.
' // VHDOutputVariable [ Input ] - Name of variable to receive New Disk Index (Typically OSDDiskIndex for ZTIDiskPart.wsf).
' // VHDDisks [Output ] - Partition Index
' // VHDCreateFileName (Optional) - Name of VHD File to create ( "RANDOM" or "" to auto generate name )
' // VHDCreateDiffVHD (Optional) - Name of VHD Differencing Disk ( "RANDOM" to auto generate name )
' // VHDCreateSource (Optional) - Name of VHD File source to prepopulate the new VHD
' // VHDCreateSizeMax (Optional) - Maximum Size (in MB) of the VHD file (Default: 90% of parent disk)
' // VHDCreateType (Optional) - Creation Type of the VHD Disk Either FIXED or EXPANDABLE (Default: EXPANDABLE)
' //
' // Usage: cscript.exe [//nologo] ZTIVHDCreate.wsf [/debug:true]
' //
' // ***************************************************************************
Option Explicit
RunNewInstance
CONST DEFAULT_VHD_EXTENSION = ".VHD"
CONST DEFAULT_VHD_DIFF_EXTENSION = ".AVHD"
CONST DEFAULT_VHD_FILE_PATH = "\VHD\"
'//----------------------------------------------------------------------------
'// Main Class
'//----------------------------------------------------------------------------
Class ZTIVHDCreate
'//----------------------------------------------------------------------------
'// Constructor to initialize needed global objects
'//----------------------------------------------------------------------------
Private sTargetDrive
Private Sub Class_Initialize
If oEnvironment.Item("VHDInputVariable") <> "" Then
If oEnvironment.Item(oEnvironment.Item("VHDInputVariable")) <> "" then
If mid(oEnvironment.Item(oEnvironment.Item("VHDInputVariable")),2,1) = ":" then
sTargetDrive = left(oEnvironment.Item(oEnvironment.Item("VHDInputVariable")),2)
oLogging.CreateEntry "Found Target Drive: " & sTargetDrive, LogTypeInfo
End if
End if
End if
If isempty(sTargetDrive) then
oLogging.CreateEntry "VHDInputVariable was not detected, fall back to GetFirstPossibleSystemDrive()", LogTypeInfo
sTargetDrive = GetFirstPossibleSystemDrive
End if
End Sub
'//----------------------------------------------------------------------------
'// Main routine
'//----------------------------------------------------------------------------
Function Main
Dim oWMIPreviousDisk
Dim sVDiskSource
Dim sVDiskFile
Dim sVDiskDiffVHD
Dim iRC
Dim oDrive
Dim oWMIDiskPart
Dim iFoundVHDDisk
Dim sParams
Dim iSize
oLogging.CreateEntry "---------------- Initialization ----------------", LogTypeInfo
oUtility.ForceRelativeDriveReCalc
' Get the list of previous disks
Set oWMIPreviousDisk = AllDiskDrives
'
' If VHDCreateSource is defined, find the file.
'
If oEnvironment.Item("VHDCreateSource") <> "" then
oLogging.CreateEntry "VHDCreateSource defined: " & oEnvironment.Item("VHDCreateSource") , LogTypeInfo
If left(oEnvironment.Item("VHDCreateSource"),2) = "\\" then
oUtility.ValidateConnection oEnvironment.Item("VHDCreateSource")
End if
If oFSO.FileExists( oEnvironment.Item("VHDCreateSource") ) then
sVDiskSource = oEnvironment.Item("VHDCreateSource")
Else
' Search for %VHDCreateSource%.
iRC = oUtility.FindFile ( oEnvironment.Item("VHDCreateSource"), sVDiskSource )
If iRC <> SUCCESS then
sVDiskSource = empty
' Search for %VHDCreateSource% on all drives.
for each oDrive in oFSO.Drives
If oDrive.isReady then
If oFSO.FileExists (AddDriveLetter ( oDrive.DriveLetter, oEnvironment.Item("VHDCreateSource")) ) then
sVDiskSource = AddDriveLetter ( oDrive.DriveLetter, oEnvironment.Item("VHDCreateSource"))
oLogging.CreateEntry "Found File: " & sVDiskSource , LogTypeInfo
exit for
End if
End if
next
End if
End if
TestAndFail not isEmpty(sVDiskSource), 10301, "Verify source disk was found %VHDCreateSource%"
End if
'
' Create a random filename if necessary
'
If ucase(oEnvironment.Item("VHDCreateFileName")) = "RANDOM" or oEnvironment.Item("VHDCreateFileName") = "" then
oLogging.CreateEntry "Create a random VHD filename.", LogTypeInfo
sVDiskFile = DEFAULT_VHD_FILE_PATH & GenerateRandomVHD(DEFAULT_VHD_EXTENSION)
Else
sVDiskFile = oEnvironment.Item("VHDCreateFileName")
End if
'
' Create and manage the path where the *.vhd file is created.
'
If oFSO.GetParentFolderName(sVDiskFile) = "" then
oLogging.CreateEntry "VHDCreateFileName does not specify a Directory. Prefix default directory: " & DEFAULT_VHD_FILE_PATH, LogTypeInfo
sVDiskFile = DEFAULT_VHD_FILE_PATH & sVDiskFile
End if
sVDiskFile = AddDriveLetter ( sTargetDrive , sVDiskFile )
oUtility.VerifyPathExists oFSO.GetParentFolderName(sVDiskFile)
oLogging.CreateEntry "Ready to deploy to: " & sVDiskFile , LogTypeInfo
'
' Create the VHD File
'
set oDrive = new ZTIDiskPartition
oDrive.Drive = sTargetDrive
TestAndFail not isempty(oDrive.Drive), 10311, "Verify Win32_LogicalDrive is available"
oLogging.CreateEntry "Found Logical Drive of size " & FormatLargeSize(oDrive.oWMIDiskPart.Size), LogTypeInfo
iSize = clng(oDrive.oWMIDrive(False).FreeSpace /1024/1024 * 80/100 ) ' 80% as MB
If isNumeric(oEnvironment.Item("VHDCreateSizePercent")) then
If 95 >= oEnvironment.Item("VHDCreateSizePercent") then
iSize = clng(oDrive.oWMIDrive(False).FreeSpace /1024/1024 * int(oEnvironment.Item("VHDCreateSizePercent"))/100 )
End if
ElseIf isNumeric(oEnvironment.Item("VHDCreateSizeMax")) then
If clng(oDrive.oWMIDrive(False).FreeSpace /1024/1024 * 95/100 ) >= clng( oEnvironment.Item("VHDCreateSizeMax") ) then
iSize = clng(oEnvironment.Item("VHDCreateSizeMax"))
End if
End if
If ucase(oEnvironment.Item("VHDCreateType")) = "FIXED" then
sParams = "TYPE=FIXED MAXIMUM=" & iSize
Else
sParams = "TYPE=EXPANDABLE MAXIMUM=" & iSize
End if
outility.safesleep 20000
oLogging.ReportProgress "About to Create VHD File (May take several minutes)...", 10
If sVDiskSource <> "" then
RunDiskPart array( "CREATE VDISK FILE=""" & sVDiskFile & """ " & sParams & " SOURCE=""" & sVDiskSource & """" )
Else
RunDiskPart array( "CREATE VDISK FILE=""" & sVDiskFile & """ " & sParams )
End if
TestAndFail oFSO.FileExists(sVDiskFile), 10302, "Verify file was created: " & sVDiskFile
'
' If there is a Differencing Disk, then create the Differencing disk.
'
If oEnvironment.Item("VHDCreateDiffVHD") <> "" then
oLogging.ReportProgress "Attach Differencing Disk...", 70
If ucase(oEnvironment.Item("VHDCreateDiffVHD")) = "RANDOM" then
' Create a random name
oEnvironment.Item("VHDCreateDiffVHD") = GenerateRandomVHD(DEFAULT_VHD_DIFF_EXTENSION)
End if
' Differencing Disks must be in the same folder as the parent VHD for Boot to VHD.
sVDiskDiffVHD = oFSO.BuildPath ( oFSO.GetParentFolderName( sVDiskFile ) , oFSO.GetFileName( oEnvironment.Item("VHDCreateDiffVHD") ) )
TestAndFail ucase(sVDiskFile) <> ucase(sVDiskDiffVHD), 10303, "Verify Diff file is not the same name as the Parent: [" & sVDiskFile & "] <> [" & sVDiskDiffVHD & "]"
RunDiskPart array( "CREATE VDISK FILE=""" & sVDiskDiffVHD & """ PARENT=""" & sVDiskFile & """" )
sVDiskFile = sVDiskDiffVHD
TestAndFail oFSO.FileExists(sVDiskFile), 10303, "Verify file was created: " & sVDiskFile
End if
'
' Now mount the Virtual Disk.
'
oLogging.ReportProgress "Mount Virtual Disk...", 80
RunDiskPart array( "select vdisk file=""" & sVDiskFile & """", "attach vdisk", "exit" )
'
' Find the new Disk Number from the VHD file mounted.
'
oLogging.ReportProgress "Cleanup...", 90
iFoundVHDDisk = FindNewDisk ( oWMIPreviousDisk )
If oEnvironment.Item("VHDOutputVariable") <> "" then
oEnvironment.Item(oEnvironment.Item("VHDOutputVariable")) = iFoundVHDDisk
End if
oEnvironment.Item("VHDDisks") = oEnvironment.Item("VHDDisks") & " " & iFoundVHDDisk
oUtility.ClearRelativeDriveLetters
Main = SUCCESS
End Function
'//----------------------------------------------------------------------------
'// Support routines
'//----------------------------------------------------------------------------
Function FindNewDisk ( oWMIPreviousDisks )
Dim oWMINewDisks
Dim oWMIDiskOld
Dim oWMIDiskNew
Dim bFoundMatch
oLogging.CreateEntry "Find a new Disk created by mounting a VHD file.", LogTypeInfo
set oWMINewDisks = AllDiskDrives
TestandFail oWMIPreviousDisks.Count + 1 = oWMINewDisks.Count, 10310, "Verify that the DIsk COunt increased by 1: " & oWMIPreviousDisks.Count & " " & oWMINewDisks.Count
For each oWMIDiskNew in oWMINewDisks
bFoundMatch = false
For each oWMIDiskOld in oWMIPreviousDisks
If oWMIDiskOld.Path_ = oWMIDiskNew.Path_ and oWMIDiskOld.PNPDeviceID = oWMIDiskNew.PNPDeviceID then
bFoundMatch = true
exit for
End if
next
If bFoundMatch then
' Disk was present before VHD DIsk was mounted, Skip...
Elseif not isEmpty(FindNewDisk) then
oLogging.CreateEntry "Another disk found: " & oWMIDiskNew.Path_ & " VS. " & FindNewDisk, LogTypeInfo
Else
oLogging.CreateEntry "Found new disk: " & oWMIDiskNew.Path_ & vbNewLine & oWMIDiskNew.PNPDeviceID, LogTypeInfo
FindNewDisk = oWMIDiskNew.Index
End if
next
TestandFail not isEmpty(FindNewDisk), 10303, "Verify that a new disk was created."
End Function
Function GenerateRandomVHD ( sExtension )
If oEnvironment.Item("TaskSequenceID") <> "" then
GenerateRandomVHD = oFSO.GetBaseName(oEnvironment.Item("TaskSequenceID") & "_" & oFSO.GetTempName) & sExtension
Else
GenerateRandomVHD = oFSO.GetBaseName(oFSO.GetTempName) & sExtension
End if
End function
Function AddDriveLetter ( sNewDriveLetter, sExistingPath )
If left(sExistingPath,2) = "\\" then
' do not search using UNC paths
ElseIf asc(ucase(left(sExistingPath,1))) >= asc("A") and asc(ucase(left(sExistingPath,1))) <= asc("Z") and mid(sExistingPath,2,2) = ":\" then
AddDriveLetter = left(sNewDriveLetter,1) & mid(sExistingPath,2)
Elseif left(sExistingPath,1) = "\" then
AddDriveLetter = left(sNewDriveLetter,1) & ":" & sExistingPath
Else
AddDriveLetter = left(sNewDriveLetter,1) & ":\" & sExistingPath
End if
End function
End class
</script>
</job>