none
How to distinguish Win2012R2 and Win2016 Hyper-V Server

    Question

  • I've got a C# program that creates and runs VMs - this works with Win2008 and Win2012R2 Hyper-V servers. Those servers support different protocol versions (using ManagementScope(\\localhost\root\virtualization\<v1 or v2>).

    Win2016 Hyper-V appears to only support v2 - but there are 2 differences from Win2012R2 that I have found (so far).

    The first is that I cannot enumerate a VM's serial port from its Msvm_ResourceAllocationSettingData - I have to find the SerialController and enumerate its child objects. This is pretty easily handled in my code (for more details on this issue see https://social.technet.microsoft.com/Forums/windowsserver/en-US/4ba241c2-271a-472c-8e5c-2b714a165563/problems-using-wmi-to-hyperv-on-windows-2016-server?forum=winserverhyperv#4ba241c2-271a-472c-8e5c-2b714a165563)

    The 2nd problem is trickier - I have to set the VM's virtual hard disk resiliency in Win2016, otherwise I get an error about this when I try to start the VM. This is a 1 line code change (see below), by adding the AutomaticCriticalErrorAction setting when I create the VM.

    But I cannot add this setting when I am using a Wind2012R2 server, and I need this program to support both hypervisors.

    I'm looking for suggestions on how I can determine which flavor of Hyper-V server I am communicating with. And since my code is often running on a VM (Win2012/2016) using a remote Hyper-V server, I cannot query the server the code is running on.

                ManagementPath settingPath = new ManagementPath("Msvm_VirtualSystemSettingData");
                ManagementClass settingClass = new ManagementClass(virtualizationScope, settingPath, null);
                ManagementObject settingData = settingClass.CreateInstance();

                settingData["ElementName"] = vmName;
                settingData["AutomaticStartupAction"] = 2; // None
                settingData["AutomaticShutdownAction"] = 3; // Save state
                settingData["AutomaticRecoveryAction"] = 2; // None
                settingData["AutomaticCriticalErrorAction"] = 0; // None

                ManagementBaseObject inParams = service.GetMethodParameters("DefineSystem");
                inParams["SystemSettings"] = settingData.GetText(TextFormat.CimDtd20);
                inParams["ResourceSettings"] = null;
                inParams["ReferenceConfiguration"] = null;
                ManagementBaseObject outParams = InvokeObjectMethod(service, "DefineSystem", inParams);

    Tuesday, March 7, 2017 5:03 PM

All replies

  • Hi Sir,

    >>Those servers support different protocol versions (using ManagementScope(\\localhost\root\virtualization\<v1 or v2>).

    Based on my understanding , you may add an additional branch for "v2" , and , check the OS version to determine which one is 2012R2 or 2016 .

    Powershell command (check OS version ) :

    gwmi -query "select * from win32_operatingsystem"

    Best Regards,

    Elton


    Please remember to mark the replies as answers if they help.
    If you have feedback for TechNet Subscriber Support, contact tnmff@microsoft.com.

    Wednesday, March 8, 2017 7:30 AM
    Moderator
  • My program is not always running on the Hyper-V server - it can run on a Win2012R2 host (typically in a VM) and it may be connecting to Hyper-V on a remote host, so querying the local host doesn't solve the problem.

    Thanks for the response...

    Wednesday, March 8, 2017 1:20 PM
  • Any reason you cannot issue the same query against the remote host?

    . : | : . : | : . tim

    Wednesday, March 8, 2017 1:59 PM
  • Good question - I wasn't aware how to do that using the Win32 API from my C# program
    Wednesday, March 8, 2017 5:13 PM
  • Good question - I wasn't aware how to do that using the Win32 API from my C# program

    System.Management.ManagementPath objects include a Server property. It can be set during initialization if you want. I didn't test this exact line, but this or something very like it will work:

    ManagementPath settingPath = new ManagementPath(String.Format("\\\\{0}\\{1}", varComputerName, "Msvm_VirtualSystemSettingData"));

    Use "." for the local system. You could also use the same constructor that you have but conditionally set Server after creation.


    Eric Siron
    Altaro Hyper-V Blog
    I am an independent contributor, not an Altaro employee. I accept all responsibility for the content of my posts. You accept all responsibility for any actions that you take based on the content of my posts.

    Wednesday, March 8, 2017 9:17 PM
  • Thanks for the responses. For now, I'm just surrounding the (potentially) offending line with a try/catch. I may revisit this later if I find more places where the 2 servers exhibit different behavior.   

                try
                {
                    // Win2016 Hyper-V server fails to start VM if we do not set this element.
                    settingData["AutomaticCriticalErrorAction"] = 0; // None
                }
                catch (Exception e)
                {
                    // Win2012 Hyper-V server doesn't support this element.
                }

    Thursday, March 9, 2017 7:21 PM