使用特定硬件创建新的Hyper-V VM(使用WMI)

时间:2013-04-01 19:58:37

标签: c# wmi virtual-machine hyper-v

我想创建一个具有确定数量的RAM,网卡,处理器内核数量的新Hyper-V VM,并将VHD文件附加到IDE控制器。

问题是Msvm_ResourceAllocationSettingData不是很容易使用。我正在使用的代码不起作用(这是将VHD附加到现有VM的代码,但是我也想在创建新的VHD时使用它。)

public void AttachVhd(IdeChannel ideChannel, String vhdPath) {

        // Get VirtualSystemSettingData
        ManagementObject vssd = this.GetVirtualSystemSettingData();

        // Get the IDE Controller
        ManagementObject ideController = this.GetResourceAllocationSettingData(ResourceType.IdeController, ResourceSubType.IdeController);

        // Create synthetic disk:
        ManagementObject syntheticDiskRasd = this.GetResourceAllocationSettingData(ResourceType.Disk, ResourceSubType.DiskSynthetic);
        syntheticDiskRasd["Parent"]  = ideController.Path;
        syntheticDiskRasd["Address"] = ideChannel == IdeChannel.Primary ? "0" : "1";

        this.AddVirtualSystemResources(syntheticDiskRasd);

        // Attach it
        ManagementObject vhdRasd = this.GetResourceAllocationSettingData(ResourceType.StorageExtent, ResourceSubType.Vhd); ;
        vhdRasd["Parent"]     = syntheticDiskRasd.Path;
        vhdRasd["Connection"] = new String[] { vhdPath };

        this.AddVirtualSystemResources( vhdRasd );

        // Cleanup
        vhdRasd.Dispose();
        syntheticDiskRasd.Dispose();
        ideController.Dispose();
        vssd.Dispose();
    }

    private ManagementObject GetResourceAllocationSettingData(ResourceType resourceType, ResourceSubType resourceSubType)
    {
        String desiredSubType = ResourceSubTypeStrings.GetString(resourceSubType); // Scout.Common.Extensions.GetDescription( resourceType );

        using(ManagementObjectCollection settingsDatas = _vm.GetRelated("Msvm_VirtualSystemSettingData"))
        foreach(ManagementObject settingData in settingsDatas)
        {
            using(ManagementObjectCollection rasds = settingData.GetRelated("Msvm_ResourceAllocationSettingData"))
            foreach(ManagementObject rasd in rasds)
            {
                ResourceType rasdResourceType    = (ResourceType)(UInt16)rasd["ResourceType"];
                String       rasdResourceSubType =               (String)rasd["ResourceSubType"];
                String       rasdOtherType       =               (String)rasd["OtherResourceType"];

                if( rasdResourceType == resourceType && rasdResourceSubType == desiredSubType )
                {
                    return rasd;
                }
            }
        }

        return null;
    }

    private void AddVirtualSystemResources(ManagementObject rasd)
    {
        using (ManagementObject vmService = HyperV.GetManagementService())
        {
            ManagementBaseObject inParams = vmService.GetMethodParameters("AddVirtualSystemResources");
            inParams["TargetSystem"]         = _vm;
            inParams["ResourceSettingsData"] = rasd.GetText(TextFormat.CimDtd20);

            ManagementBaseObject outParams = vmService.InvokeMethod("AddVirtualSystemResources", inParams, options: null);

            String[]            addedResources = (String[])outParams["NewResources"];
            OperationReturnCode returnValue    = (OperationReturnCode)(UInt32)outParams["ReturnValue"];

            if (returnValue == OperationReturnCode.JobStarted)
            {
                String jobPath = (String)outParams["Job"];
                HyperV.MonitorJob(jobPath);
            }
            else if (returnValue == OperationReturnCode.Completed)
            {
            }
            else
            {
                throw new ApplicationException( returnValue.ToString() );
            }
        }
    }

1 个答案:

答案 0 :(得分:-1)

我可以指出一个有效的例子,而不是找到你的问题吗?

请参阅my Apache CloudStack Hyper-V plugin

中的WmiCalls.DeployVirtualMachine

如果您需要其他详细信息,请发表评论,我会更新答案。