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 http://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.


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.


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.


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.


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.


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.


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


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.


The mount of install.wim…


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


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


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


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


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


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)

<Source Directory>

These are the relevant parameters:


Ignore the maximum size limit of the image


Optimize by removing duplicate files


UDF file system ISO image


UDF version will be 1.02


Specified there will be two boot catalog entries


# 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


# 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.


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 http://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.


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


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.


Comments (20)

  1. John Howard -MSFT says:

    CW – Yes I understand your perception, however you have to recall that when Windows 8 was released, it was before the conception of Windows 8.1 and generation 2 VMs, and there was no such VM container which did not have an emulated keyboard present. Hence,
    it would have been impossible to test and extremely hard to imagine what at the time might have happened in the next release as that WIndows 8 RTM was before Windows 8.1 planning had started.

  2. Eyal-Sasasoftware says:

    Hi John,

    a few days ago I've installed server 2012 core , I'm managing it from my Windows 8.1 Installed laptop using Hyperv management Feature.

    I got a WINPE image (5.0) that I've created using windows 8.1 Assessment and Deployment Kit.

    after adding some additional packages I've added the Windows6.2-HyperVIntegrationServices-x64.cab .
    i took the cab from the server 2012 core itself.

    but still i do not have keyboard and mouse support at all.
    i did not get mouse & keyboard support prior adding the mentioned cab file.

    the funny thing is when i deploy a new VM and use windows 8.1 iso installation i do get keyboard & mouse support.

    Another thing i have noticed is, at first i tried booting from an X86 winpe with no success.
    then I created an X64 winpe that did booted up.

    on Vmware they both boot and work fine.

    any suggestions ?

    Great post.

  3. John Howard -MSFT says:

    Apologies for delay in replying – out of office for Christmas/New Year. Looks like there’s a couple of things here. You need to take the CAB from Windows 8.1 or Windows Server 2012 R2, not 2012. For the x86 issue, this is expected. Generation 2 VMs in Hyper-V only support 64-bit guest OS’s. There is no CSM in the firmware. There’s more information on this in the FAQ part.

  4. Anonymous says:

    Thanks , I'll try it out.

  5. John Howard -MSFT says:

    Great sleuthing, thanks. I’ve re-typed them above as a regular dash. I think it’s a case of this blog engine automatically changing them for some reason. Hopefully it’s fixed now.

  6. affordable web designers says:

    Hello..Lovely and fantastic article.. I agree about this article…Thanks to all..

  7. Christophe says:

    I have a question regarding this problem with keyboard :

    Can there be a side effect to Windows 7 when deployed from SCCM 2012 R2 on a Gen 1 VM hosted on Windows 8.1 ?

    Here's my problem :

    – I decided to migrate my computer from Windows 8.0 to 8.1 this week-end. In order to do this, I installed Windows 8.1 in a VHDX and decided to boot from VHD and keep my Windows 8.0 on the hard-drive. (I'm not a big fan of upgrading an OS.. I prefer reinstalling it).

    – I have a platform running a number of 2012 R2 servers in VMs in order to test SCCM 2012 R2 in Hyper-V. I use this platform to test my Windows 7 deployment scenario. (This scenario was working perfectly when Hyper-V was running on Windows 8.0)

    I imported my Hyper-V VMs in Windows 8.1 Hyper-V Manager.

    Now when I deploy a previously created Windows 7 MDT TS to a new Gen 1 VM I create in Hyper-V manager, I had to change the following :

    1) Set the memory of the VM to 1024 instead of 512 even if I check "Use Dynamic Memory" otherwise, the WinPE image won't boot with a crash screnn. I didn't have to do this under Windows 8.0.

    2) I have access to the keyboard (F8 key) up to the Windows Setup task.

    3) When the deployment arrives at the Windows Setup part (Windows 7 has booted and continues the installation), I cannot use my F8 key anymore and no other key works. It was working perfectly before migrating to 8.1.

    Do you have any suggestion regarding this ?

    Do I need to do what you did in this article even if I'm using a Gen 1 VM for Windows 7 ?

    I'm a bit confused here.


  8. No, this has nothing to do with generation 1 at all – they can use the emulated keyboard device which is present in a generation 1's hardware.

    For 1 (memory), this does not surprise me. DM is not active in PE and 512 is below the minimum amount of RAM. Operating system needs change, but I'm not specifically sure what the PE requirements are between different versions.

    For 2 (keyboard) As I would expect.

    For 3. This has not been reported to my knowledge. What happens if you do a straight install from media taking SCCM/MDT out of the picture? I don't have that environment setup to attempt to repro myself.

    Re "do I need to…". To re-iterate, this is not required for generation 1 VMs. Only generation 2 running Windows 8 PE & RE environments.

  9. Christophe says:

    Dear John

    It happened to be a problem…. with my keyboard itself :(…

    I don't know how but I changed my keyboard and everything when OK

    Regarding the memory, I confirm that, if I don't assign a minimum of 1024 MB to the VM, it won't boot.

    Thanks for your answers.

  10. Anonymous says:

    Pingback from Windows 8.1 Hyper-V – Simplified VM Import, and Generation 2 VMs | Learning every day…

  11. Anonymous says:

    Pingback from Hyper-V Windows 8.1 – Boot von Eval ISO schl??gt fehl | erik's weblog

  12. Anonymous says:

    Pingback from Hyper-V Windows 8.1 – Boot von Eval ISO schl??gt fehl | erik's weblog

  13. Anonymous says:

    Pingback from Hyper-V Windows 8.1 – Boot von Eval ISO schl??gt fehl | erik's weblog

  14. Anonymous says:

    Pingback from Hyper-V Windows 8.1 – Boot von Eval ISO schl??gt fehl | erik's weblog

  15. Anonymous says:

    Pingback from Hyper-V Windows 8.1 – Boot von Eval ISO schl??gt fehl | erik's weblog

  16. CW says:

    Thanks for this, much appreciated. I have to say like many I can't help feel that the quality of MS software development appears to be declining. How did this significant issue get past testing. This is a fairly substantial and time consuming modification
    for end users to implement. I spend much of my time in the SharePoint domain so poorly implemented buggy software (particularly hot-fixes) are the norm.

  17. dean says:

    Greetings, I've worked my way successfully through all of this, up to the point of recreating the ISO using Oscdimg. My paths are a little different so I adjusted the command accordingly: Sitting at the extract directory and fully-pathing oscdimg: "C:Program
    Files (x86)Windows Kits8.1Assessment and Deployment KitDeployment Toolsamd64OscdimgOscdimg.exe" -m –o –u2 –udfver102 –bootdata:2 #p0,e,bD:tempW2K12R2Extractbootetfsboot.com #pEF,e,bD:tempW2K12R2Extractefimicrosoftbootefisys.bin D:tempW2K12R2Extract
    d:tempW2k12R22012_r2_x64_dvd_2707946_KeyboardUpdate.iso I get an error on execution: Scanning source tree ERROR: Failure enumerating files in directory "D:TEMPW2K12R2EXTRACTûO" Error 3: The system cannot find the path specified. Sitting in the oscdimg
    directory and running: Oscdimg -m –o –u2 –udfver102 –bootdata:2 #p0,e,bD:tempW2K12R2Extractbootetfsboot.com #pEF,e,bD:tempW2K12R2Extractefimicrosoftbootefisys.bin D:tempW2K12R2Extract d:tempW2k12R22012_r2_x64_dvd_2707946_KeyboardUpdate.iso
    I get similar error, but on execution directory: Scanning source tree ERROR: Failure enumerating files in directory "C:PROGRAM FILES (X86)WINDOWS KITS8.1ASSESSMENT AND DEPLOYMENT KITDEPLOYMENT TOOLSAMD64OSCDIMGûO" Error 3: The system cannot find the
    path specified. So I'm stuck at last step. Any insight would be appreciated. Thanks ~dean~

  18. BOFH says:

    I get the same problem as Dean described above.
    Here is my commandline from the ADK Command Prompt on Win2012 R2 Datacenter:
    G:Workingextract>oscdimg –m –o –u2 –udfver102 –bootdata:2#p0,e,b"G:Workingextractbootetfsboot.com"#pEF,e,b"G:Workingextractefimicrosoftbootefisys.bin" "G:Workingextract" "G:WorkingWin2012r2_modified.iso"

    And the command output
    Scanning source tree
    ERROR: Failure enumerating files in directory "G:WORKINGEXTRACTûM"
    Error 3: The system cannot find the path specified.

    There is no such folder or file in there named "ûM", and I ran "chkdsk G: /f" to check the filesystem, it's intact.
    Any ideas?

  19. BOFH says:

    The command sems correct according to the last example in this article:

    I recorded the command execution with procmon.exe, it’s wierd, it creates four threads and then performs this in the filesystem (this time I ran oscdimg.exe from G:Working):
    "Process Name","Operation","Path","Result","Detail"
    "oscdimg.exe","CreateFile","G:Workingûo","NAME NOT FOUND","Desired Access: Read Attributes, Delete, Disposition: Open, Options: Non-Directory File, Open Reparse Point, Attributes: n/a, ShareMode: Read, Write, Delete, AllocationSize: n/a"
    "oscdimg.exe","CreateFile","G:WorkingûM","NAME NOT FOUND","Desired Access: Read Data/List Directory, Synchronize, Disposition: Open, Options: Directory, Synchronous IO Non-Alert, Attributes: n/a, ShareMode: Read, Write, Delete, AllocationSize: n/a"
    "oscdimg.exe","CreateFile","G:Working","SUCCESS","Desired Access: Read Data/List Directory, Synchronize, Disposition: Open, Options: Directory, Synchronous IO Non-Alert, Attributes: n/a, ShareMode: Read, Write, Delete, AllocationSize: n/a, OpenResult: Opened"
    "oscdimg.exe","QueryDirectory","G:WorkingûM","NO SUCH FILE","Filter: ûM"
    "oscdimg.exe","CreateFile","G:WorkingûM","NAME NOT FOUND","Desired Access: Read Data/List Directory, Synchronize, Disposition: Open, Options: Directory, Synchronous IO Non-Alert, Attributes: n/a, ShareMode: Read, Write, Delete, AllocationSize: n/a"

    Then it closes the threads and exits.

    What is it trying to create files with those garbled filenames, and then failing even?

  20. BOFH says:

    I found the problem with the error-message me and Dean got with oscdimg.exe.
    It's in Guy's user-comment here:

    The dash-characters in the text above are some "pretty-type" version, not the actual dash.
    Replace the "pretty" long dashes (the '–') with the correct dash character '-', then the command works.

    Maybe John Howard could be so kind and replace the character directly in the article? 🙂