In this article, we examined the Microsoft Hyper-V control problems when managing the hypervisor with the help of the C++ language and WMI technology.
The attached example represents a small library of classes for managing Microsoft Hyper-V hypervisor and a test application, which uses the part of the library functionality.
1.1. The notion of hypervisor. Brief survey of existing products
Hypervisor, also called virtual machine monitor (VMM), is the special software that allows running several operating systems (OS) on the single physical computer. For each of these operating systems, the hypervisor creates an illusion of functioning on its own physical computer, which is called the virtual machine (VM).
The operating system, on which the hypervisor works, is called the host OS, and operating systems that are launched on virtual machines are called guest OS. The hypervisor monitors the work of guest OS and influences the process of their launching (unnoticeably for these OS) in that way to eliminate conflicts between them and the host OS.
There are two types of hypervisors:
- Native or bare-metal hypervisors, which work directly with the computer hardware and do not require the presence of the conventional OS (such hypervisors are the operating systems in some way or they can be implemented on the basis of some cut universal OS).
- Hosted hypervisors, which are the software that is running within a conventional OS (such as Windows or Linux).
Examples of hypervisors of the first type are the Microsoft Hyper-V (as a part of Windows Server 2008 (R2) and the self-contained version – Microsoft Hyper-V Server 2008 (R2)), VMware ESX(i), Citrix XenServer and others. The hypervisors of the second type are the VMware Workstation, Oracle (the former Sun) VirtualBox, Microsoft Virtual PC and others.
1.2. Microsoft Hyper-V hypervisor
Microsoft Hyper-V hypervisor was introduced in 2008 as a part of Windows Server 2008 and also was released as a free stand-alone version – Microsoft Hyper-V Server 2008. It is also included into the R2 (Release 2) version of these products. Hyper-V functions only on x86-64-compatible processors (the IA-64 architecture is not supported) with the AMD64/EM64T technology, which support the virtualization technology (AMD-V or Intel VT).
For Windows Server 2008 (R2), the hypervisor is installed as a separate role. It is managed through the standard management console. Also the program control of the hypervisor is possible by means of Microsoft WMI technology.
2. The Microsoft Hyper-V program control
2.1. WMI technology
WMItechnology (Windows Management Instrumentation) is Microsoft's implementation of the Web-Based Enterprise Management (WBEM) and Common Information Model (CIM) standards from the Distributed Management Task Force (DMTF). WMI is a program infrastructure for managing various Windows OS components and also third-party products. The WMI technology is designed with taking into account its possible usage with different programming language: C/C++, Visual Basic, scripting languages (such as VBScript or JScript) and languages that belong to .NET family (for example, C#). Thus, developers can use WMI in their programs for performing specific tasks and administrators can use it in their scripts to optimize their chores. WMI allows managing both local and remote computers.
COM/DCOM technologies are the basis of WMI technology, so it is useful to know them well before studying WMI. WMI uses object-oriented model, where managed components are represented as the set of connected objects with their own properties and methods. All objects form the object database, which is called the CIM repository. A special SQL-like query language – WQL (WMI Query Language) – is used for managing the repository.
Special program component (called WMI provider) is required if some Windows component or application should support WMI management interface. Microsoft supplies the Windows OS with the set of standard WMI providers, such as Active Directory Provider, DNS Provider, Event Log Provider, Security Provider, System Registry Provider, Virtualization Provider, Windows Installer Provider, and others. Besides, such products as SQL Server, Exchange Server also install their own WMI providers.
Virtualization Provider is designed for managing Microsoft Hyper-V hypervisor and will be examined in detail in the article.
I recommend you to acquaint yourselves with the WMI fundamentals before using this technology for interaction with Virtualization Provider or any other provider.
2.2. Description of main WMI objects for Hyper-V management
Let’s briefly examine some WMI classes provided by the virtualization provider.
Msvm_ComputerSystem WMI class is the basis of the Hyper-V object model. This class represents either a physical, or a virtual machine. The class has a lot of properties but let’s examine some of them:
Captioncontains "Virtual Machine" string if the class represents a virtual machine or "Hosting Computer System" string if it is a physical machine. We can distinguish virtual and physical machines by this property value when we write WQL queries to the provider.
ElementNamecontains the display name of the virtual machine (it is displayed in the list of virtual machines in the manager console) or its NETBIOS name if it is a physical machine.
Namecontains a unique identifier (GUID) of virtual machine.
EnabledStatedefines the state of the virtual machine (stopped, running, paused, etc.).
RequestStateChange method of the
Msvm_ComputerSystem class allows modifying the state of the virtual machine (for example, to launch or to stop it).
Msvm_VirtualSystemManagementService class represents a virtualization service and is used for creating, deleting, and modifying virtual machines, and also for creating virtual machine snapshots, exporting and importing VMs. Let’s examine some methods of this class:
ModifyVirtualSystemmethods are used for creating, deleting, and modifying VMs, respectively.
RemoveVirtualSystemSnapshotmethods aim at snapshots creation, rollback to a snapshot, and snapshot deletion, respectively.
ImportVirtualSystem(Ex)methods aim at VM export and import.
Msvm_VirtualSystemSettingData class provides a set of properties, which represent the low-level settings of the VM, for example:
AutoActivate– it defines if the VM should start automatically at the hypervisor startup.
BIOSNumLock– it defines the state of the Num Lock key during the VM starting.
BootOrder– it defines the order of boot devices (hard drive, CD-ROM, etc.).
Each instance of the
Msvm_VirtualSystemSettingData class corresponds either to the VM itself, or to one of its snapshots. It is defined by the value of the
SettingType property (value 3 corresponds to a VM, 5 corresponds to a snapshot). The
SystemName property contains the GUID of the VM, which corresponds to the given instance of the
Msvm_VirtualSystemSettingData class. Thus, we can find all snapshots of the given VM by means of filtering all instances of the
Msvm_VirtualSystemSettingData class by the values of
Msvm_ResourceAllocationSettingData class represents virtual resources, which are associated with some VM, for example, virtual hard drive, IDE controller, network adapter, COM port, etc. The
ResourceType property defines the type of this resource and the
Connection property defines which “physical entity” corresponds to this resource. Thus, for the virtual drive, this property contains the path to the corresponding VHD file (disk image).
For more information about these and other classes, see MSDN.
2.3. Connecting to a hypervisor
Let’s examine how we can implement basic Hyper-V management operations using C++. As the WMI technology is based on COM, we will use the
ATL library (ATL – Active Template Library – is a part of the Microsoft Visual Studio and contains a large toolset, which can be used to solve typical development tasks within the bounds of COM development)). Actually, we will use only some simple wrapper classes for the COM types, such as
CComPtr (a “smart” pointer to COM interfaces, which automatically calls the
Release methods of the interfaces) and
CComBSTR (a wrapper for the BSTR string type).
Also we will define the auxiliary
CHK_HRES macro (from “check HRESULT”), which is intended for COM errors checking. Each COM method must return the special status of the
HRESULT type. We could analyze this status after each call of the COM method and perform the corresponding handling. But for the code facilitation, it is better to use the macro, which automatically analyzes the status and throws an exception in case of an error. The
CHK_HRES macro is defined in the following way:
CAtlException exception class, which just stores the corresponding
HRESULT status. We can process thrown exception in any suitable place. We will use the
CHK_HRES macro in the following way:
So, let’s proceed to the first task, namely, connecting to a hypervisor:
In this very example, the
pServer is a string containing the network address of the Hyper-V server. It can be the IP address or the name of the computer in the network.
pUserName is the user name and
pPassword is the user password, which are used to connect to the server. The user name can be of the “DOMAIN\USER” form. If we pass
NULL to the
ConnectServer method as the user name and the user password, then current user will be used for the connection.
ConnectServer method returns the pointer (
pWbemServices) to the
IWbemServices WMI interface, which represents the WMI services that are provided by the given Hyper-V server.
To disconnect from the server, we should release the pointer to the
IWbemServices interface by calling the
Release method (the
CComPtr class performs it automatically in its destructor).
2.4. Obtaining the list of virtual machines
To obtain the list of all virtual machines of the server, it is necessary to form the corresponding WQL query. As it was mentioned in the section 2.2, the
Msvm_ComputerSystem WMI class corresponds to virtual machines. But as this class can represent not only the virtual machine but also the Hyper-V server itself, we should filter objects by the value of the
In this example, we use the
ExecQuery method of the
IWbemServices interface, which allows performing some WQL query and returns the result in the form of enumerator object. The last implements the
IEnumWbemClassObject WMI interface. We can receive the list of objects, which implement the
IWbemClassObject WMI interface, by using this enumerator. In our case, these will be the objects that represent the virtual machines.
2.5. Obtaining the properties of the virtual machine
IWbemClassObject interface has the
Get method, which allows obtaining the values of the corresponding object properties. The properties can be of different types (for example, string or number) but there is a single method for all of them. So, the method returns the values of properties in the form of
VARIANT COM type, which allows representing the values of different types. We will use the
CComVariant class – the ATL wrapper for the
In the example above, we get the value of the
Name property (the unique identifier) of the
pVmObject virtual machine. We expect that the value of this property will be returned as a string. That is why it is better to check if we got the value of the required type in the
Name variable to ensure the code reliability.
This code can be used for obtaining the properties of other objects that are represented by the
IWbemClassObject interface (not only for virtual machines).
2.6. Start, stop and status check of the virtual machine
Now we can read the properties of the virtual machine and know its state. The
Msvm_ComputerSystem class has the
EnabledState property. Its value is some number, which characterizes the current state of the virtual machine. There is a set of reserved constants describing different states of the VM. For example, 2 means that the VM is launched, 3 means that it is shut down (for more information, see MSDN).
That is why, it is enough to read the
EnabledState property of the VM (the
Get method must return the
VT_14 VARIANT type value) and to compare it with 2 in order to check if the virtual machine is launched at the moment.
Let’s move to more difficult things. You cannot change the value of the
EnabledState property to launch or stop the VM, because this property is read only. The
Msvm_ComputerSystem class has the
RequestStateChange method for changing the VM state.
The call of the WMI method is more complicated task than obtaining the property. To call the method, we should do the following:
- Get the object that represents the input parameters of the method.
- Set the values of the input parameters by setting the values of the corresponding properties of this object.
- Call the method and receive the object that represents the output parameters of the method if necessary.
- Obtain the values of the output parameters by reading the values of corresponding properties of this object.
So, let’s obtain the object that represents the input parameters of the
First, we obtain the pointer to the object, which represents the
Msvm_ComputerSystem class, with the help of the
GetObject method. This object does not correspond to some definite virtual machine or server but represents the class itself.
Then, with the help of the
GetMethod, we obtain the information about the input parameters of the required method. This information is contained in the object, to which the
pInParamsDefinition pointer refers (we do not obtain the information about the output parameters in this example because we are not interested in them).
And finally, with the help of the
SpawnInstance method, we create an object that represents the values of the input parameters.
Now we can set the values of the input parameters of the
RequestStateChange method. We have only one such parameter. This is the
RequestState parameter. It can possess the same values as the
EnabledState property of the
Msvm_ComputerSystem class does.
state is the state code of the VM, which we are going to set. Now almost everything is ready for the call of the method:
We use the
ExecMethod method of the
IWbemServices interface to call the method of the
ExecMethod receives such parameters: repository path to the object, whose method should be called (we receive the object path of the VM by reading its
__PATH property); the method name; and the pointer to the object, which stores the values of the input parameters. After performing, the
ExecMethod returns the pointer to the object, which stores the values of the output parameters. We can obtain the values of the output parameters by reading the corresponding properties of this object.
RequestStateChange has the
Job output parameter. It contains the reference to the object, with the help of which you can track the task execution if the method is performed asynchronously. But we will not dwell on it. The example of using this parameter is in the file attached to the article.
It is worth mentioning that by changing the state of the VM to Disabled (3), we will shut it down without saving any data (as if we unplugged the power cable of the physical computer). In most cases, we would like to shut down the VM in a more delicate way, for example, by means of the guest OS (as if we clicked
Start – Shut Down in the guest OS). Luckily, Hyper-V gives such opportunity and provides the special
Msvm_ShutdownComponent class for these purposes.
Msvm_ShutdownComponent class has the
InitiateShutdown method, which initiates the VM shutdown (as it follows from its name). But in order to use it, we must find the instance of the
Msvm_ShutdownComponent class, which corresponds to our virtual machine. The instances of the
Msvm_ShutdownComponent classes do not refer one to another but they are connected via the special
Msvm_SystemDevice class. In the WMI terminology, the instance of the
Msvm_ShutdownComponent class is associated with the instance of the
Msvm_ComputerSystem class. There is a special
ASSOCIATORS OF operator in the WQL language for searching the associated objects (for more information, see MSDN). Let’s examine how we can find the required instance of the
First, we get the path in the repository to our VM. Then we form the WQL query for obtaining the associated instance of the
Msvm_ShutdownComponent class and call the
ExecQuery method for performing the query. Finally, we receive the pointer to
Msvm_ShutdownComponent from the enumerator object.
Now we can shut the VM down.
In this article, we examined the problems of Microsoft Hyper-V program control with the help of the C++ language and WMI technology. Examples that were given in the article will help you to get the common idea of solving the typical tasks on Hyper-V management by the programs written in C++ language and Microsoft Hyper-V management trobleshooting. Of course, we could not examine many more complicated tasks (such as managing devices of the VM) within the limits of the introductory article. But the WMI interface of Hyper-V is rather clearly documented in MSDN and you can solve your tasks yourselves with its help. Besides, you can google and find many examples of solving the tasks on Hyper-V management using different programming languages, including scripting languages. As a rule, these examples can be easily translated to the C++ language, if necessary.
4. Useful links
- Hypervisors. http://en.wikipedia.org/wiki/Hypervisor
- Hyper-V. http://en.wikipedia.org/wiki/Hyper-V
- WMI. http://msdn.microsoft.com/en-us/library/aa394582%28VS.85%29.aspx
- WMI. http://en.wikipedia.org/wiki/Windows_Management_Instrumentation
- WMI providers. http://msdn.microsoft.com/en-us/library/aa394570%28VS.85%29.aspx
- Hyper-V WMI Provider. http://msdn.microsoft.com/en-us/library/cc136992%28v=VS.85%29.aspx
- Useful blog on managing Hyper-V with the help of scripts (with code examples). http://dungkhoang.spaces.live.com/?_c11_BlogPart_pagedir=Next&_c11_BlogPart_handle=cns!31A50D02D661C816!192&_c11_BlogPart_BlogPart=blogview&_c=BlogPart
5. Attachment. The source code of the example
The attached example represents a small library of classes for managing the Hyper-V hypervisor and the test application, which uses the part of the library functionality.
The library contains two classes: the
CHyperV class and the
CHyperVVirtualMachine class. The
CHyperV class allows connecting to the Hyper-V server and obtaining the list of all virtual machines or separate virtual machine. The
CHyperVVirtualMachine class represents an individual virtual machine and allows obtaining some of its properties and controlling its state.
The test application allows connecting to the specified server (parameters are set in the command line) and displays the list of all virtual machines.
DNS name and
IPv4 address are also defined for the running virtual machines.
The example is designed for the Microsoft Visual Studio 2008.
Take a look at the Apriorit Virtualization project experience
Learn more about Apriorit hypervisor-level technologies: Virtual machine file system access SDK