Hyper-V generation 2 virtual machines – part 4

Part 1: Introduction to generation 2 virtual machines
Part 2: Networking and boot order
Part 3: Storage
Part 4: Keyboard for Windows 8 & Windows Server 2012
Part 5: Kernel debugging
Part 6: Secure Boot
Part 7: FAQ
Part 8: Manually migrating generation 1 virtual machines to generation 2
Part 9: Installing from ISO
Part 10: Utility for converting generation 1 virtual machines to generation 2 (Convert-VMGeneration)

This part of the series on generation 2 virtual machines in Hyper-V looks a little more at the keyboard device. This has relevance if you are running Windows 8 or Windows Server 2012 as a guest operating system, and more specifically WinPE/WinRE from these operating systems. PE is used, for example, during Windows setup. In part one, I mentioned that we removed the emulated i8042 keyboard device from generation 2 virtual machines. That means the only keyboard device available is the software based keyboard.

Unfortunately… this is also where hindsight is a marvelous asset. In PE & RE environments, the software based keyboard driver is not present. It was a pure and simple oversight, and I’m probably as good a person to blame as anyone. (Not literally though please ;).) At the time, no-one had thought there might be a need for it to be present in the future. It simply didn’t affect any end user scenarios. Generation 2 virtual machines changed those assumptions.

So let’s take the case of when you are installing Windows 8 client into a generation 2 virtual machine booted from an ISO. It’s the retail version which requires a product key. Setup is built on WinPE, and without the software based keyboard driver, you can’t enter the product key. (Well I guess you can use the on-screen keyboard.) Obviously in the case of unattended installs, you can get around this. You would hit the same problem doing a network install where the WDS server boot image (again based on WinPE) provided to the VM is Windows 8/Windows Server 2012 based. If that is the case, update your boot image to 8.1 and the problem will go away. Another workaround is to do an initial boot to an ISO containing Windows 8.1 PE from where Windows 8/Windows Server 2012 can be launched.

Fortunately, it’s relatively easy to solve the above using standard servicing mechanisms, which is what I’ll walk through in this part.

I’m assuming your client or technician machine is Windows 8.1 with Hyper-V enabled (or you have access to a Windows Server 2012 R2 machine with Hyper-V enabled). To start with, grab the Windows Assessment and Deployment Kit for Windows 8.1 (otherwise known as the ADK) from https://www.microsoft.com/en-ie/download/details.aspx?id=39982. Note I have tried this on Windows 8 as well, using the Windows 8 version of the ADK, but with pre-release versions of Windows 8.1. It should still work though.

When installing the ADK, you can use the default options, although if you choose, you only need the ‘Deployment Tools’ option for this walkthrough.

clip_image001

Once installed, start an elevated “Deployment and Imaging Tools Environment” command prompt.

While it’s installing, grab an ISO of Windows 8 (or Windows Server 2012) and copy it locally to the machine where the ADK is installed. For this walkthrough, I’m using an en_us Windows 8 RTM ISO although the language should be irrelevant. (Thinking about it, I should have grabbed the en_gb ISO as I still get frustrated continually seeing “Favourites” misspelt!)

The next think you need is the CAB file which contains the Integration Service .CAB file for Windows 8.1. It is important to use the .CAB file from the final RTM build of Windows 8.1, not the version from Windows 8.1 preview to avoid driver signing issues and a conflict with the Secure Boot feature of generation 2 virtual machines. The CAB file can be found under \Windows\vmguest\support\amd64, named “Windows6.2-HyperVIntegrationServices-x64.cab”. Copy it to a working directory where the .ISO being modified is located.

clip_image003

Now you need to mount the .ISO as a local drive letter to extract the contents which you are soon going to be modifying. You can mount it by simply typing the name of the .ISO file at the command prompt, or using Windows File Explorer. Simply copy the contents, including sub-directories to a temporary directory. In my case, I’m using c:\working\extract. After copying, you can unmount the ISO from explorer by right clicking on the drive and selecting Eject.

clip_image005

Next job is to examine the Windows PE boot WIM image which will be in the sources sub-directory where you just extracted the .ISO contents. Use dism /get-imageinfo to do this. There is a little gotcha here, you need to use DISM from the ADK, not the one built into Windows to avoid “Error: 87” as shown below.

