Hyper-V: Why is networking reset in my VM when I copy a VHD?
This is a question I’ve seen come up a few times so figured it was time to examine why in a little more detail. In Virtual Server, you were able to copy VHDs and the associated VMC (Virtual Machine Configuration) file from one host to another, add the VMC to the other host and everything would work. In Hyper-V however, this is not the case due to improvements in our security model.
The supported way of copying a virtual machine from one Hyper-V enabled server to another is to use the export and import functionality in Hyper-V Manager. However, there are few situations I’ve seen where some creative workarounds have been necessary.
Consider the case where you store a VHD on a different physical drive than the VM configuration, and the physical drive holding the configuration gets corrupted or re-imaged for some reason and the original configuration is “lost”. Let’s suppose further that the virtual machine contains some very specific IP configuration settings on one or more network adapters – maybe it’s a router of some kind, for example.
In this scenario, the obvious thing to do is to create a new virtual machine with a similar configuration, add the VHD(s) and start it up. When you log on to the VM, you’ll see that the originally configured IP settings are no longer present. The reason for this is that the “GUID” of the original network adapter was stored in the “lost” configuration. So when a new configuration is created, when a synthetic NIC is added, a new GUID is generated. When the virtual machine starts, plug-and-play see this new NIC, as a completely different NIC, just like as you would in a physical machine.
Of course, you can, in most circumstances (I’m not aware of any Microsoft applications which you can’t do this on) reset the IP configuration, change the application(s) to bind to the new network adapter and all is good. Apart, that is, from that reminder from Windows that another adapter already has that IP address, as shown below.
There's a KB article outlining how to remove those hidden network adapters. (Although targeted for XP, this appears to also work on Windows Server 2008).
So that explains what’s going on. The rest of this article really just digs a tad deeper for a little more insight into how Hyper-V operates under the covers, and see if there’s another way to approach this.
Let’s go back and go through what we’ve done so far:
- Created a (Windows Server 2008) virtual machine with a single “synthetic” NIC
- Assigned a static IPv4 address of 192.168.200.248.
- Deleted the virtual machine using Hyper-V manager (this doesn’t delete the VHD).
- Created a new virtual machine using the same VHD and a single “synthetic” NIC.
- In Network Connections (ncpa.cpl), you see Local Area Connection n where n does not match what would have been seen in the original VM
- For that same “Local Area Connection n” network connection, you’ll see the device name is “Microsoft Virtual Machine Bus Network Adapter #m” where m does not match what you would have seen in the original VM (or may have been missing entirely).
Now perform the steps in the KB article so that we can see the “old” NIC in device manager. From an elevated command prompt:
- set devmgr_show_nonpresent_devices=1
- start devmgmt.msc
- On the menu bar: View/Show hidden devices
- Expand the Network adapters node
There are two NICs. Let’s take a closer look at the dimmed adapter (the one highlighted) by selecting properties, switching to the details tab and selecting Hardware Ids from the dropdown. In particular, notice the first line highlighted which is a GUID, in this example, starting f61bbefc-.
This is the VMBus “Channel Offer GUID” for the “old” NIC. Let’s do the same with the currently configured NIC.
Notice that the highlighted GUIDs are different – the new one, in my case, starts 944fafdc. (Another way to retrieve this GUID is to extract it from the registry – a little harder, but absolutely possible.) Now a bit of background information – let’s take a look at the XML configuration file for the current virtual machine. By default, the XML configuration files are stored under \programdata\microsoft\windows\hyper-v\virtual machines. BUT – it’s totally unsupported to edit these files manually, and we entirely reserve the right to change the format at any point in time. There’s no harm though taking a peek at a section of it. Notice the highlighted line (ChannelInstanceGuid) matches 944fafdc….
So you’ve probably now worked it out. We know the old “ChannelInstanceGuid” from the device manager screenshot above, and need to create a VM configuration with that same ChannelInstanceGuid. As I mentioned above, it’s totally unsupported to hand-edit the configuration file, so we have to use an alternate mechanism. We expose this property in our WMI model (http://msdn.microsoft.com/en-us/library/cc136992(VS.85).aspx). Specifically, it’s the first element of the array Msvm_SyntheticEthernetPortSettingData.VirtualSystemIdentifiers which needs updating. I’ll leave the actual scripting sample up to someone else – there’s various examples out there on the Internet of how to use the Hyper-V WMI model.
Hope that was of interest.