Friday, May 31, 2013

SCVMM: Install VM components Failed

I'm attempting to deploy a virtual machine from a template but I get this error: Install VM components: Failed.




Error (2940)
VMM is unable to complete the requested file transfer. The connection to the HTTP server 2012-SCVMM.bottheory.local could not be established.
Unknown error (0x80072ee2)

Recommended Action
Ensure that the HTTP service and/or the agent on the machine 2012-SCVMM.bottheory.local are installed and running and that a firewall is not blocking HTTP/HTTPS traffic on the configured port.



TL;DR
SO...  Long story short; if you are encountering this error, I would suggest booting your VHD file in a VM and re-sysprep /generalize it.  If you've maxed out on sysprep's I have a post earlier in my blog on how to get around the 3-times limit and rerun sysprep.  Alternatively, you can try what I did, but I can't gaurantee your success and replace the BCD file in your Library VHD with a BCD you *know* has been sysprepp'ed and try redeploying it.
=------------------------------------------------------------------------------------------------=

I've ensured that HTTP and HTTPS is not blocked (firewall is disabled) and the agent on my SCVMM machine is installed and running.  So this error message is somewhat useless.



So I took my two boxes, 2012-SCVMM (the SCVMM server) and S5000VXN-SERVER (the Hyper-V host) and procmon'ed them while it was attempting to "Install VM Components" to try and understand what it's trying to do.



After reinitating the task, we can see that the vmmAgent.exe on the Hyper-V host accesses the file about 2 seconds after I submit the command to retry the job.

A few seconds after this, it appears to "CreateFile" in the Windows\Temp directory; but this is not actually correct.



What it is really doing is *mounting* the VHD into a folder in the Windows\Temp directory.  You can actually watch this in action if you view Disk Management on the Hyper-V host while you execute the task.




So now that we know it's mounting the file as a volume this helps us narrow down on what Hyper-V is attempting to do...  And I suspect what it is attempting to do is "offline servicing" of the attached vdisk/vhd.



After attaching the vdisk the next thing it does it query the BCD file on the system.  Maybe it needs to be in a certain mode to operate?  I'm not sure...



Continuing on we can see that events are written to the Microsoft-Windows-FileShareShadowCopyProvider Operational.evtx, System.evtx, and Microsoft-Windows-Bits-CompactServer Operational.evtx event logs.  Examining each log at the time stamp showed the FileShareShadowCopyProvider and System log were just noticed of volume shadow copy starting, but the BITS event log was interesting.






It showed that it was doing something with the BCD file.  The Hyper-V host was *serving* it out.  I suspect it was serving it to the SCVMM.
Looking back at the SCVMM server we see that was executing some WinRM commands.  Sadly, we do not know what commands it was trying to send.

If I mount the vhd file and check out the BCD file I can see that it appears to be corrupted in that it doesn't know what the proper boot device should be.

C:\Windows\system32>bcdedit /store "K:\boot\bcd" /enum all

Windows Boot Manager
--------------------
identifier              {bootmgr}
device                  unknown
description             Windows Boot Manager
locale                  en-US
inherit                 {globalsettings}
bootshutdowndisabled    Yes
default                 {default}
resumeobject            {b520e13c-48da-11e2-9a8b-00155d011700}
displayorder            {default}
                        {7619dcc9-fafe-11d9-b411-000476eba25f}
toolsdisplayorder       {memdiag}
timeout                 3

Windows Boot Loader
-------------------
identifier              {7619dcc9-fafe-11d9-b411-000476eba25f}
device                  ramdisk=[boot]\sources\boot.wim,{7619dcc8-fafe-11d9-b411
-000476eba25f}
path                    \windows\system32\boot\winload.exe
description             Windows Setup
locale                  en-US
inherit                 {bootloadersettings}
osdevice                ramdisk=[boot]\sources\boot.wim,{7619dcc8-fafe-11d9-b411
-000476eba25f}
systemroot              \windows
detecthal               Yes
winpe                   Yes
ems                     Yes