clip_image006

The output shows there are two images in the WIM file, both of which we are going to update. Using another temporary empty directory, in my case, c:\mount, mount one of the images in the above WIM. Again, using dism, we are going to use the /mount-image parameter. Note the use of the /index: parameter too to match each of the images in the WIM per the above screenshot.

clip_image007

Next we need to add the software-based keyboard driver from the CAB file we copied earlier. As the Hyper-V Integration Services are catalog signed, it is necessary to apply the complete package of the integration services rather than the single keyboard driver. This is done using the /add-package parameter to dism.

clip_image008

And finally, for this image, unmount it, remembering to commit the changes. This is done using dism with the /unmount-image and /commit parameters.

clip_image009

Here’s the raw commands for completeness

dism /get-imageinfo boot.wim
dism /mount-image /imagefile:boot.wim /index:1 /mountdir:c:\mount
dism /image:c:\mount /add-package /packagepath:Windows6.2-HyperVIntegrationServices-x64.cab
dism /unmount-image /mountdir:c:\mount /commit

Repeat the above three commands but mounting index 2 in the boot.wim file (which is the Windows Setup image) this time around.

At this point, you might also optionally want to update the recovery WIM in the media too. This is a tiny bit more complicated due to the fact that it’s a WIM inside a WIM. To do this, you need to mount install.wim rather than boot.wim to start with. For example below, you can see that the media I am using contains Windows 8 and Windows 8 Pro.

clip_image010

The mount of install.wim…

clip_image011

Information on winre.wim under \mount\windows\system32\recovery\winre.wim

clip_image012

Mounting the first (and only) image in WinRE.wim to a second mount temporary directory (c:\mount2)

clip_image013

Adding the integration services package (remember c:\mount2, not c:\mount)

clip_image014

Committing the package and unmounting (again remember c:\mount2)

clip_image015

And now unmounting the Windows 8 image itself from c:\mount committing the contents.

clip_image016

Repeat for each image inside install.wim.

At this point, you are ready to re-create the ISO which can be used for Operating System installation on both generation 1 (PCAT) and generation 2 (UEFI) virtual machines. We use oscdimg.exe from the ADK for this purpose. From the sources directory where the modified Windows media is extracted, run the following command (on one line)

Oscdimg
-m
-o
-u2
-udfver102
-bootdata:2
#p0,e,b<Path>\etfsboot.com
#pEF,e,b<Path>\efisys.bin
<Source Directory>
<Target>

These are the relevant parameters:

-m

Ignore the maximum size limit of the image

-o

Optimize by removing duplicate files

-u2

UDF file system ISO image

-udfver102

UDF version will be 1.02

-bootdata:2

Specified there will be two boot catalog entries

#p0,e,b<Path>\etfsboot.com

# is the separator between boot entries

p0 sets the platform ID to 0 for the first default boot entry for the BIOS e Specifies floppy disk emulation in the El Torito catalog b<Path>\etfsboot.com Puts the specified file in the boot sectors of the disk

#pEF,e,b<Path>efisys.bin

# is the separator between first and second entry

pEF sets the platform ID to “EF” as defined by the UEFI specification

b<Path>\efisys.bin Puts the specified file (Efisys.bin) in the boot sector of the disk. Efisys.bin is the binary floppy disk layout of the EFI boot code. This disk image contains the files that are used to start from the EFI firmware in the Efi\boot\x64boot.efi folder

<Source Directory>

Is the top directory where the (modified) Windows Media was extracted to.

<Target>

Is the full path to the .ISO that will be generated.

Note that using just etfsboot.com is not sufficient as this only puts a boot loader suitable for BIOS/PCAT based machines onto the ISO. More information can be found at https://support.microsoft.com/kb/947024. (This KB applies for Windows Server 2008, but can be used for Windows Server 2012/Windows 8 as well).

Using our previous working directories, here’s an example.

clip_image017

Phew! Let’s try it out in a new generation 2 virtual machine attaching and installing from the patched ISO.

clip_image019

Of course, you can also use the patched boot.wim file for use on a WDS server. However, I would recommend instead you put the Windows 8.1 PE and boot.wim on the WDS server instead as these contain the software keyboard driver already.

In the next part, I’ll talk about debugging as it relates to generation 2 virtual machines.

Cheers,
John.