Boot from VHD and WDS

Following on from Aly’s excellent article about configuring MDT to support Boot from VHD I thought I would add some words about WDS and boot from VHD.

Windows Server 2008 R2 contains an enhanced version of the WDS server. I will talk about some of the other enhancements in a later post – today I will touch on the VHD enhancements. WDS now supports the ability to deploy a VHD file to target computers and configure them to boot from it.

Which VHD to use? You cannot just use any VHD – there are some restrictions. The VHD has to contain either Windows Server 2008 R2 or Windows 7 Enterprise or Ultimate. Also you must use either use Hyper-Visor or the wim2vhd script running on Windows 7 or Windows Server 2008 R2, available from MSDN, to create the VHD. Once you have created the VHD place it somewhere you can access it from the WDS server.

Importing the VHD to WDS. Unfortunately it is not possible to use the WDS GUI to import a VHD file to the WDS server – we have to get our hands dirty using the command line – yippee! First though use the WDS management console to create a group that will hold the VHD images – for example create a group called VHD. Now use the command line below to import your image; this assumes the group is called VHD. (This should all be on one line. It may be wrapped here for readability. )

WDSUtil.exe /Verbose /Progress /Add-Image /ImageFile:<path to image file><image file name> /ImageType:Install /ImageGroup:vhd

You have to supply the full path and the name of the VHD file. Don’t forget if there are spaces in your directory structure or file name to enclose this string in quotes. The image will appear in the GUI with the same name as the VHD file.

Deploying the VHD. Ok so now it starts to get a bit tricky. If you boot a client and connect to the WDS server you will see the VHD image listed in the available images. However deploying via this method is not supported. The only supported method is to use an unattend.xml file. A sample file is given at the end of this article; the key code section is posted below.

<ImageSelection>

<WillShowUI>OnError</WillShowUI>

<InstallImage>

<ImageName>Win7-Beta</ImageName>

<ImageGroup>VHD</ImageGroup>

<Filename>w7x32ulti.vhd</Filename>

</InstallImage>

Here you can see that we specify the name of the image to be deployed, the group the image is in and the actual file name of the VHD itself.

The rest of the unattend.xml defines things like credentials to connect to the WDS server, the disk to place the VHD on and if we are going to deploy to an existing disk/partition or wipe and create a new one. So lets just dwell on that for a moment. This means that we can PXE boot our working machines, have a new Windows 7 VHD file applied to it and still preserve the existing OS. Sweet! The example unattend below will do just this – it leaves the current partition alone.

Using the Unattend.xml. So how do we specify that a client is going to use the unattend.xml? There are a couple of ways of doing this. However before I outline this process I need to touch on a gotcha. In the full unattend.xml you will see that there is an entry for the architecture of the WinPE environment that this unattend will run in. So if we have both 32 bit and 64 bit boot environments we need an unattend.xml for each. Don’t forget though that a 32 bit boot Win PE can deploy a VHD with a 64 bit OS in it. Just make sure that the target client can support that architecture. If all boot environments are 32 bit then we only need one unattend file – unless we have different architecture VHDs of course.

So lets get back to the unattend file. There are two ways;

1) Associate the unattend with the boot WinPE image. This is the simplest configuration – the down side is that every client that boots with that architecture and using that boot image will get the VHD file.
clip_image002[4]

2) Associate the unattend with individual clients via AD. This is more complex and if there are lots of clients or the clients frequently change deployment methods it takes a lot of management. However this solution gives you the most flexibility.

Use the Windows System Image Manger in the WAIK to create your unattend.xml file, or use the sample one below. The sample one will drop the VHD into partition 1 of your disk. If partition one is a 200Mb Bitlocker partition its not going to fit! Change the partition number to one with enough size.

Create a directory under the reminst dir on your WDS server and copy the unattend file to this directory. Give the unattend a suitable name. In the screen shot above you can see I have created an unattend file and placed it in the reminst\unattends directory on the WDS server.

Now I am ready to boot a client and deploy my VHD to it.

When the client boots it should automatically connect to the WDS server, select the VHD you chose and deploy it to the target system. The file gets dropped into a standard directory structure c:\Windows Images\XXX. XXX is an index number that starts a 000. Each new image you deploy increases the index by 1. When the image has been deployed you will find the BCD has been updated to include a new entry. For Windows 7 machines this is “Windows 7”. It is not possible to change this via WDS or the unattend.xml. If you do need to change it you will have to write a post deployment task to do so. The last image deployed is the default boot OS and is placed at the top of the list – which might make changing the description easier.

NOTE: The disk must already be running Windows 7 or Server 2008 R2 and the destination partition must NOT be Bitlockered.

I hope you found the post useful. I look forward to your comments.

This post was contributed by Richard Trusson, a Senior Consultant with Microsoft Services, UK.

 

The wim2vhd script can be found here: https://code.msdn.microsoft.com/wim2vhd

The example unattend.xml is below.

<?xml version="1.0" ?>
<unattend xmlns="urn:schemas-microsoft-com:unattend">
<settings pass="windowsPE">
<component name="Microsoft-Windows-Setup" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" processorArchitecture="x86">
<WindowsDeploymentServices>
<Login>
<WillShowUI>OnError</WillShowUI>
<Credentials>
<Username>Administrator</Username>
<Domain>woodgrove</Domain>
<Password>*********</Password>
</Credentials>
</Login>
<ImageSelection>
<WillShowUI>OnError</WillShowUI>
<InstallImage>
<ImageName>Win7-Beta</ImageName>
<ImageGroup>VHD</ImageGroup>
<Filename>w7x32ulti.vhd</Filename>
</InstallImage>
<InstallTo>
<DiskID>0</DiskID>
<PartitionID>1</PartitionID>
</InstallTo>
</ImageSelection>
</WindowsDeploymentServices>
<DiskConfiguration>
<WillShowUI>OnError</WillShowUI>
<Disk>
<DiskID>0</DiskID>
<WillWipeDisk>False</WillWipeDisk>
<ModifyPartitions>
<ModifyPartition>
<Order>1</Order>
<PartitionID>1</PartitionID>
<Extend>True</Extend>
</ModifyPartition>
</ModifyPartitions>
</Disk>
</DiskConfiguration>
</component>
<component name="Microsoft-Windows-International-Core-WinPE" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" processorArchitecture="x86">
<SetupUILanguage>
<WillShowUI>OnError</WillShowUI>
<UILanguage>en-US</UILanguage>
</SetupUILanguage>
<UILanguage>en-US</UILanguage>
</component>
</settings>
</unattend>

 

Disclaimer: The information on this site is provided "AS IS"
with no warranties, confers no rights, and is not supported by the
authors or Microsoft Corporation. Use of included script samples are
subject to the terms specified in the
Terms of Use .