Windows Boot Loader
-------------------
identifier              {default}
device                  unknown
path                    \Windows\system32\winload.exe
description             Windows Server 2012
locale                  en-US
inherit                 {bootloadersettings}
allowedinmemorysettings 0x15000075
osdevice                unknown
systemroot              \Windows
resumeobject            {b520e13c-48da-11e2-9a8b-00155d011700}
nx                      OptOut
detecthal               Yes

Resume from Hibernate
---------------------
identifier              {b520e13c-48da-11e2-9a8b-00155d011700}
device                  unknown
path                    \Windows\system32\winresume.exe
description             Windows Resume Application
locale                  en-US
inherit                 {resumeloadersettings}
allowedinmemorysettings 0x15000075
filepath                \hiberfil.sys

Windows Memory Tester
---------------------
identifier              {memdiag}
device                  unknown
path                    \boot\memtest.exe
description             Windows Memory Diagnostic
locale                  en-US
inherit                 {globalsettings}
badmemoryaccess         Yes

EMS Settings
------------
identifier              {emssettings}
bootems                 Yes

Debugger Settings
-----------------
identifier              {dbgsettings}
debugtype               Serial
debugport               1
baudrate                115200

RAM Defects
-----------
identifier              {badmemory}

Global Settings
---------------
identifier              {globalsettings}
inherit                 {dbgsettings}
                        {emssettings}
                        {badmemory}

Boot Loader Settings
--------------------
identifier              {bootloadersettings}
inherit                 {globalsettings}
                        {hypervisorsettings}

Hypervisor Settings
-------------------
identifier              {hypervisorsettings}
hypervisordebugtype     Serial
hypervisordebugport     1
hypervisorbaudrate      115200

Resume Loader Settings
----------------------
identifier              {resumeloadersettings}
inherit                 {globalsettings}

Device options
--------------
identifier              {7619dcc8-fafe-11d9-b411-000476eba25f}
ramdisksdidevice        boot
ramdisksdipath          \boot\boot.sdi

It's not actually corrupted though; the reason why the devices are unknown is because bcdedit isn't finding the disk signature of the volume I mounted.  But it has the disk signature because I can boot with it without issue.

Continuing on...

In order to try and find out what commands WSMAN was sending I enabled debugview on the SCVMM server:
http://support.microsoft.com/kb/970066?wa=wsignin1.0

I then reproduced the error by rerunning the Create Virtual Machine job.



DebugView gave me more information to narrow down what was happening.  It appears that the process is failing with:
[4276] 10B4.000C::05/31-12:52:00.894#16BcdUtil.cs(1987): bootDevice UnknownDevice
[4276] 10B4.000C::05/31-12:52:01.334#16MountedVhd.cs(91): MountedVhd windows volume not found
[4276] 10B4.000C::05/31-12:52:01.342#16VMAdditions.cs(874): VMAdditions install failed at OS detection phase for vm AirVid
[4276] 10B4.000C::05/31-12:52:01.388#16VMAdditions.cs(874): Microsoft.VirtualManager.Engine.VmOperations.MountedSystem+BootOrSystemVolumeNotFoundException: Virtual Machine Manager cannot locate the boot or system volume on virtual machine NO_PARAM. The resulting virtual machine might not start or operate properly. 

Doing some googling on this took me to a Korean Microsoft page where the following was stated:
http://social.technet.microsoft.com/Forums/ko-KR/momsmsmofko/thread/fedbc514-1fc0-4b55-979b-7d07babb074b/

