diff --git a/WebsitePanel/Sources/WebsitePanel.Providers.Base/Virtualization/VirtualMachine.cs b/WebsitePanel/Sources/WebsitePanel.Providers.Base/Virtualization/VirtualMachine.cs index 5f5847a8..11da6676 100644 --- a/WebsitePanel/Sources/WebsitePanel.Providers.Base/Virtualization/VirtualMachine.cs +++ b/WebsitePanel/Sources/WebsitePanel.Providers.Base/Virtualization/VirtualMachine.cs @@ -136,5 +136,11 @@ namespace WebsitePanel.Providers.Virtualization [Persistent] public int Generation { get; set; } + [Persistent] + public int ProcessorCount { get; set; } + + [Persistent] + public string ParentSnapshotId { get; set; } + } } diff --git a/WebsitePanel/Sources/WebsitePanel.Providers.Base/Virtualization/VirtualMachineSnapshot.cs b/WebsitePanel/Sources/WebsitePanel.Providers.Base/Virtualization/VirtualMachineSnapshot.cs index f8f496ce..a20ae5f0 100644 --- a/WebsitePanel/Sources/WebsitePanel.Providers.Base/Virtualization/VirtualMachineSnapshot.cs +++ b/WebsitePanel/Sources/WebsitePanel.Providers.Base/Virtualization/VirtualMachineSnapshot.cs @@ -37,6 +37,7 @@ namespace WebsitePanel.Providers.Virtualization public string Id { get; set; } public string CheckPointId { get; set; } public string Name { get; set; } + public string VMName { get; set; } public string ParentId { get; set; } public DateTime Created { get; set; } public bool IsCurrent { get; set; } diff --git a/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/Extensions/PSObjectExtension.cs b/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/Extensions/PSObjectExtension.cs index e1a50bfa..33426fe2 100644 --- a/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/Extensions/PSObjectExtension.cs +++ b/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/Extensions/PSObjectExtension.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Management; using System.Management.Automation; using System.Text; using System.Threading.Tasks; @@ -9,6 +10,8 @@ namespace WebsitePanel.Providers.Virtualization { static class PSObjectExtension { + #region Properties + public static object GetProperty(this PSObject obj, string name) { return obj.Members[name].Value; @@ -33,5 +36,27 @@ namespace WebsitePanel.Providers.Virtualization { return obj.Members[name].Value == null ? "" : obj.Members[name].Value.ToString(); } + + #endregion + + + #region Methods + + public static ManagementObject Invoke(this PSObject obj, string name, object argument) + { + return obj.Invoke(name, new[] {argument}); + } + public static ManagementObject Invoke(this PSObject obj, string name, params object[] arguments) + { + var results = (ManagementObjectCollection)obj.Methods[name].Invoke(arguments); + + foreach (var result in results) + { + return (ManagementObject) result; + } + return null; + } + + #endregion } } 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 25fcfe3b..ebfc9694 100644 --- a/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/Helpers/BiosHelper.cs +++ b/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/Helpers/BiosHelper.cs @@ -12,7 +12,7 @@ namespace WebsitePanel.Providers.Virtualization { public static class BiosHelper { - public static BiosInfo GetVMBios(PowerShellManager powerShell, string name, int generation) + public static BiosInfo Get(PowerShellManager powerShell, string name, int generation) { BiosInfo info = new BiosInfo(); @@ -76,7 +76,7 @@ namespace WebsitePanel.Providers.Virtualization return info; } - public static void UpdateBios(PowerShellManager powerShell, VirtualMachine vm, bool bootFromCD, bool numLockEnabled) + public static void Update(PowerShellManager powerShell, VirtualMachine vm, bool bootFromCD, bool numLockEnabled) { // for Win2012R2+ and Win8.1+ if (vm.Generation == 2) diff --git a/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/Helpers/JobHelper.cs b/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/Helpers/JobHelper.cs new file mode 100644 index 00000000..92d1e95a --- /dev/null +++ b/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/Helpers/JobHelper.cs @@ -0,0 +1,74 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Management.Automation; +using System.Management.Automation.Runspaces; +using System.Text; +using System.Threading.Tasks; + +namespace WebsitePanel.Providers.Virtualization +{ + public static class JobHelper + { + public static JobResult CreateSuccessResult(ReturnCode returnCode = ReturnCode.OK) + { + return new JobResult + { + Job = new ConcreteJob {JobState = ConcreteJobState.Completed}, + ReturnValue = returnCode + }; + } + + public static JobResult CreateResultFromPSResults(Collection objJob) + { + if (objJob == null || objJob.Count == 0) + return null; + + JobResult result = new JobResult(); + + result.Job = CreateFromPSObject(objJob); + result.ReturnValue = ReturnCode.JobStarted; + + switch (result.Job.JobState) + { + case ConcreteJobState.Failed: + result.ReturnValue = ReturnCode.Failed; + break; + } + + return result; + } + + public static ConcreteJob CreateFromPSObject(Collection objJob) + { + if (objJob == null || objJob.Count == 0) + return null; + + ConcreteJob job = new ConcreteJob(); + job.Id = objJob[0].GetProperty("Id").ToString(); + job.JobState = objJob[0].GetEnum("JobStateInfo"); + job.Caption = objJob[0].GetProperty("Name"); + job.Description = objJob[0].GetProperty("Command"); + job.StartTime = objJob[0].GetProperty("PSBeginTime"); + job.ElapsedTime = objJob[0].GetProperty("PSEndTime") ?? DateTime.Now; + + // PercentComplete + job.PercentComplete = 0; + var progress = (PSDataCollection)objJob[0].GetProperty("Progress"); + if (progress != null && progress.Count > 0) + job.PercentComplete = progress[0].PercentComplete; + + // Errors + var errors = (PSDataCollection)objJob[0].GetProperty("Error"); + if (errors != null && errors.Count > 0) + { + job.ErrorDescription = errors[0].ErrorDetails.Message + ". " + errors[0].ErrorDetails.RecommendedAction; + job.ErrorCode = errors[0].Exception != null ? -1 : 0; + } + + return job; + } + + } +} diff --git a/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/Helpers/SnapshotHelper.cs b/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/Helpers/SnapshotHelper.cs new file mode 100644 index 00000000..b5dee5c2 --- /dev/null +++ b/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/Helpers/SnapshotHelper.cs @@ -0,0 +1,72 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Management; +using System.Management.Automation; +using System.Management.Automation.Runspaces; +using System.Text; +using System.Threading.Tasks; + +namespace WebsitePanel.Providers.Virtualization +{ + public static class SnapshotHelper + { + public static VirtualMachineSnapshot GetFromPS(PSObject psObject, string runningSnapshotId = null) + { + var snapshot = new VirtualMachineSnapshot + { + Id = psObject.GetString("Id"), + Name = psObject.GetString("Name"), + VMName = psObject.GetString("VMName"), + ParentId = psObject.GetString("ParentSnapshotId"), + Created = psObject.GetProperty("CreationTime") + }; + + if (string.IsNullOrEmpty(snapshot.ParentId)) + snapshot.ParentId = null; // for capability + + if (!String.IsNullOrEmpty(runningSnapshotId)) + snapshot.IsCurrent = snapshot.Id == runningSnapshotId; + + return snapshot; + } + + public static VirtualMachineSnapshot GetFromWmi(ManagementBaseObject objSnapshot) + { + if (objSnapshot == null || objSnapshot.Properties.Count == 0) + return null; + + VirtualMachineSnapshot snapshot = new VirtualMachineSnapshot(); + snapshot.Id = (string)objSnapshot["InstanceID"]; + snapshot.Name = (string)objSnapshot["ElementName"]; + + string parentId = (string)objSnapshot["Parent"]; + if (!String.IsNullOrEmpty(parentId)) + { + int idx = parentId.IndexOf("Microsoft:"); + snapshot.ParentId = parentId.Substring(idx, parentId.Length - idx - 1); + snapshot.ParentId = snapshot.ParentId.ToLower().Replace("microsoft:", ""); + } + if (!String.IsNullOrEmpty(snapshot.Id)) + { + snapshot.Id = snapshot.Id.ToLower().Replace("microsoft:", ""); + } + snapshot.Created = Wmi.ToDateTime((string)objSnapshot["CreationTime"]); + + if (string.IsNullOrEmpty(snapshot.ParentId)) + snapshot.ParentId = null; // for capability + + return snapshot; + } + + public static void Delete(PowerShellManager powerShell, VirtualMachineSnapshot snapshot, bool includeChilds) + { + Command cmd = new Command("Remove-VMSnapshot"); + cmd.Parameters.Add("VMName", snapshot.VMName); + cmd.Parameters.Add("Name", snapshot.Name); + if (includeChilds) cmd.Parameters.Add("IncludeAllChildSnapshots", true); + + powerShell.Execute(cmd, false); + } + } +} diff --git a/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/HyperV2012R2.cs b/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/HyperV2012R2.cs index e14db44b..095eba14 100644 --- a/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/HyperV2012R2.cs +++ b/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/HyperV2012R2.cs @@ -59,7 +59,7 @@ namespace WebsitePanel.Providers.Virtualization { #region Constants private const string CONFIG_USE_DISKPART_TO_CLEAR_READONLY_FLAG = "WebsitePanel.HyperV.UseDiskPartClearReadOnlyFlag"; - private const string WMI_VIRTUALIZATION_NAMESPACE = @"root\virtualization"; + private const string WMI_VIRTUALIZATION_NAMESPACE = @"root\virtualization\v2"; private const string WMI_CIMV2_NAMESPACE = @"root\cimv2"; private const int SWITCH_PORTS_NUMBER = 1024; @@ -174,6 +174,8 @@ namespace WebsitePanel.Providers.Virtualization vm.Status = result[0].GetProperty("Status").ToString(); vm.ReplicationState = result[0].GetProperty("ReplicationState").ToString(); vm.Generation = result[0].GetInt("Generation"); + vm.ProcessorCount = result[0].GetInt("ProcessorCount"); + vm.ParentSnapshotId = result[0].GetString("ParentSnapshotId"); vm.Heartbeat = VirtualMachineHelper.GetVMHeartBeatStatus(PowerShell, vm.Name); @@ -187,7 +189,7 @@ namespace WebsitePanel.Providers.Virtualization vm.RamSize = memoryInfo.Startup; // BIOS - BiosInfo biosInfo = BiosHelper.GetVMBios(PowerShell, vm.Name, vm.Generation); + BiosInfo biosInfo = BiosHelper.Get(PowerShell, vm.Name, vm.Generation); vm.NumLockEnabled = biosInfo.NumLockEnabled; vm.BootFromCD = biosInfo.BootFromCD; @@ -219,6 +221,7 @@ namespace WebsitePanel.Providers.Virtualization return vm; } + public List GetVirtualMachines() { HostedSolutionLog.LogStart("GetVirtualMachines"); @@ -255,11 +258,10 @@ namespace WebsitePanel.Providers.Virtualization public byte[] GetVirtualMachineThumbnailImage(string vmId, ThumbnailSize size) { - //ManagementBaseObject objSummary = GetVirtualMachineSummaryInformation(vmId, (SummaryInformationRequest)size); - //wmi.Dump(objSummary); - //return GetTumbnailFromSummaryInformation(objSummary, size); - // TODO: - return (byte[]) (new ImageConverter()).ConvertTo(new Bitmap(80, 60), typeof (byte[])); + ManagementBaseObject objSummary = GetVirtualMachineSummaryInformation(vmId, (SummaryInformationRequest)size); + wmi.Dump(objSummary); + return GetTumbnailFromSummaryInformation(objSummary, size); + //return (byte[]) (new ImageConverter()).ConvertTo(new Bitmap(80, 60), typeof (byte[])); } private byte[] GetTumbnailFromSummaryInformation(ManagementBaseObject objSummary, ThumbnailSize size) @@ -436,7 +438,7 @@ namespace WebsitePanel.Providers.Virtualization var realVm = GetVirtualMachineEx(vm.VirtualMachineId); DvdDriveHelper.Update(PowerShell, realVm, vm.DvdDriveInstalled); // Dvd should be before bios because bios sets boot order - BiosHelper.UpdateBios(PowerShell, realVm, vm.BootFromCD, vm.NumLockEnabled); + BiosHelper.Update(PowerShell, realVm, vm.BootFromCD, vm.NumLockEnabled); VirtualMachineHelper.UpdateProcessors(PowerShell, realVm, vm.CpuCores, CpuLimitSettings, CpuReserveSettings, CpuWeightSettings); VirtualMachineHelper.UpdateMemory(PowerShell, realVm, vm.RamSize); NetworkAdapterHelper.Update(PowerShell, vm); @@ -661,7 +663,7 @@ namespace WebsitePanel.Providers.Virtualization paramList.ForEach(p => cmd.Parameters.Add(p)); PowerShell.Execute(cmd, false); - jobResult = CreateSuccessJobResult(); + jobResult = JobHelper.CreateSuccessResult(); } catch (Exception ex) { @@ -852,130 +854,148 @@ namespace WebsitePanel.Providers.Virtualization #endregion #region Snapshots + public List GetVirtualMachineSnapshots(string vmId) { - // get all VM setting objects - ManagementObject objVmSettings = GetVirtualMachineSettingsObject(vmId); - VirtualMachineSnapshot runningSnapshot = CreateSnapshotFromWmiObject(objVmSettings); - - // load snapshots - ManagementBaseObject objSummary = GetVirtualMachineSummaryInformation(vmId, SummaryInformationRequest.Snapshots); - ManagementBaseObject[] objSnapshots = (ManagementBaseObject[])objSummary["Snapshots"]; - List snapshots = new List(); - if (objSnapshots != null) + try { - foreach (ManagementBaseObject objSnapshot in objSnapshots) + var vm = GetVirtualMachine(vmId); + + Command cmd = new Command("Get-VMSnapshot"); + cmd.Parameters.Add("VMName", vm.Name); + + Collection result = PowerShell.Execute(cmd, false); + if (result != null && result.Count > 0) { - VirtualMachineSnapshot snapshot = CreateSnapshotFromWmiObject(objSnapshot); - snapshot.IsCurrent = (runningSnapshot.ParentId == snapshot.Id); - snapshots.Add(snapshot); + foreach (PSObject psSnapshot in result) + { + snapshots.Add(SnapshotHelper.GetFromPS(psSnapshot, vm.ParentSnapshotId)); + } } } + catch (Exception ex) + { + HostedSolutionLog.LogError("GetVirtualMachineSnapshots", ex); + throw; + } return snapshots; } public VirtualMachineSnapshot GetSnapshot(string snapshotId) { - // load snapshot - ManagementObject objSnapshot = GetSnapshotObject(snapshotId); - return CreateSnapshotFromWmiObject(objSnapshot); + try + { + Command cmd = new Command("Get-VMSnapshot"); + cmd.Parameters.Add("Id", snapshotId); + + Collection result = PowerShell.Execute(cmd, false); + if (result != null && result.Count > 0) + { + return SnapshotHelper.GetFromPS(result[0]); + } + } + catch (Exception ex) + { + HostedSolutionLog.LogError("GetSnapshot", ex); + throw; + } + + return null; } public JobResult CreateSnapshot(string vmId) { - // get VM management service - ManagementObject objVmsvc = GetVirtualSystemManagementService(); + try + { + var vm = GetVirtualMachine(vmId); - // load virtual machine - ManagementObject objVm = GetVirtualMachineObject(vmId); + Command cmd = new Command("Checkpoint-VM"); + cmd.Parameters.Add("Name", vm.Name); - // get method params - ManagementBaseObject inParams = objVmsvc.GetMethodParameters("CreateVirtualSystemSnapshot"); - inParams["SourceSystem"] = objVm; - - // invoke method - ManagementBaseObject outParams = objVmsvc.InvokeMethod("CreateVirtualSystemSnapshot", inParams, null); - return CreateJobResultFromWmiMethodResults(outParams); + PowerShell.Execute(cmd, false); + return JobHelper.CreateSuccessResult(ReturnCode.JobStarted); + } + catch (Exception ex) + { + HostedSolutionLog.LogError("CreateSnapshot", ex); + throw; + } } public JobResult RenameSnapshot(string vmId, string snapshotId, string name) { - // load virtual machine - ManagementObject objVm = GetVirtualMachineObject(vmId); + try + { + var vm = GetVirtualMachine(vmId); + var snapshot = GetSnapshot(snapshotId); - // load snapshot - ManagementObject objSnapshot = GetSnapshotObject(snapshotId); + Command cmd = new Command("Rename-VMSnapshot"); + cmd.Parameters.Add("VMName", vm.Name); + cmd.Parameters.Add("Name", snapshot.Name); + cmd.Parameters.Add("NewName", name); - // rename snapshot - objSnapshot["ElementName"] = name; - - // save - ManagementObject objVmsvc = GetVirtualSystemManagementService(); - ManagementBaseObject inParams = objVmsvc.GetMethodParameters("ModifyVirtualSystem"); - inParams["ComputerSystem"] = objVm.Path.Path; - inParams["SystemSettingData"] = objSnapshot.GetText(TextFormat.CimDtd20); - ManagementBaseObject outParams = objVmsvc.InvokeMethod("ModifyVirtualSystem", inParams, null); - return CreateJobResultFromWmiMethodResults(outParams); + PowerShell.Execute(cmd, false); + return JobHelper.CreateSuccessResult(); + } + catch (Exception ex) + { + HostedSolutionLog.LogError("RenameSnapshot", ex); + throw; + } } public JobResult ApplySnapshot(string vmId, string snapshotId) { - // get VM management service - ManagementObject objVmsvc = GetVirtualSystemManagementService(); + try + { + var vm = GetVirtualMachine(vmId); + var snapshot = GetSnapshot(snapshotId); - // load virtual machine - ManagementObject objVm = GetVirtualMachineObject(vmId); + Command cmd = new Command("Restore-VMSnapshot"); + cmd.Parameters.Add("VMName", vm.Name); + cmd.Parameters.Add("Name", snapshot.Name); - // load snapshot - ManagementObject objSnapshot = GetSnapshotObject(snapshotId); - - ManagementObjectCollection objRelated = objVm.GetRelated("Msvm_SettingsDefineState"); - - // get method params - ManagementBaseObject inParams = objVmsvc.GetMethodParameters("ApplyVirtualSystemSnapshot"); - inParams["ComputerSystem"] = objVm.Path.Path; - inParams["SnapshotSettingData"] = objSnapshot.Path.Path; - - // invoke method - ManagementBaseObject outParams = objVmsvc.InvokeMethod("ApplyVirtualSystemSnapshot", inParams, null); - return CreateJobResultFromWmiMethodResults(outParams); + PowerShell.Execute(cmd, false); + return JobHelper.CreateSuccessResult(); + } + catch (Exception ex) + { + HostedSolutionLog.LogError("ApplySnapshot", ex); + throw; + } } public JobResult DeleteSnapshot(string snapshotId) { - // get VM management service - ManagementObject objVmsvc = GetVirtualSystemManagementService(); - - // load snapshot object - ManagementObject objSnapshot = GetSnapshotObject(snapshotId); - - // get method params - ManagementBaseObject inParams = objVmsvc.GetMethodParameters("RemoveVirtualSystemSnapshot"); - inParams["SnapshotSettingData"] = objSnapshot.Path.Path; - - // invoke method - ManagementBaseObject outParams = objVmsvc.InvokeMethod("RemoveVirtualSystemSnapshot", inParams, null); - return CreateJobResultFromWmiMethodResults(outParams); + try + { + var snapshot = GetSnapshot(snapshotId); + SnapshotHelper.Delete(PowerShell, snapshot, false); + return JobHelper.CreateSuccessResult(ReturnCode.JobStarted); + } + catch (Exception ex) + { + HostedSolutionLog.LogError("DeleteSnapshot", ex); + throw; + } } public JobResult DeleteSnapshotSubtree(string snapshotId) { - // get VM management service - ManagementObject objVmsvc = GetVirtualSystemManagementService(); - - // load snapshot object - ManagementObject objSnapshot = GetSnapshotObject(snapshotId); - - // get method params - ManagementBaseObject inParams = objVmsvc.GetMethodParameters("RemoveVirtualSystemSnapshotTree"); - inParams["SnapshotSettingData"] = objSnapshot.Path.Path; - - // invoke method - ManagementBaseObject outParams = objVmsvc.InvokeMethod("RemoveVirtualSystemSnapshotTree", inParams, null); - return CreateJobResultFromWmiMethodResults(outParams); + try + { + var snapshot = GetSnapshot(snapshotId); + SnapshotHelper.Delete(PowerShell, snapshot, true); + return JobHelper.CreateSuccessResult(ReturnCode.JobStarted); + } + catch (Exception ex) + { + HostedSolutionLog.LogError("DeleteSnapshot", ex); + throw; + } } public byte[] GetSnapshotThumbnailImage(string snapshotId, ThumbnailSize size) @@ -983,6 +1003,7 @@ namespace WebsitePanel.Providers.Virtualization ManagementBaseObject objSummary = GetSnapshotSummaryInformation(snapshotId, (SummaryInformationRequest)size); return GetTumbnailFromSummaryInformation(objSummary, size); } + #endregion #region DVD operations @@ -1029,7 +1050,7 @@ namespace WebsitePanel.Providers.Virtualization } HostedSolutionLog.LogEnd("InsertDVD"); - return CreateSuccessJobResult(); + return JobHelper.CreateSuccessResult(); } public JobResult EjectDVD(string vmId) @@ -1049,7 +1070,7 @@ namespace WebsitePanel.Providers.Virtualization } HostedSolutionLog.LogEnd("InsertDVD"); - return CreateSuccessJobResult(); + return JobHelper.CreateSuccessResult(); } #endregion @@ -1276,8 +1297,7 @@ namespace WebsitePanel.Providers.Virtualization } catch { - // TODO - // add logging... + HostedSolutionLog.LogError("GetKVPItems", new Exception("msvm_KvpExchangeComponent")); return pairs; } @@ -1306,7 +1326,71 @@ namespace WebsitePanel.Providers.Virtualization pairs.Add(new KvpExchangeDataItem(name, data)); } - return pairs; + return pairs; + + //HostedSolutionLog.LogStart("GetKVPItems"); + //HostedSolutionLog.DebugInfo("Virtual Machine: {0}", vmId); + //HostedSolutionLog.DebugInfo("exchangeItemsName: {0}", exchangeItemsName); + + //List pairs = new List(); + + //try + //{ + // var vm = GetVirtualMachine(vmId); + + // Command cmdGetVm = new Command("Get-WmiObject"); + + // cmdGetVm.Parameters.Add("Namespace", WMI_VIRTUALIZATION_NAMESPACE); + // cmdGetVm.Parameters.Add("Class", "Msvm_ComputerSystem"); + // cmdGetVm.Parameters.Add("Filter", "ElementName = '" + vm.Name + "'"); + + // Collection result = PowerShell.Execute(cmdGetVm, false); + + // if (result != null && result.Count > 0) + // { + // dynamic resultDynamic = result[0];//.Invoke(); + // var kvp = resultDynamic.GetRelated("Msvm_KvpExchangeComponent"); + + // // return XML pairs + // string[] xmlPairs = null; + + // foreach (dynamic a in kvp) + // { + // xmlPairs = a[exchangeItemsName]; + // break; + // } + + // if (xmlPairs == null) + // return pairs; + + // // join all pairs + // StringBuilder sb = new StringBuilder(); + // sb.Append(""); + // foreach (string xmlPair in xmlPairs) + // sb.Append(xmlPair); + // sb.Append(""); + + // // parse pairs + // XmlDocument doc = new XmlDocument(); + // doc.LoadXml(sb.ToString()); + + // foreach (XmlNode nodeName in doc.SelectNodes("/result/INSTANCE/PROPERTY[@NAME='Name']/VALUE")) + // { + // string name = nodeName.InnerText; + // string data = nodeName.ParentNode.ParentNode.SelectSingleNode("PROPERTY[@NAME='Data']/VALUE").InnerText; + // pairs.Add(new KvpExchangeDataItem(name, data)); + // } + // } + //} + //catch (Exception ex) + //{ + // HostedSolutionLog.LogError("GetKVPItems", ex); + // throw; + //} + + //HostedSolutionLog.LogEnd("GetKVPItems"); + + //return pairs; } public JobResult AddKVPItems(string vmId, KvpExchangeDataItem[] items) @@ -1832,13 +1916,12 @@ exit", Convert.ToInt32(objDisk["Index"]))); try { - Command cmd = new Command("Get-Job"); if (!string.IsNullOrEmpty(jobId)) cmd.Parameters.Add("Id", jobId); Collection result = PowerShell.Execute( cmd, false); - job = CreateJobFromPSObject(result); + job = JobHelper.CreateFromPSObject(result); } catch (Exception ex) { @@ -2123,35 +2206,15 @@ exit", Convert.ToInt32(objDisk["Index"]))); { return value == null ? 0 : Convert.ToInt64(value); } + + //protected VirtualMachineSnapshot GetSnapshotById(string id) + //{ + // var vms = GetVirtualMachines(); + // var allSnapshots = vms.SelectMany(vm => GetVirtualMachineSnapshots(vm.Id.ToString())); + + // return allSnapshots.FirstOrDefault(s => s.Id == id); + //} - protected JobResult CreateSuccessJobResult() - { - JobResult result = new JobResult(); - - result.Job = new ConcreteJob(){JobState = ConcreteJobState.Completed}; - result.ReturnValue = ReturnCode.OK; - - return result; - } - protected JobResult CreateJobResultFromPSResults(Collection objJob) - { - if (objJob == null || objJob.Count == 0) - return null; - - JobResult result = new JobResult(); - - result.Job = CreateJobFromPSObject(objJob); - - result.ReturnValue = ReturnCode.JobStarted; - switch (result.Job.JobState) - { - case ConcreteJobState.Failed: - result.ReturnValue = ReturnCode.Failed; - break; - } - - return result; - } protected JobResult CreateJobResultFromWmiMethodResults(ManagementBaseObject outParams) { @@ -2201,29 +2264,12 @@ exit", Convert.ToInt32(objDisk["Index"]))); private ManagementObject GetSnapshotObject(string snapshotId) { - return wmi.GetWmiObject("Msvm_VirtualSystemSettingData", "InstanceID = '{0}'", snapshotId); + return wmi.GetWmiObject("Msvm_VirtualSystemSettingData", "InstanceID = '{0}'", snapshotId) ?? + wmi.GetWmiObject("Msvm_VirtualSystemSettingData", "InstanceID = '{0}'", "Microsoft:" + snapshotId); } - private VirtualMachineSnapshot CreateSnapshotFromWmiObject(ManagementBaseObject objSnapshot) - { - if (objSnapshot == null || objSnapshot.Properties.Count == 0) - return null; - - VirtualMachineSnapshot snapshot = new VirtualMachineSnapshot(); - snapshot.Id = (string)objSnapshot["InstanceID"]; - snapshot.Name = (string)objSnapshot["ElementName"]; - - string parentId = (string)objSnapshot["Parent"]; - if (!String.IsNullOrEmpty(parentId)) - { - int idx = parentId.IndexOf("Microsoft:"); - snapshot.ParentId = parentId.Substring(idx, parentId.Length - idx - 1); - } - snapshot.Created = wmi.ToDateTime((string)objSnapshot["CreationTime"]); - - return snapshot; - } + private VirtualSwitch CreateSwitchFromWmiObject(ManagementObject objSwitch) { @@ -2236,36 +2282,6 @@ exit", Convert.ToInt32(objDisk["Index"]))); return sw; } - private ConcreteJob CreateJobFromPSObject(Collection objJob) - { - if (objJob == null || objJob.Count == 0) - return null; - - ConcreteJob job = new ConcreteJob(); - job.Id = objJob[0].GetProperty("Id").ToString(); - job.JobState = objJob[0].GetEnum("JobStateInfo"); - job.Caption = objJob[0].GetProperty("Name"); - job.Description = objJob[0].GetProperty("Command"); - job.StartTime = objJob[0].GetProperty("PSBeginTime"); - job.ElapsedTime = objJob[0].GetProperty("PSEndTime") ?? DateTime.Now; - - // PercentComplete - job.PercentComplete = 0; - var progress = (PSDataCollection)objJob[0].GetProperty("Progress"); - if (progress != null && progress.Count > 0) - job.PercentComplete = progress[0].PercentComplete; - - // Errors - var errors = (PSDataCollection)objJob[0].GetProperty("Error"); - if (errors != null && errors.Count > 0) - { - job.ErrorDescription = errors[0].ErrorDetails.Message + ". " + errors[0].ErrorDetails.RecommendedAction; - job.ErrorCode = errors[0].Exception != null ? -1 : 0; - } - - return job; - } - private ConcreteJob CreateJobFromWmiObject(ManagementBaseObject objJob) { if (objJob == null || objJob.Properties.Count == 0) @@ -2276,7 +2292,7 @@ exit", Convert.ToInt32(objDisk["Index"]))); job.JobState = (ConcreteJobState)Convert.ToInt32(objJob["JobState"]); job.Caption = (string)objJob["Caption"]; job.Description = (string)objJob["Description"]; - job.StartTime = wmi.ToDateTime((string)objJob["StartTime"]); + job.StartTime = Wmi.ToDateTime((string)objJob["StartTime"]); // TODO proper parsing of WMI time spans, e.g. 00000000000001.325247:000 job.ElapsedTime = DateTime.Now; //wmi.ToDateTime((string)objJob["ElapsedTime"]); job.ErrorCode = Convert.ToInt32(objJob["ErrorCode"]); diff --git a/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/WebsitePanel.Providers.Virtualization.HyperV2012R2.csproj b/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/WebsitePanel.Providers.Virtualization.HyperV2012R2.csproj index d033344b..c18926b0 100644 --- a/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/WebsitePanel.Providers.Virtualization.HyperV2012R2.csproj +++ b/WebsitePanel/Sources/WebsitePanel.Providers.Virtualization.HyperV-2012R2/WebsitePanel.Providers.Virtualization.HyperV2012R2.csproj @@ -57,6 +57,8 @@ + +