From 8b3332e3c70fb6c5061c1caa6d4fea80e6d938f5 Mon Sep 17 00:00:00 2001 From: AlexanderTr Date: Fri, 20 Mar 2015 21:24:07 +0300 Subject: [PATCH] wsp-10323 Convert the VSP provider into one utilizing PowerShell. Step 6 Create\Delete\Export --- .../Helpers/BiosHelper.cs | 8 +- .../Helpers/DvdDriveHelper.cs | 8 +- .../Helpers/HardDriveHelper.cs | 6 +- .../Helpers/NetworkAdapterHelper.cs | 12 +- .../Helpers/SnapshotHelper.cs | 2 +- .../Helpers/VirtualMachineHelper.cs | 10 +- .../HyperV2012R2.cs | 403 ++++-------------- .../PowerShellManager.cs | 73 +--- 8 files changed, 121 insertions(+), 401 deletions(-) diff --git a/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/Helpers/BiosHelper.cs b/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/Helpers/BiosHelper.cs index 21dafb52..fdb71f50 100644 --- a/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/Helpers/BiosHelper.cs +++ b/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/Helpers/BiosHelper.cs @@ -23,7 +23,7 @@ namespace WebsitePanel.Providers.Virtualization cmd.Parameters.Add("VMName", name); - Collection result = powerShell.Execute(cmd, false); + Collection result = powerShell.Execute(cmd, true); if (result != null && result.Count > 0) { info.NumLockEnabled = true; @@ -56,7 +56,7 @@ namespace WebsitePanel.Providers.Virtualization cmd.Parameters.Add("VMName", name); - Collection result = powerShell.Execute(cmd, false); + Collection result = powerShell.Execute(cmd, true); if (result != null && result.Count > 0) { info.NumLockEnabled = Convert.ToBoolean(result[0].GetProperty("NumLockEnabled")); @@ -89,7 +89,7 @@ namespace WebsitePanel.Providers.Virtualization else cmd.Parameters.Add("FirstBootDevice", HardDriveHelper.GetPS(powerShell, vm.Name).FirstOrDefault()); - powerShell.Execute(cmd, false); + powerShell.Execute(cmd, true); } // for others win and linux else @@ -102,7 +102,7 @@ namespace WebsitePanel.Providers.Virtualization : new[] { "IDE", "CD", "LegacyNetworkAdapter", "Floppy" }; cmd.Parameters.Add("StartupOrder", bootOrder); - powerShell.Execute(cmd, false); + powerShell.Execute(cmd, true); } } } diff --git a/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/Helpers/DvdDriveHelper.cs b/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/Helpers/DvdDriveHelper.cs index 012232ee..ce039f0c 100644 --- a/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/Helpers/DvdDriveHelper.cs +++ b/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/Helpers/DvdDriveHelper.cs @@ -36,7 +36,7 @@ namespace WebsitePanel.Providers.Virtualization cmd.Parameters.Add("VMName", vmName); - Collection result = powerShell.Execute(cmd, false); + Collection result = powerShell.Execute(cmd, true); if (result != null && result.Count > 0) { @@ -57,7 +57,7 @@ namespace WebsitePanel.Providers.Virtualization cmd.Parameters.Add("ControllerNumber", dvd.ControllerNumber); cmd.Parameters.Add("ControllerLocation", dvd.ControllerLocation); - powerShell.Execute(cmd, false); + powerShell.Execute(cmd, true); } public static void Update(PowerShellManager powerShell, VirtualMachine vm, bool dvdDriveShouldBeInstalled) @@ -74,7 +74,7 @@ namespace WebsitePanel.Providers.Virtualization cmd.Parameters.Add("VMName", vmName); - powerShell.Execute(cmd, false); + powerShell.Execute(cmd, true); } public static void Remove(PowerShellManager powerShell, string vmName) @@ -87,7 +87,7 @@ namespace WebsitePanel.Providers.Virtualization cmd.Parameters.Add("ControllerNumber", dvd.ControllerNumber); cmd.Parameters.Add("ControllerLocation", dvd.ControllerLocation); - powerShell.Execute(cmd, false); + powerShell.Execute(cmd, true); } } } diff --git a/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/Helpers/HardDriveHelper.cs b/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/Helpers/HardDriveHelper.cs index c8a951d6..b2e90e90 100644 --- a/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/Helpers/HardDriveHelper.cs +++ b/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/Helpers/HardDriveHelper.cs @@ -47,7 +47,7 @@ namespace WebsitePanel.Providers.Virtualization // Command cmd = new Command("Get-VM"); - // Collection result = powerShell.Execute(cmd, false); + // Collection result = powerShell.Execute(cmd, true); // if (result == null || result.Count == 0) // return null; @@ -63,7 +63,7 @@ namespace WebsitePanel.Providers.Virtualization Command cmd = new Command("Get-VMHardDiskDrive"); cmd.Parameters.Add("VMName", vmname); - return powerShell.Execute(cmd, false); + return powerShell.Execute(cmd, true); } public static void GetVirtualHardDiskDetail(PowerShellManager powerShell, string path, ref VirtualHardDiskInfo disk) @@ -72,7 +72,7 @@ namespace WebsitePanel.Providers.Virtualization { Command cmd = new Command("Get-VHD"); cmd.Parameters.Add("Path", path); - Collection result = powerShell.Execute(cmd, false); + Collection result = powerShell.Execute(cmd, true); if (result != null && result.Count > 0) { disk.DiskFormat = result[0].GetEnum("VhdFormat"); diff --git a/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/Helpers/NetworkAdapterHelper.cs b/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/Helpers/NetworkAdapterHelper.cs index bd6f9b37..f14f8f97 100644 --- a/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/Helpers/NetworkAdapterHelper.cs +++ b/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/Helpers/NetworkAdapterHelper.cs @@ -26,7 +26,7 @@ namespace WebsitePanel.Providers.Virtualization Command cmd = new Command("Get-VMNetworkAdapter"); if (!string.IsNullOrEmpty(vmName)) cmd.Parameters.Add("VMName", vmName); - Collection result = powerShell.Execute(cmd, false); + Collection result = powerShell.Execute(cmd, true); if (result != null && result.Count > 0) { foreach (PSObject psAdapter in result) @@ -89,8 +89,9 @@ namespace WebsitePanel.Providers.Virtualization else cmd.Parameters.Add("StaticMacAddress", macAddress); - powerShell.Execute(cmd, false); + powerShell.Execute(cmd, true); } + public static void Delete(PowerShellManager powerShell, string vmName, string macAddress) { var networkAdapter = Get(powerShell, vmName, macAddress); @@ -98,12 +99,17 @@ namespace WebsitePanel.Providers.Virtualization if (networkAdapter == null) return; + Delete(powerShell, vmName, networkAdapter); + } + + public static void Delete(PowerShellManager powerShell, string vmName, VirtualMachineNetworkAdapter networkAdapter) + { Command cmd = new Command("Remove-VMNetworkAdapter"); cmd.Parameters.Add("VMName", vmName); cmd.Parameters.Add("Name", networkAdapter.Name); - powerShell.Execute(cmd, false); + powerShell.Execute(cmd, true); } } } diff --git a/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/Helpers/SnapshotHelper.cs b/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/Helpers/SnapshotHelper.cs index b5dee5c2..fa738ce0 100644 --- a/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/Helpers/SnapshotHelper.cs +++ b/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/Helpers/SnapshotHelper.cs @@ -66,7 +66,7 @@ namespace WebsitePanel.Providers.Virtualization cmd.Parameters.Add("Name", snapshot.Name); if (includeChilds) cmd.Parameters.Add("IncludeAllChildSnapshots", true); - powerShell.Execute(cmd, false); + powerShell.Execute(cmd, true); } } } diff --git a/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/Helpers/VirtualMachineHelper.cs b/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/Helpers/VirtualMachineHelper.cs index e7d05288..bd1291a1 100644 --- a/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/Helpers/VirtualMachineHelper.cs +++ b/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/Helpers/VirtualMachineHelper.cs @@ -21,7 +21,7 @@ namespace WebsitePanel.Providers.Virtualization cmd.Parameters.Add("VMName", name); cmd.Parameters.Add("Name", "HeartBeat"); - Collection result = powerShell.Execute(cmd, false); + Collection result = powerShell.Execute(cmd, true); if (result != null && result.Count > 0) { var statusString = result[0].GetProperty("PrimaryOperationalStatus"); @@ -41,7 +41,7 @@ namespace WebsitePanel.Providers.Virtualization cmd.Parameters.Add("VMName", name); - Collection result = powerShell.Execute(cmd, false); + Collection result = powerShell.Execute(cmd, true); if (result != null && result.Count > 0) { procs = Convert.ToInt32(result[0].GetProperty("Count")); @@ -58,7 +58,7 @@ namespace WebsitePanel.Providers.Virtualization cmd.Parameters.Add("VMName", name); - Collection result = powerShell.Execute(cmd, false); + Collection result = powerShell.Execute(cmd, true); if (result != null && result.Count > 0) { info.DynamicMemoryEnabled = Convert.ToBoolean(result[0].GetProperty("DynamicMemoryEnabled")); @@ -81,7 +81,7 @@ namespace WebsitePanel.Providers.Virtualization cmd.Parameters.Add("Reserve", Convert.ToInt64(cpuReserveSettings * 1000)); cmd.Parameters.Add("RelativeWeight", cpuWeightSettings); - powerShell.Execute(cmd, false); + powerShell.Execute(cmd, true); } public static void UpdateMemory(PowerShellManager powerShell, VirtualMachine vm, long ramMB) @@ -91,7 +91,7 @@ namespace WebsitePanel.Providers.Virtualization cmd.Parameters.Add("VMName", vm.Name); cmd.Parameters.Add("StartupBytes", ramMB * Constants.Size1M); - powerShell.Execute(cmd, false); + powerShell.Execute(cmd, true); } } } diff --git a/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/HyperV2012R2.cs b/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/HyperV2012R2.cs index 7b1801ea..b8ad22ab 100644 --- a/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/HyperV2012R2.cs +++ b/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/HyperV2012R2.cs @@ -163,7 +163,7 @@ namespace WebsitePanel.Providers.Virtualization cmd.Parameters.Add("Id", vmId); - Collection result = PowerShell.Execute(cmd, false); + Collection result = PowerShell.Execute(cmd, true); if (result != null && result.Count > 0) { vm.Name = result[0].GetProperty("Name").ToString(); @@ -232,7 +232,7 @@ namespace WebsitePanel.Providers.Virtualization { Command cmd = new Command("Get-VM"); - Collection result = PowerShell.Execute(cmd, false); + Collection result = PowerShell.Execute(cmd, true); foreach (PSObject current in result) { VirtualMachine vm = new VirtualMachine @@ -332,8 +332,9 @@ namespace WebsitePanel.Providers.Virtualization // Add new VM Command cmdNew = new Command("New-VM"); cmdNew.Parameters.Add("Name", vm.Name); + cmdNew.Parameters.Add("Generation", vm.Generation > 1 ? vm.Generation : 1); cmdNew.Parameters.Add("VHDPath", vm.VirtualHardDrivePath); - PowerShell.Execute(cmdNew, false); + PowerShell.Execute(cmdNew, true); // Set VM Command cmdSet = new Command("Set-VM"); @@ -350,7 +351,7 @@ namespace WebsitePanel.Providers.Virtualization } if (autoStopAction != AutomaticStopAction.Undefined) cmdSet.Parameters.Add("AutomaticStopAction", autoStopAction.ToString()); - PowerShell.Execute(cmdSet, false); + PowerShell.Execute(cmdSet, true); // Get created machine Id var createdMachine = GetVirtualMachines().FirstOrDefault(m => m.Name == vm.Name); @@ -396,168 +397,6 @@ namespace WebsitePanel.Providers.Virtualization return vm; } - - private void AddVirtualMachineDvdDrive(string vmId, ManagementObject objVM) - { - // load IDE 1 controller - ManagementObject objIDE1 = wmi.GetWmiObject( - "Msvm_ResourceAllocationSettingData", "ResourceSubType = 'Microsoft Emulated IDE Controller'" - + " and InstanceID Like 'Microsoft:{0}%' and Address = 1", vmId); - - // load default hard disk drive - ManagementObject objDefaultDvd = wmi.GetWmiObject( - "Msvm_ResourceAllocationSettingData", "ResourceSubType = 'Microsoft Synthetic DVD Drive'" - + " and InstanceID like '%Default'"); - ManagementObject objDvd = (ManagementObject)objDefaultDvd.Clone(); - objDvd["Parent"] = objIDE1.Path; - objDvd["Address"] = 0; - - // add DVD drive to VM resources - AddVirtualMachineResources(objVM, objDvd); - } - - private void AddNetworkAdapter(ManagementObject objVm, string switchId, string portName, string macAddress, string adapterName, bool legacyAdapter) - { - string nicClassName = GetNetworkAdapterClassName(legacyAdapter); - - string vmId = (string)objVm["Name"]; - - // check if already exists - ManagementObject objNic = wmi.GetWmiObject( - nicClassName, "InstanceID like 'Microsoft:{0}%' and Address = '{1}'", vmId, macAddress); - - if (objNic != null) - return; // exists - exit - - portName = String.Format("{0} - {1}", - portName, (adapterName == EXTERNAL_NETWORK_ADAPTER_NAME) ? "External" : "Private"); - - // Network service - ManagementObject objNetworkSvc = GetVirtualSwitchManagementService(); - - // default NIC - ManagementObject objDefaultNic = wmi.GetWmiObject(nicClassName, "InstanceID like '%Default'"); - - // find switch - ManagementObject objSwitch = wmi.GetWmiObject("msvm_VirtualSwitch", "Name = '{0}'", switchId); - - // create switch port - ManagementBaseObject inParams = objNetworkSvc.GetMethodParameters("CreateSwitchPort"); - inParams["VirtualSwitch"] = objSwitch; - inParams["Name"] = portName; - inParams["FriendlyName"] = portName; - inParams["ScopeOfResidence"] = ""; - - // invoke method - ManagementBaseObject outParams = objNetworkSvc.InvokeMethod("CreateSwitchPort", inParams, null); - - // process output parameters - ReturnCode code = (ReturnCode)Convert.ToInt32(outParams["ReturnValue"]); - if (code == ReturnCode.OK) - { - // created port - ManagementObject objPort = wmi.GetWmiObjectByPath((string)outParams["CreatedSwitchPort"]); - - // create NIC - ManagementObject objExtNic = (ManagementObject)objDefaultNic.Clone(); - objExtNic["Connection"] = new string[] { objPort.Path.Path }; - - if (!String.IsNullOrEmpty(macAddress)) - { - objExtNic["StaticMacAddress"] = true; - objExtNic["Address"] = macAddress; - } - else - { - objExtNic["StaticMacAddress"] = false; - } - objExtNic["ElementName"] = adapterName; - - if (!legacyAdapter) - objExtNic["VirtualSystemIdentifiers"] = new string[] { Guid.NewGuid().ToString("B") }; - - // add NIC - ManagementObject objCreatedExtNic = AddVirtualMachineResources(objVm, objExtNic); - } - } - - private string GetNetworkAdapterClassName(bool legacy) - { - return legacy ? "Msvm_EmulatedEthernetPortSettingData" : "Msvm_SyntheticEthernetPortSettingData"; - } - - private ManagementObject AddVirtualMachineResources(ManagementObject objVm, ManagementObject resource) - { - if (resource == null) - return resource; - - // request management service - ManagementObject objVmsvc = GetVirtualSystemManagementService(); - - // add resources - string txtResource = resource.GetText(TextFormat.CimDtd20); - ManagementBaseObject inParams = objVmsvc.GetMethodParameters("AddVirtualSystemResources"); - inParams["TargetSystem"] = objVm; - inParams["ResourceSettingData"] = new string[] { txtResource }; - ManagementBaseObject outParams = objVmsvc.InvokeMethod("AddVirtualSystemResources", inParams, null); - JobResult result = CreateJobResultFromWmiMethodResults(outParams); - - if (result.ReturnValue == ReturnCode.OK) - { - string[] wmiPaths = (string[])outParams["NewResources"]; - return wmi.GetWmiObjectByPath(wmiPaths[0]); - } - else if (result.ReturnValue == ReturnCode.JobStarted) - { - if (JobCompleted(result.Job)) - { - string[] wmiPaths = (string[])outParams["NewResources"]; - return wmi.GetWmiObjectByPath(wmiPaths[0]); - } - else - { - throw new Exception("Cannot add virtual machine resources"); - } - } - else - { - throw new Exception("Cannot add virtual machine resources: " + txtResource); - } - } - - private JobResult RemoveVirtualMachineResources(ManagementObject objVm, ManagementObject resource) - { - if (resource == null) - return null; - - // request management service - ManagementObject objVmsvc = GetVirtualSystemManagementService(); - - // remove resources - ManagementBaseObject inParams = objVmsvc.GetMethodParameters("RemoveVirtualSystemResources"); - inParams["TargetSystem"] = objVm; - inParams["ResourceSettingData"] = new string[] { resource.Path.Path }; - ManagementBaseObject outParams = objVmsvc.InvokeMethod("RemoveVirtualSystemResources", inParams, null); - JobResult result = CreateJobResultFromWmiMethodResults(outParams); - if (result.ReturnValue == ReturnCode.OK) - { - return result; - } - else if (result.ReturnValue == ReturnCode.JobStarted) - { - if (!JobCompleted(result.Job)) - { - throw new Exception("Cannot remove virtual machine resources"); - } - } - else - { - throw new Exception("Cannot remove virtual machine resources: " + resource.Path.Path); - } - - return result; - } - public JobResult ChangeVirtualMachineState(string vmId, VirtualMachineRequestedState newState) { HostedSolutionLog.LogStart("ChangeVirtualMachineState"); @@ -604,8 +443,8 @@ namespace WebsitePanel.Providers.Virtualization //cmd.Parameters.Add("AsJob"); paramList.ForEach(p => cmd.Parameters.Add(p)); - PowerShell.Execute(cmd, false); - jobResult = JobHelper.CreateSuccessResult(); + PowerShell.Execute(cmd, true); + jobResult = JobHelper.CreateSuccessResult(ReturnCode.JobStarted); } catch (Exception ex) { @@ -633,7 +472,7 @@ namespace WebsitePanel.Providers.Virtualization if (force) cmd.Parameters.Add("Force"); //if (!string.IsNullOrEmpty(reason)) cmd.Parameters.Add("Reason", reason); - PowerShell.Execute(cmd, false); + PowerShell.Execute(cmd, true); } catch (Exception ex) { @@ -665,133 +504,58 @@ namespace WebsitePanel.Providers.Virtualization public JobResult RenameVirtualMachine(string vmId, string name) { - // load virtual machine - ManagementObject objVm = GetVirtualMachineObject(vmId); + var vm = GetVirtualMachine(vmId); - // load machine settings - ManagementObject objVmSettings = GetVirtualMachineSettingsObject(vmId); + Command cmdSet = new Command("Rename-VM"); + cmdSet.Parameters.Add("Name", vm.Name); + cmdSet.Parameters.Add("NewName", name); + PowerShell.Execute(cmdSet, true); - // rename machine - objVmSettings["ElementName"] = name; - - // save - ManagementObject objVmsvc = GetVirtualSystemManagementService(); - ManagementBaseObject inParams = objVmsvc.GetMethodParameters("ModifyVirtualSystem"); - inParams["ComputerSystem"] = objVm.Path.Path; - inParams["SystemSettingData"] = objVmSettings.GetText(TextFormat.CimDtd20); - ManagementBaseObject outParams = objVmsvc.InvokeMethod("ModifyVirtualSystem", inParams, null); - return CreateJobResultFromWmiMethodResults(outParams); + return JobHelper.CreateSuccessResult(); } public JobResult DeleteVirtualMachine(string vmId) { - // load virtual machine object - ManagementObject objVm = GetVirtualMachineObject(vmId); - - // check state - VirtualMachine vm = GetVirtualMachine(vmId); + var vm = GetVirtualMachineEx(vmId); // The virtual computer system must be in the powered off or saved state prior to calling this method. - if (vm.State == VirtualMachineState.Saved - || vm.State == VirtualMachineState.Off) - { - // delete network adapters and ports - DeleteNetworkAdapters(objVm); - - // destroy machine - ManagementObject objVmsvc = GetVirtualSystemManagementService(); - - // get method - ManagementBaseObject inParams = objVmsvc.GetMethodParameters("DestroyVirtualSystem"); - inParams["ComputerSystem"] = objVm; - - // invoke method - ManagementBaseObject outParams = objVmsvc.InvokeMethod("DestroyVirtualSystem", inParams, null); - return CreateJobResultFromWmiMethodResults(outParams); - } - else - { + if (vm.State != VirtualMachineState.Saved && vm.State != VirtualMachineState.Off) throw new Exception("The virtual computer system must be in the powered off or saved state prior to calling Destroy method."); + + // Delete network adapters and network switchesw + foreach (var networkAdapter in vm.Adapters) + { + NetworkAdapterHelper.Delete(PowerShell, vm.Name, networkAdapter); + + if (!string.IsNullOrEmpty(networkAdapter.SwitchName)) + DeleteSwitch(networkAdapter.SwitchName); } - } - private void DeleteNetworkAdapters(ManagementObject objVM) - { - string vmId = (string)objVM["Name"]; + object[] errors; - // delete synthetic adapters - foreach (ManagementObject objNic in wmi.GetWmiObjects("Msvm_SyntheticEthernetPortSettingData", "InstanceID like 'Microsoft:{0}%'", vmId)) - DeleteNetworkAdapter(objVM, objNic); + Command cmdSet = new Command("Remove-VM"); + cmdSet.Parameters.Add("Name", vm.Name); + cmdSet.Parameters.Add("Force"); + PowerShell.Execute(cmdSet, false, out errors); - // delete legacy adapters - foreach (ManagementObject objNic in wmi.GetWmiObjects("Msvm_EmulatedEthernetPortSettingData", "InstanceID like 'Microsoft:{0}%'", vmId)) - DeleteNetworkAdapter(objVM, objNic); - } + PowerShellManager.ExceptionIfErrors(errors); - private void DeleteNetworkAdapter(ManagementObject objVM, string macAddress) - { - // locate network adapter - ManagementObject objNic = wmi.GetWmiObject("CIM_ResourceAllocationSettingData", "Address = '{0}'", macAddress); - - // delete adapter - DeleteNetworkAdapter(objVM, objNic); - } - - private void DeleteNetworkAdapter(ManagementObject objVM, ManagementObject objNic) - { - if (objNic == null) - return; - - // delete corresponding switch port - string[] conn = (string[])objNic["Connection"]; - if (conn != null && conn.Length > 0) - DeleteSwitchPort(conn[0]); - - // delete adapter - RemoveVirtualMachineResources(objVM, objNic); - } - - private void DeleteSwitchPort(string portPath) - { - // Network service - ManagementObject objNetworkSvc = GetVirtualSwitchManagementService(); - - // create switch port - ManagementBaseObject inParams = objNetworkSvc.GetMethodParameters("DeleteSwitchPort"); - inParams["SwitchPort"] = portPath; - - // invoke method - objNetworkSvc.InvokeMethod("DeleteSwitchPort", inParams, null); + return JobHelper.CreateSuccessResult(ReturnCode.JobStarted); } public JobResult ExportVirtualMachine(string vmId, string exportPath) { - // load virtual machine object - ManagementObject objVm = GetVirtualMachineObject(vmId); - - // check state - VirtualMachine vm = GetVirtualMachine(vmId); + var vm = GetVirtualMachine(vmId); // The virtual computer system must be in the powered off or saved state prior to calling this method. - if (vm.State == VirtualMachineState.Off) - { - // export machine - ManagementObject objVmsvc = GetVirtualSystemManagementService(); - - // get method - ManagementBaseObject inParams = objVmsvc.GetMethodParameters("ExportVirtualSystem"); - inParams["ComputerSystem"] = objVm; - inParams["CopyVmState"] = true; - inParams["ExportDirectory"] = FileUtils.EvaluateSystemVariables(exportPath); - - // invoke method - ManagementBaseObject outParams = objVmsvc.InvokeMethod("ExportVirtualSystem", inParams, null); - return CreateJobResultFromWmiMethodResults(outParams); - } - else - { + if (vm.State != VirtualMachineState.Off) throw new Exception("The virtual computer system must be in the powered off or saved state prior to calling Export method."); - } + + Command cmdSet = new Command("Export-VM"); + cmdSet.Parameters.Add("Name", vm.Name); + cmdSet.Parameters.Add("Path", FileUtils.EvaluateSystemVariables(exportPath)); + PowerShell.Execute(cmdSet, true); + return JobHelper.CreateSuccessResult(ReturnCode.JobStarted); } #endregion @@ -808,7 +572,7 @@ namespace WebsitePanel.Providers.Virtualization Command cmd = new Command("Get-VMSnapshot"); cmd.Parameters.Add("VMName", vm.Name); - Collection result = PowerShell.Execute(cmd, false); + Collection result = PowerShell.Execute(cmd, true); if (result != null && result.Count > 0) { foreach (PSObject psSnapshot in result) @@ -833,7 +597,7 @@ namespace WebsitePanel.Providers.Virtualization Command cmd = new Command("Get-VMSnapshot"); cmd.Parameters.Add("Id", snapshotId); - Collection result = PowerShell.Execute(cmd, false); + Collection result = PowerShell.Execute(cmd, true); if (result != null && result.Count > 0) { return SnapshotHelper.GetFromPS(result[0]); @@ -857,7 +621,7 @@ namespace WebsitePanel.Providers.Virtualization Command cmd = new Command("Checkpoint-VM"); cmd.Parameters.Add("Name", vm.Name); - PowerShell.Execute(cmd, false); + PowerShell.Execute(cmd, true); return JobHelper.CreateSuccessResult(ReturnCode.JobStarted); } catch (Exception ex) @@ -879,7 +643,7 @@ namespace WebsitePanel.Providers.Virtualization cmd.Parameters.Add("Name", snapshot.Name); cmd.Parameters.Add("NewName", name); - PowerShell.Execute(cmd, false); + PowerShell.Execute(cmd, true); return JobHelper.CreateSuccessResult(); } catch (Exception ex) @@ -900,7 +664,7 @@ namespace WebsitePanel.Providers.Virtualization cmd.Parameters.Add("VMName", vm.Name); cmd.Parameters.Add("Name", snapshot.Name); - PowerShell.Execute(cmd, false); + PowerShell.Execute(cmd, true); return JobHelper.CreateSuccessResult(); } catch (Exception ex) @@ -1042,7 +806,10 @@ namespace WebsitePanel.Providers.Virtualization if (!string.IsNullOrEmpty(computerName)) cmd.Parameters.Add("ComputerName", computerName); if (!string.IsNullOrEmpty(type)) cmd.Parameters.Add("SwitchType", type); - Collection result = PowerShell.Execute(cmd,false); + object[] errors; + Collection result = PowerShell.Execute(cmd, false, out errors); + PowerShellManager.ExceptionIfErrors(errors); + foreach (PSObject current in result) { VirtualSwitch sw = new VirtualSwitch(); @@ -1083,7 +850,7 @@ namespace WebsitePanel.Providers.Virtualization cmd.Parameters.Add("SwitchType", "Private"); cmd.Parameters.Add("Name", name); - Collection result = PowerShell.Execute(cmd, false); + Collection result = PowerShell.Execute(cmd, true); if (result != null && result.Count > 0) { virtualSwitch = new VirtualSwitch(); @@ -1102,7 +869,7 @@ namespace WebsitePanel.Providers.Virtualization return virtualSwitch; } - public ReturnCode DeleteSwitch(string switchId) + public ReturnCode DeleteSwitch(string switchId) // switchId is SwitchName { HostedSolutionLog.LogStart("DeleteSwitch"); HostedSolutionLog.DebugInfo("switchId: {0}", switchId); @@ -1111,7 +878,8 @@ namespace WebsitePanel.Providers.Virtualization { Command cmd = new Command("Remove-VMSwitch"); cmd.Parameters.Add("Name", switchId); - PowerShell.Execute(cmd, false); + cmd.Parameters.Add("Force"); + PowerShell.Execute(cmd, true); } catch (Exception ex) { @@ -1438,13 +1206,6 @@ namespace WebsitePanel.Providers.Virtualization } } - private string GetPropertyValue(string propertyName, XmlDocument doc) - { - string xpath = string.Format(@"//PROPERTY[@NAME = '{0}']/VALUE/child::text()", propertyName); - XmlNode node = doc.SelectSingleNode(xpath); - return node != null ? node.Value : null; - } - public MountedDiskInfo MountVirtualHardDisk(string vhdPath) { ManagementObject objImgSvc = GetImageManagementService(); @@ -1687,7 +1448,7 @@ exit", Convert.ToInt32(objDisk["Index"]))); cmd.Parameters.Add("DestinationPath", destinationPath); cmd.Parameters.Add("VHDType", diskType.ToString()); - PowerShell.Execute(cmd, false); + PowerShell.Execute(cmd, true); return JobHelper.CreateSuccessResult(ReturnCode.JobStarted); } catch (Exception ex) @@ -1840,53 +1601,41 @@ exit", Convert.ToInt32(objDisk["Index"]))); #region Jobs public ConcreteJob GetJob(string jobId) { - HostedSolutionLog.LogStart("GetJob"); - HostedSolutionLog.DebugInfo("jobId: {0}", jobId); + throw new NotImplementedException(); - Runspace runSpace = null; - ConcreteJob job; + //HostedSolutionLog.LogStart("GetJob"); + //HostedSolutionLog.DebugInfo("jobId: {0}", jobId); - try - { - Command cmd = new Command("Get-Job"); + //Runspace runSpace = null; + //ConcreteJob job; - if (!string.IsNullOrEmpty(jobId)) cmd.Parameters.Add("Id", jobId); + //try + //{ + // Command cmd = new Command("Get-Job"); - Collection result = PowerShell.Execute( cmd, false); - job = JobHelper.CreateFromPSObject(result); - } - catch (Exception ex) - { - HostedSolutionLog.LogError("GetJob", ex); - throw; - } + // if (!string.IsNullOrEmpty(jobId)) cmd.Parameters.Add("Id", jobId); - HostedSolutionLog.LogEnd("GetJob"); - return job; + // Collection result = PowerShell.Execute(cmd, true); + // job = JobHelper.CreateFromPSObject(result); + //} + //catch (Exception ex) + //{ + // HostedSolutionLog.LogError("GetJob", ex); + // throw; + //} + + //HostedSolutionLog.LogEnd("GetJob"); + //return job; } public List GetAllJobs() { - List jobs = new List(); - - ManagementObjectCollection objJobs = wmi.GetWmiObjects("CIM_ConcreteJob"); - foreach (ManagementObject objJob in objJobs) - jobs.Add(CreateJobFromWmiObject(objJob)); - - return jobs; + throw new NotImplementedException(); } public ChangeJobStateReturnCode ChangeJobState(string jobId, ConcreteJobRequestedState newState) { - ManagementObject objJob = GetJobWmiObject(jobId); - - // get method - ManagementBaseObject inParams = objJob.GetMethodParameters("RequestStateChange"); - inParams["RequestedState"] = (Int32)newState; - - // invoke method - ManagementBaseObject outParams = objJob.InvokeMethod("RequestStateChange", inParams, null); - return (ChangeJobStateReturnCode)Convert.ToInt32(outParams["ReturnValue"]); + throw new NotImplementedException(); } #endregion @@ -2504,7 +2253,7 @@ exit", Convert.ToInt32(objDisk["Index"]))); private PowerShellManager _powerShell; protected PowerShellManager PowerShell { - get { return _powerShell ?? (_powerShell = new PowerShellManager()); } + get { return _powerShell ?? (_powerShell = new PowerShellManager(ServerNameSettings)); } } #endregion diff --git a/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/PowerShellManager.cs b/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/PowerShellManager.cs index 949b08bd..74298da0 100644 --- a/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/PowerShellManager.cs +++ b/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/PowerShellManager.cs @@ -12,12 +12,14 @@ namespace WebsitePanel.Providers.Virtualization { public class PowerShellManager : IDisposable { + private readonly string _remoteComputerName; protected static InitialSessionState session = null; protected Runspace RunSpace { get; set; } - public PowerShellManager() + public PowerShellManager(string remoteComputerName) { + _remoteComputerName = remoteComputerName; OpenRunspace(); } @@ -61,24 +63,27 @@ namespace WebsitePanel.Providers.Virtualization return Execute(cmd, true); } - public Collection Execute(Command cmd, bool useDomainController) + public Collection Execute(Command cmd, bool addComputerNameParameter) { object[] errors; - return Execute(cmd, useDomainController, out errors); + return Execute(cmd, addComputerNameParameter, out errors); } - public Collection Execute(Command cmd, out object[] errors) - { - return Execute(cmd, true, out errors); - } - - public Collection Execute(Command cmd, bool useDomainController, out object[] errors) + public Collection Execute(Command cmd, bool addComputerNameParameter, out object[] errors) { HostedSolutionLog.LogStart("Execute"); List errorList = new List(); HostedSolutionLog.DebugCommand(cmd); Collection results = null; + + // Add computerName parameter to command if it is remote server + if (addComputerNameParameter) + { + if (!string.IsNullOrEmpty(_remoteComputerName)) + cmd.Parameters.Add("ComputerName", _remoteComputerName); + } + // Create a pipeline Pipeline pipeLine = RunSpace.CreatePipeline(); using (pipeLine) @@ -88,6 +93,8 @@ namespace WebsitePanel.Providers.Virtualization // Execute the pipeline and save the objects returned. results = pipeLine.Invoke(); + // Only non-terminating errors are delivered here. + // Terminating errors raise exceptions instead. // Log out any errors in the pipeline execution // NOTE: These errors are NOT thrown as exceptions! // Be sure to check this to ensure that no errors @@ -108,52 +115,10 @@ namespace WebsitePanel.Providers.Virtualization return results; } - - /// - /// Returns the identity of the object from the shell execution result - /// - /// - /// - public static string GetResultObjectIdentity(Collection result) + public static void ExceptionIfErrors(object[] errors) { - HostedSolutionLog.LogStart("GetResultObjectIdentity"); - if (result == null) - throw new ArgumentNullException("result", "Execution result is not specified"); - - if (result.Count < 1) - throw new ArgumentException("Execution result is empty", "result"); - - if (result.Count > 1) - throw new ArgumentException("Execution result contains more than one object", "result"); - - PSMemberInfo info = result[0].Members["Identity"]; - if (info == null) - throw new ArgumentException("Execution result does not contain Identity property", "result"); - - string ret = info.Value.ToString(); - HostedSolutionLog.LogEnd("GetResultObjectIdentity"); - return ret; - } - - public static string GetResultObjectDN(Collection result) - { - HostedSolutionLog.LogStart("GetResultObjectDN"); - if (result == null) - throw new ArgumentNullException("result", "Execution result is not specified"); - - if (result.Count < 1) - throw new ArgumentException("Execution result does not contain any object"); - - if (result.Count > 1) - throw new ArgumentException("Execution result contains more than one object"); - - PSMemberInfo info = result[0].Members["DistinguishedName"]; - if (info == null) - throw new ArgumentException("Execution result does not contain DistinguishedName property", "result"); - - string ret = info.Value.ToString(); - HostedSolutionLog.LogEnd("GetResultObjectDN"); - return ret; + if (errors != null && errors.Length > 0) + throw new Exception("Invoke error: " + string.Join("; ", errors.Select(e => e.ToString()))); } } }