There is a hidden feature in Server 2012. Buried deep in the bowels of the WMI classes is this little tidbit that is discoverable, but not talked about.
You can set the IP of a VM through Hyper-V 2012.
For a long time now, in the forums we have told folks that this cannot be done. Well, it can be. And at small scale it works. I have used it to set up my Network Virtualization demonstration environment.
The thing that you need to be aware of is that this is one of those cases where you send your command to WMI / CIM and you need to double back and check what happened. Did the IP actually set?
Be sure to check that before going off and expecting that it did. If it didn’t, you have event logs in the VM. Check there.
This took a bit of working through and discovery. I never did work through IPv6, I stopped when I got IPv4 working.
As you might imagine, there has to be a dependency on the aligning of the version of the Integration Services within the VM and the Hyper-V Server. I could not imagine this working with Hyper-V 2012 and a Server 2008 VM when the Integration Components in the VM have not been updated to the current Hyper-V level.
One thing that I did not blog about with the Network Virtualization script was how I set up my environment, more on that next, I scripted it, and it is not small.
Back the the subject, setting the IP of a VM through WMI of the Hyper-V Server. I am going to leave out all the error handling just to make this easier to read through.
Here is a PowerShell function where you can see the WMI in action:
function Set-VMIPAddress ($VMName, $IPSettings)
$Service = Get-WmiObject -Class "Msvm_VirtualSystemManagementService" -Namespace "root\virtualization\v2"
$Query = "SELECT * FROM Msvm_ComputerSystem WHERE ElementName = '" + $VMName + "'"
$VM = Get-WmiObject -Query $Query -Namespace "root\virtualization\v2"
$setIP = $Service.SetGuestNetworkAdapterConfiguration($VM, $IPSettings.GetText(1))
Of course, you want to consider $setIP.ReturnValue
Like all WMI / CIM commands if the return value is “0” then you have success, “4096” generally means it is running. And anything else means something went wrong in most cases.
If you have “4096” then query for the status of the job itself. $job = [WMI]$setIP.job
By the way, if you want to get the IP of the VM don’t think $Service.GetGuestNetworkAdapterConfiguration. This is proper thinking for PowerShell but not for WMI / CIM. CIM could never be that easy. ;-)
Look for the class Msvm_GuestNetworkAdapterConfiguration to get the IP of a VM. Find the VM NIC with Msvm_SyntheticEthernetPortSettingData first.