When creating a new VM from template, and that template contains a blank VHD or a non-Windows OS or a Windows OS that has not been generalized (i.e. the OS is not sysprepped), then the job will fail because VMM expects a VM from template to go through the sysprep customization process (hence why we ask for an OS profile). VMM will crack open the VHD and check of the OS is in a sysprep state. If not, then the job will fail. To create a proper template, you can use an existing Vm with a running Windows OS (right click on it and select New Template… this will kick off sysprep in the OS and then store the VM to Library as template… this removes the original VM). Or… if you already have VHDs that have been sysprepped, simply import them to the Library and then when you create a new template… attach that VHD instead of the blank one. Last… you can create a new template that does not require a sysprepped OS by selecting ‘Customization Not Required’ from the Guest OS profile dropdown:
http://blogs.technet.com/b/hectorl/archive/2008/08/21/digging-deeper-into-error-13206-virtual-machine-manager-cannot-locate-the-boot-or-system-volume-on-virtual-machine.aspx

Thinking about it, I do not think my VHD was SysPrep'ed.  I find it interesting that sysprep appears to do something to the BCD file.  To find out what sysprep does to the BCD file I booted up my 2012 VHD into Windows and ran sysprep, generalize and shutdown.


With the VM now generalized I can crack open the VHD and see what's added to the BCD to make it so special...

C:\Users\amttye\Desktop>fc before-sysprep.txt after-sysprep.txt
Comparing files before-sysprep.txt and AFTER-SYSPREP.TXT
***** before-sysprep.txt
identifier              {bootmgr}
device                  partition=K:
description             Windows Boot Manager
***** AFTER-SYSPREP.TXT
identifier              {bootmgr}
device                  locate=unknown
description             Windows Boot Manager
*****

***** before-sysprep.txt
toolsdisplayorder       {memdiag}
timeout                 3

***** AFTER-SYSPREP.TXT
toolsdisplayorder       {memdiag}
timeout                 30

*****

***** before-sysprep.txt
identifier              {default}
device                  partition=K:
path                    \Windows\system32\winload.exe
***** AFTER-SYSPREP.TXT
identifier              {default}
device                  locate=\Windows\system32\winload.exe
path                    \Windows\system32\winload.exe
*****

***** before-sysprep.txt
inherit                 {bootloadersettings}
allowedinmemorysettings 0x15000075
osdevice                partition=K:
systemroot              \Windows
***** AFTER-SYSPREP.TXT
inherit                 {bootloadersettings}
recoveryenabled         No
allowedinmemorysettings 0x15000075
osdevice                locate=\Windows
systemroot              \Windows
*****

***** before-sysprep.txt
nx                      OptOut
detecthal               Yes

***** AFTER-SYSPREP.TXT
nx                      OptOut

*****

***** before-sysprep.txt
identifier              {b520e13c-48da-11e2-9a8b-00155d011700}
device                  partition=K:
path                    \Windows\system32\winresume.exe
***** AFTER-SYSPREP.TXT
identifier              {b520e13c-48da-11e2-9a8b-00155d011700}
device                  locate=\Windows\system32\winresume.exe
path                    \Windows\system32\winresume.exe
*****

***** before-sysprep.txt
inherit                 {resumeloadersettings}
allowedinmemorysettings 0x15000075
filepath                \hiberfil.sys

***** AFTER-SYSPREP.TXT
inherit                 {resumeloadersettings}
recoveryenabled         No
allowedinmemorysettings 0x15000075
filedevice              locate=\hiberfil.sys
filepath                \hiberfil.sys
debugoptionenabled      No

*****

***** before-sysprep.txt
identifier              {memdiag}
device                  unknown
path                    \boot\memtest.exe
***** AFTER-SYSPREP.TXT
identifier              {memdiag}
device                  locate=\boot\memtest.exe
path                    \boot\memtest.exe
*****

Interestinginly the differences appear to be mostly "locate=%%".  I guess this would make sense as the assumption is the BCD is being moved to a new disk with a new disk signature and so it can't lock on to the existing signature.  Some other oddities is the removal of "detecthal" and explicit declarations of debugoptionenabled and recoveryenabled.  I suspect that a generalized BCD file is portable, so I'm going to extract it from this image and inject it into my previously "failing" image.  I then edited the template and removed the old VHD and added the new one.



