public static SyntheticEthernetPortSettingData[] GetEthernetPorts(ComputerSystem vm) { // An ASSOCIATOR object provides the cross reference from the ComputerSettings and the // SyntheticEthernetPortSettingData, via the VirtualSystemSettingData. // However, generated wrappers do not expose a ASSOCIATOR OF query as a method. // Instead, we use the System.Management to code the equivalant of // // string query = string.Format( "ASSOCIATORS OF {{{0}}} WHERE ResultClass = {1}", vm.path, resultclassName); // VirtualSystemSettingData vmSettings = GetVmSettings(vm); var wmiObjQuery = new RelatedObjectQuery(vmSettings.Path.Path, SyntheticEthernetPortSettingData.CreatedClassName); // NB: default scope of ManagementObjectSearcher is '\\.\root\cimv2', which does not contain // the virtualisation objects. var wmiObjectSearch = new ManagementObjectSearcher(vm.Scope, wmiObjQuery); var wmiObjCollection = new SyntheticEthernetPortSettingData.SyntheticEthernetPortSettingDataCollection(wmiObjectSearch.Get()); List<SyntheticEthernetPortSettingData> results = new List<SyntheticEthernetPortSettingData>(wmiObjCollection.Count); foreach (SyntheticEthernetPortSettingData item in wmiObjCollection) { results.Add(item); } return results.ToArray(); }
/// <summary> /// Create a disk and attach it to the vm /// </summary> /// <param name="vm"></param> /// <param name="cntrllerAddr"></param> /// <param name="driveResourceType">IDE_HARDDISK_DRIVE or IDE_ISO_DRIVE</param> public static ManagementPath AddDiskDriveToVm(ComputerSystem vm, string vhdfile, string cntrllerAddr, string driveResourceType) { logger.DebugFormat("Creating DISK for VM {0} (GUID {1}) by attaching {2}", vm.ElementName, vm.Name, vhdfile); // Determine disk type for drive and assert drive type valid string diskResourceSubType = null; switch(driveResourceType) { case IDE_HARDDISK_DRIVE: diskResourceSubType = IDE_HARDDISK_DISK; break; case IDE_ISO_DRIVE: diskResourceSubType = IDE_ISO_DISK; break; default: var errMsg = string.Format( "Unrecognised disk drive type {0} for VM {1} (GUID {2})", string.IsNullOrEmpty(driveResourceType) ? "NULL": driveResourceType, vm.ElementName, vm.Name); var ex = new WmiException(errMsg); logger.Error(errMsg, ex); throw ex; } ManagementPath newDrivePath = AttachNewDriveToVm(vm, cntrllerAddr, driveResourceType); // If there's not disk to insert, we are done. if (String.IsNullOrEmpty(vhdfile)) { logger.DebugFormat("No disk to be added to drive, disk drive {0} is complete", newDrivePath.Path); } else { InsertDiskImage(vm, vhdfile, diskResourceSubType, newDrivePath); } return newDrivePath; }
/// <summary> /// Create a (synthetic) nic, and attach it to the vm /// </summary> /// <param name="vm"></param> /// <param name="mac"></param> /// <param name="vlan"></param> /// <returns></returns> public static SyntheticEthernetPortSettingData CreateNICforVm(ComputerSystem vm, string mac, string vlan) { logger.DebugFormat("Creating nic for VM {0} (GUID {1})", vm.ElementName, vm.Name); // Obtain controller for Hyper-V networking subsystem VirtualSwitchManagementService vmNetMgmtSvc = GetVirtualSwitchManagementService(); // Create NIC resource by cloning the default NIC var synthNICsSettings = SyntheticEthernetPortSettingData.GetInstances(vmNetMgmtSvc.Scope, "InstanceID LIKE \"%Default\""); // Assert if (synthNICsSettings.Count != 1) { var errMsg = string.Format("Internal error, coudl not find default SyntheticEthernetPort instance"); var ex = new WmiException(errMsg); logger.Error(errMsg, ex); throw ex; } var defaultSynthNICSettings = synthNICsSettings.OfType<SyntheticEthernetPortSettingData>().First(); var newSynthNICSettings = new SyntheticEthernetPortSettingData((ManagementBaseObject)defaultSynthNICSettings.LateBoundObject.Clone()); // Get the virtual switch VirtualSwitch vSwitch = GetExternalVirtSwitch(); // Crate switch port for new VM ManagementPath newSwitchPath = CreateSwitchPortForVm(vm, vmNetMgmtSvc, vSwitch); // Add required VLAND support if (vlan != null) { SetPortVlan(vlan, vmNetMgmtSvc, newSwitchPath); } logger.DebugFormat("Created switch port {0} on switch {1}", newSwitchPath.Path, vSwitch.Path.Path); // Assign configuration to new NIC string normalisedMAC = string.Join("", (mac.Split(new char[] { ':' }))); newSynthNICSettings.LateBoundObject["Connection"] = new string[] { newSwitchPath.Path }; newSynthNICSettings.LateBoundObject["ElementName"] = vm.ElementName; newSynthNICSettings.LateBoundObject["Address"] = normalisedMAC; newSynthNICSettings.LateBoundObject["StaticMacAddress"] = "TRUE"; newSynthNICSettings.LateBoundObject["VirtualSystemIdentifiers"] = new string[] { "{" + Guid.NewGuid().ToString() + "}" }; newSynthNICSettings.CommitObject(); // Insert NIC into vm string[] newResources = new string[] { newSynthNICSettings.LateBoundObject.GetText(System.Management.TextFormat.CimDtd20)}; ManagementPath[] newResourcePaths = AddVirtualResource(newResources, vm ); // assert if (newResourcePaths.Length != 1) { var errMsg = string.Format( "Failed to properly insert a single NIC on VM {0} (GUID {1}): number of resource created {2}", vm.ElementName, vm.Name, newResourcePaths.Length); var ex = new WmiException(errMsg); logger.Error(errMsg, ex); throw ex; } return new SyntheticEthernetPortSettingData(newResourcePaths[0]); }
private static void InsertDiskImage(ComputerSystem vm, string vhdfile, string diskResourceSubType, ManagementPath drivePath) { // A description of the disk is created by modifying a clone of the default ResourceAllocationSettingData for that disk type string defaultDiskQuery = String.Format("ResourceSubType LIKE \"{0}\" AND InstanceID LIKE \"%Default\"", diskResourceSubType); var newDiskSettings = CloneResourceAllocationSetting(defaultDiskQuery); // Set disk drive and VHD file on disk for new disk newDiskSettings.LateBoundObject["Parent"] = drivePath.Path; newDiskSettings.LateBoundObject["Connection"] = new string[] { vhdfile }; newDiskSettings.CommitObject(); // Add the new vhd object as a virtual hard disk to the vm. string[] newDiskResource = new string[] { newDiskSettings.LateBoundObject.GetText(System.Management.TextFormat.CimDtd20) }; ManagementPath[] newDiskPaths = AddVirtualResource(newDiskResource, vm); // assert if (newDiskPaths.Length != 1) { var errMsg = string.Format( "Failed to add disk image type {3} to VM {0} (GUID {1}): number of resource created {2}", vm.ElementName, vm.Name, newDiskPaths.Length, diskResourceSubType); var ex = new WmiException(errMsg); logger.Error(errMsg, ex); throw ex; } logger.InfoFormat("Created disk {2} for VM {0} (GUID {1}), image {3} ", vm.ElementName, vm.Name, newDiskPaths[0].Path, vhdfile); }
private static void ModifyVmResources(VirtualSystemManagementService vmMgmtSvc, ComputerSystem vm, string[] resourceSettings) { // Resource settings are changed through the management service System.Management.ManagementPath jobPath; var ret_val = vmMgmtSvc.ModifyVirtualSystemResources(vm.Path, resourceSettings, out jobPath); // If the Job is done asynchronously if (ret_val == ReturnCode.Started) { JobCompleted(jobPath); } else if (ret_val != ReturnCode.Completed) { var errMsg = string.Format( "Failed to update VM {0} (GUID {1}) due to {2} (ModifyVirtualSystem call), existing VM not deleted", vm.ElementName, vm.Name, ReturnCode.ToString(ret_val)); var ex = new WmiException(errMsg); logger.Error(errMsg, ex); throw ex; } }
private static ComputerSystem CreateDefaultVm(VirtualSystemManagementService vmMgmtSvc, string name) { // Tweak default settings by basing new VM on default global setting object // with designed display name. VirtualSystemGlobalSettingData vs_gs_data = VirtualSystemGlobalSettingData.CreateInstance(); vs_gs_data.LateBoundObject["ElementName"] = name; System.Management.ManagementPath jobPath; System.Management.ManagementPath defined_sys; var ret_val = vmMgmtSvc.DefineVirtualSystem( new string[0], null, vs_gs_data.LateBoundObject.GetText(System.Management.TextFormat.CimDtd20), out defined_sys, out jobPath); // If the Job is done asynchronously if (ret_val == ReturnCode.Started) { JobCompleted(jobPath); } else if (ret_val != ReturnCode.Completed) { var errMsg = string.Format( "Failed to create VM {0} due to {1} (DefineVirtualSystem call)", name, ReturnCode.ToString(ret_val)); var ex = new WmiException(errMsg); logger.Error(errMsg, ex); throw ex; } logger.DebugFormat(CultureInfo.InvariantCulture, "Created VM {0}", name); // Is the defined_system real? var vm = new ComputerSystem(defined_sys); // Assertion if (vm.ElementName.CompareTo(name) != 0) { var errMsg = string.Format( "New VM created with wrong name (is {0}, should be {1}, GUID {2})", vm.ElementName, name, vm.Name); var ex = new WmiException(errMsg); logger.Error(errMsg, ex); throw ex; } return vm; }
private static ManagementPath CreateSwitchPortForVm(ComputerSystem vm, VirtualSwitchManagementService vmNetMgmtSvc, VirtualSwitch vSwitch) { ManagementPath newSwitchPath = null; var ret_val = vmNetMgmtSvc.CreateSwitchPort( vm.ElementName, Guid.NewGuid().ToString(), "", vSwitch.Path, out newSwitchPath); // Job is always done synchronously if (ret_val != ReturnCode.Completed) { var errMsg = string.Format( "Failed to create switch for NIC on VM {0} (GUID {1}), error code {2}", vm.ElementName, vm.Name, ret_val); var ex = new WmiException(errMsg); logger.Error(errMsg, ex); throw ex; } return newSwitchPath; }
private static ManagementPath AttachNewDriveToVm(ComputerSystem vm, string cntrllerAddr, string driveType) { // Disk drives are attached to a 'Parent' IDE controller. We IDE Controller's settings for the 'Path', which our new Disk drive will use to reference it. VirtualSystemSettingData vmSettings = GetVmSettings(vm); var ctrller = GetIDEControllerSettings(vmSettings, cntrllerAddr); // A description of the drive is created by modifying a clone of the default ResourceAllocationSettingData for that drive type string defaultDriveQuery = String.Format("ResourceSubType LIKE \"{0}\" AND InstanceID LIKE \"%Default\"", driveType); var newDiskDriveSettings = CloneResourceAllocationSetting(defaultDriveQuery); // Set IDE controller and address on the controller for the new drive newDiskDriveSettings.LateBoundObject["Parent"] = ctrller.Path.ToString(); newDiskDriveSettings.LateBoundObject["Address"] = "0"; newDiskDriveSettings.CommitObject(); // Add this new disk drive to the VM logger.DebugFormat("Creating disk drive type {0}, parent IDE controller is {1} and address on controller is {2}", newDiskDriveSettings.ResourceSubType, newDiskDriveSettings.Parent, newDiskDriveSettings.Address); string[] newDriveResource = new string[] { newDiskDriveSettings.LateBoundObject.GetText(System.Management.TextFormat.CimDtd20) }; ManagementPath[] newDrivePaths = AddVirtualResource(newDriveResource, vm); // assert if (newDrivePaths.Length != 1) { var errMsg = string.Format( "Failed to add disk drive type {3} to VM {0} (GUID {1}): number of resource created {2}", vm.ElementName, vm.Name, newDrivePaths.Length, driveType); var ex = new WmiException(errMsg); logger.Error(errMsg, ex); throw ex; } logger.DebugFormat("New disk drive type {0} WMI path is {1}s", newDiskDriveSettings.ResourceSubType, newDrivePaths[0].Path); return newDrivePaths[0]; }
// Add new private static ManagementPath[] AddVirtualResource(string[] resourceSettings, ComputerSystem vm ) { var virtSysMgmtSvc = GetVirtualisationSystemManagementService(); ManagementPath jobPath; ManagementPath[] resourcePaths; var ret_val = virtSysMgmtSvc.AddVirtualSystemResources( resourceSettings, vm.Path, out jobPath, out resourcePaths); // If the Job is done asynchronously if (ret_val == ReturnCode.Started) { JobCompleted(jobPath); } else if (ret_val != ReturnCode.Completed) { var errMsg = string.Format( "Failed to add resources to VM {0} (GUID {1}) due to {2}", vm.ElementName, vm.Name, ReturnCode.ToString(ret_val)); var ex = new WmiException(errMsg); logger.Error(errMsg, ex); throw ex; } return resourcePaths; }
public static void SetState(ComputerSystem vm, ushort requiredState) { logger.InfoFormat( "Changing state of {0} (GUID {1}) to {2}", vm.ElementName, vm.Name, RequiredState.ToString(requiredState)); ManagementPath jobPath; // TimeSpan is a value type; default ctor is equivalent to 0. var ret_val = vm.RequestStateChange(requiredState, new TimeSpan(), out jobPath); // If the Job is done asynchronously if (ret_val == ReturnCode.Started) { JobCompleted(jobPath); } else if (ret_val == 32775) { logger.InfoFormat("RequestStateChange returned 32775, which means vm in wrong state for requested state change. Treating as if requested state was reached"); } else if (ret_val != ReturnCode.Completed) { var errMsg = string.Format( "Failed to change state of VM {0} (GUID {1}) to {2} due to {3}", vm.ElementName, vm.Name, RequiredState.ToString(requiredState), ReturnCode.ToString(ret_val)); var ex = new WmiException(errMsg); logger.Error(errMsg, ex); throw ex; } logger.InfoFormat( "Successfully changed vm state of {0} (GUID {1} to requested state {2}", vm.ElementName, vm.Name, requiredState); }
public static VirtualSystemSettingData GetVmSettings(ComputerSystem vm) { // An ASSOCIATOR object provides the cross reference from the ComputerSettings and the // VirtualSystemSettingData, but generated wrappers do not expose a ASSOCIATOR OF query as a method. // Instead, we use the System.Management to code the equivalant of // string query = string.Format( "ASSOCIATORS OF {{{0}}} WHERE ResultClass = {1}", vm.path, resultclassName); // var wmiObjQuery = new RelatedObjectQuery(vm.Path.Path, VirtualSystemSettingData.CreatedClassName); // NB: default scope of ManagementObjectSearcher is '\\.\root\cimv2', which does not contain // the virtualisation objects. var wmiObjectSearch = new ManagementObjectSearcher(vm.Scope, wmiObjQuery); var wmiObjCollection = new VirtualSystemSettingData.VirtualSystemSettingDataCollection(wmiObjectSearch.Get()); // When snapshots are taken into account, there can be multiple settings objects // take the first one that isn't a snapshot foreach (VirtualSystemSettingData wmiObj in wmiObjCollection) { if (wmiObj.SettingType == 3) { return wmiObj; } } var errMsg = string.Format("No VirtualSystemSettingData for VM {0}, path {1}", vm.ElementName, vm.Path.Path); var ex = new WmiException(errMsg); logger.Error(errMsg, ex); throw ex; }
public static SwitchPort[] GetSwitchPorts(ComputerSystem vm) { var virtSwitchMgmtSvc = GetVirtualSwitchManagementService(); // Get NIC path var condition = string.Format("ElementName=\"{0}\"", vm.ElementName); var switchPortCollection = SwitchPort.GetInstances(virtSwitchMgmtSvc.Scope, condition); List<SwitchPort> result = new List<SwitchPort>(switchPortCollection.Count); foreach (SwitchPort item in switchPortCollection) { result.Add(item); } return result.ToArray(); }