Quantcast
Channel: Interfusion - WPF
Viewing all articles
Browse latest Browse all 3

Create a Hyper-V Virtual Machine with C#

$
0
0

Creating a Virtual Guest with C# took alot of trial and error even with the current resources on the web. So I thought I would publish a series on how to create a virtual machine and add the required resources. This will be the first in the series and will explain how to create the virtual machine. Later, I will publish how to add disk, ram, network, etc... First I will start with the primary method for creating the machine:

publicbool CreateVirtualServer(string vmName)
{
     bool SystemCreated = false;
     ManagementObject definedSystem = null;
     ConnectionOptions oConn = new ConnectionOptions();
     oConn.Username = strWMIUID;
     oConn.Password = strWMIPW;
     oConn.Authority = strWMIAuth;
     ManagementScope scope = new ManagementScope(@"\\" + strWMIHost + @"\ROOT\virtualization", oConn);
     ManagementObject virtualSystemService = GetServiceObject(scope, "
Msvm_VirtualSystemManagementService");
     ManagementBaseObject inParams = virtualSystemService.GetMethodParameters("
DefineVirtualSystem");
     inParams["
ResourcesettingData"] = null;
     inParams["
SourceSetting"] = null;
     inParams["
SystemSettingData"] = GetVirtualSystemGlobalSettingDataInstance(scope, vmName);
     ManagementBaseObject outParams = virtualSystemService.InvokeMethod("
DefineVirtualSystem", inParams, null);
           
     if ((UInt32)outParams["
ReturnValue"] == ReturnCode.Started)
     {
         if (JobCompleted(outParams, scope))
         {
             definedSystem = new ManagementObject(outParams["
DefinedSystem"].ToString());
                                    
             SystemCreated = true;
         }
         else
         {
             throw new ApplicationException("
Failed to define virtual system");
         }
     }
     else if ((UInt32)outParams["
ReturnValue"] == ReturnCode.Completed)
     {
         definedSystem = new ManagementObject(outParams["
DefinedSystem"].ToString());
         SystemCreated = true;
     }
     else
     {
         throw new ApplicationException("
Failed to define virtual system with " + outParams["ReturnValue"].ToString());
     }
     inParams.Dispose();
     outParams.Dispose();
     virtualSystemService.Dispose();
     return SystemCreated;
}

As you can see the method above requires 1 argument to be passed to it. The name of the machine as you want it to appear in the Hyper-V admin console. It returns true if the machine creation was successful and false if not. So I start out with the return bool being false. Then I create an instance of the ManagementObject which is a part of the System.Management namespace. I also create a ConnectionOptions instance and fill in the required properties. I am using string variables for this so that the code can be moved from one app to another and all that is needed is to define those variables somewhere in the application. The username and password have to be either a domain or server based user account that has the permissions to create the machine. The authority is either the domain or the servername and should look something like "ntlmdomain:servername". Next a ManagementScope is created which also requires another string variable within the WMI path. That string should be set to the name of the Host Hyper-V server that you would like to create this guest on. I am also passing it the ConnectionOptions instance created earlier. Next, another ManagementObject is created and calls a seperate method to get the default parameters needed to define the virtual system. Here is the code for that method:

publicstatic ManagementObject GetServiceObject(ManagementScope scope, string serviceName)
{
    scope.Connect();
    ManagementPath wmiPath = new ManagementPath(serviceName);
    ManagementClass serviceClass = new ManagementClass(scope, wmiPath, null);
    ManagementObjectCollection services = serviceClass.GetInstances();
    ManagementObject serviceObject = null;

    foreach (ManagementObject service in services)
    {
        serviceObject = service;
    }
    return serviceObject;
}

Once we have our ManagementObject, it is time to create a ManagementBaseObject so that we can get and set the parameters needed to create the guest machine. Then you set the required parameters and use the InvokeMethod to create the system and retrieve the returned results. Then you check the return value to see if it complete. For this you will need to create the following class:

staticclass ReturnCode
{
    publicconst UInt32 Completed = 0;
    publicconst UInt32 Started = 4096;
    publicconst UInt32 Failed = 32768;
    publicconst UInt32 AccessDenied = 32769;
    publicconst UInt32 NotSupported = 32770;
    publicconst UInt32 Unknown = 32771;
    publicconst UInt32 Timeout = 32772;
    publicconst UInt32 InvalidParameter = 32773;
    publicconst UInt32 SystemInUser = 32774;
    publicconst UInt32 InvalidState = 32775;
    publicconst UInt32 IncorrectDataType = 32776;
    publicconst UInt32 SystemNotAvailable = 32777;
    publicconst UInt32 OutofMemory = 32778;
}

Then run the JobCompleted method:

publicstaticbool JobCompleted(ManagementBaseObject outParams, ManagementScope scope)
{
    bool jobCompleted = true;
   
    string JobPath = (string)outParams["Job"];
    ManagementObject Job = new ManagementObject(scope, new ManagementPath(JobPath), null);
   
    Job.Get();
    while ((UInt16)Job["JobState"] == JobState.Starting || (UInt16)Job["JobState"] == JobState.Running)
    {
        //thrownew ApplicationException("In progress... " + Job["PercentComplete"] + " completed." );
        System.Threading.Thread.Sleep(1000);
        Job.Get();
    }
   
    UInt16 jobState = (UInt16)Job["JobState"];
    if (jobState != JobState.Completed)
    {
        UInt16 jobErrorCode = (UInt16)Job["ErrorCode"];
        thrownew ApplicationException("Error Code: " + jobErrorCode + "<br>ErrorDescription: " + (string)Job["ErrorDescription"]);
        jobCompleted = false;
    }
    return jobCompleted;
}

Then I populate a definedSystem ManagementObject with the outparams to be used later to add resources, etc... to the virtual machine.


Viewing all articles
Browse latest Browse all 3

Trending Articles