And..........?  Lets go to DebugView:

[4276] 10B4.000C::05/31-13:57:40.193#16SystemInformation.cs(192): SYSTEM: :\ Version=0.0 HALType=  Memory=2MB, Procs=1 Is64s=False . OSLanguage=0
[4276] 10B4.000C::05/31-13:57:40.193#16SystemInformation.cs(970): Lookup for '\??\Volume{b42a3001-c871-11e2-93f4-0015172fc019}' in MountedDevices
[4276] 10B4.000C::05/31-13:57:40.193#16SystemInformation.cs(764): DISK: 10, signature=a9083c0a #partitions 1
[4276] 10B4.000C::05/31-13:57:40.194#16SystemInformation.cs(768):  PARTITION: 10.0 Bootable=True, #LDs 1
[4276] 10B4.000C::05/31-13:57:40.194#16SystemInformation.cs(775):   LOGICALDRIVE: \\?\Volume{b42a3001-c871-11e2-93f4-0015172fc019}\(\\?\Volume{b42a3001-c871-11e2-93f4-0015172fc019}\), WindowsDrive=True, IsBoot=False, BootSectorType=Bootmgr, FullSize=136363114496, [1048576-136364163072]
[4276] 10B4.000C::05/31-13:57:40.194#16MountedVhd.cs(623): FindBootVol \\?\Volume{b42a3001-c871-11e2-93f4-0015172fc019}\, found boot drive candidate
[4276] 10B4.000C::05/31-13:57:40.194#16MountedVhd.cs(308): Bootmgr boot loader
[4276] 10B4.000C::05/31-13:57:40.194#16MountedVhd.cs(1053): Trying to get the mounted point for volume \\?\Volume{b42a3001-c871-11e2-93f4-0015172fc019}\.
[4276] 10B4.000C::05/31-13:57:40.196#16CommonUtils.cs(171): Fixup & Copy 'C:\Windows\TEMP\tmp2E1.tmp\boot\bcd' to C:\Users\svc_scvmm\AppData\Local\Temp\tmpA2F4.tmp
[4276] 10B4.000C::05/31-13:57:40.196#04BitsDeployer.cs(1392): Deploy file C:\Windows\TEMP\tmp2E1.tmp\boot\bcd from s5000vxn-server.bottheory.local to C:\Users\svc_scvmm\AppData\Local\Temp\tmpA2F4.tmp on 2012-SCVMM.bottheory.local





Voila!  It appears much better than before.  It found the drive correctly and checked the BCD file and found it is the "Generalize" state.  The *actual* image I originally made was NOT sysprep'ed and all I did was replace the BCD file, but it allowed it to continue beyond and the machine actually completed the imaging process properly.  It joined the domain and whatever else the answer file was I gave it in SCVMM.

It appears I was correct in my earlier assumption about what SCVMM is doing.  It goes and grabs the BCD file and transfers it from the target machine to itself, "fixes it up" (not sure what it's doing at this stage precisely), then sends it back for injection.  Certainly a bit of a complicated process with a fair bit that can go wrong, but shame on Microsoft for having such a poor error message.  I suspect it wouldn't have required much effort to push out a real message; something to the effect of, "The BCD of this vDisk does not appear to have been through the sysprep /generalize process.  Please rerun sysprep against the image and try again".

SO...  Long story short; if you are encountering this error, I would suggest booting your VHD file in a VM and re-sysprep /generalize it.  If you've maxed out on sysprep's I have a post earlier in my blog on how to get around the 3-times limit and rerun sysprep.  Alternatively, you can try what I did, but I can't gaurantee your success and replace the BCD file in your Library VHD with a BCD you *know* has been sysprepp'ed and try redeploying it.

1 comment:

Anonymous said...

I´m having the exact same error but not for the OS disk. The error only occurs when I try to add an empty VHDX-file as a secondary data disk in the hardware profile. Tried different data disks here.

Any thoughts on this?