Summary: Copy a VHD file template and inject an Unattend.xml file in preparation for attachment to a VHD file.
Hey, Scripting Guy!
Yesterday you were showing us how to edit the Unattend.XML file. How can we easily inject that into a virtual machine and maybe turn that into a virtual machine?
—RD
Hello RD,
Never fear. Honorary Scripting Guy, Sean Kearney, is here to help you save the day with more Windows PowerShell!
Note Today's post is the third in a five-part series. To catch up, read:
- Set Up a Lab with Windows PowerShell and Free Microsoft Software: Part 1
- Set Up a Lab with Windows PowerShell and Free Microsoft Software: Part 2
If you’ve played around with Windows 8.1 you have noticed that you can double-click an ISO or VHD file, and it will automatically mount as a virtual drive in Windows Explorer! The first time I saw that, I thought it was amazingly cool.
Our first challenge with this VHD file is to get the Unattend.XML file sitting in the \Windows\System32\Sysprep folder.
Actually I fibbed a bit. The FIRST thing is to make a copy of one of the VHD files we just created as the basis for our virtual machine. So I need some minor criteria for the new name of the VHD:
- I want TemplateVHD as part of the file name.
- I am going to use the VMName as part of the VHD name.
- I will attach the drive letter to the end.
- I’m going to grab the default location of the virtual machines from Hyper-V so I can drop the new VHDs into the proper place.
Let’s set up the first parameters we’ll need:
Param(
# Virtual Machine Name
$VMname,
# Explicit name of the Server Version
$Edition=”WindowsServer2012R2StandardServer”,
# Source folder for the Virtual Machine Templates
$Source=”C:\ISO”
)
We also need to obtain the default folder location for virtual hard disks in Hyper-V. This is stored in the registry of the computer.
$VHDPath=(Get-ItemProperty -Path 'HKLM:\Software\Microsoft\Windows NT\CurrentVersion\Virtualization' -Name 'DefaultVirtualHardDiskPath').DefaultVirtualHardDiskPath
Now we’re into building some simple file names for a backup with the Copy-Item cmdlet:
$SourceData=$SourcePath+"\"+$Edition+".vhd"
$TargetData=$VHDPath+$VMName+"-"+$Edition+"-c.vhd"
COPY-ITEM $SourceData $TargetData
After we copy the file into a new folder, we can mount our new VHD file and inject the Unattend.xml file into it. For this to work, we need to get the drive letter of the mounted VHD file. This uses the same cmdlet we used to obtain the drive letter for the ISO file—we just pipe it to two different cmdlets.
First we mount the new VHD file:
MOUNT-DISKIMAGE $TargetData
Next obtain the drive letter by using Get-DiskImage on the mounted VHD file, but pipe the output into Get-Disk and then to Get-Partition:
$DriveLetter=((Get-DiskImage $TargetData | get-disk | get-partition).DriveLetter)+":"
Then we build out the target folder for our Unattend.xml file to drop into. Remember that you’re dealing with the mounted VHD and its Windows folder structure:
$Destination=$Driveletter+"\Windows\System32\Sysprep\unattend.xml"
After we complete our work, we copy the file and dismount the VHD file:
COPY-ITEM $UnattendXML $Destination
DISMOUNT-DISKIMAGE $TargetData
At this point, I can populate this data to New-VM, and I’m done, right?
Well sure, I could stop there. But then again, you wouldn’t get to see how we can go farther. Maybe go to the next step: populate some automatically starting scripts. Or maybe if you’re really good and eat all your Scriptos cereal, we’ll spin all this into a brand new shiny domain controller for the lab!
Interested? Eyes ablaze? Stay tuned for tomorrow’s thrill-packed episode of the Hey, Scripting Guys! Blog.
I invite you to follow the Scripting Guys on Twitter and Facebook. If you have any questions, send an email to The Scripting Guys at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then remember eat your Cmdlets each and every day with a tasty dash of Creativity.
Sean Kearney, Windows PowerShell MVP and Honorary Scripting Guy