wsp-10323 Convert the VSP provider into one utilizing PowerShell. Step 2
This commit is contained in:
parent
a96931786c
commit
5b09a543f8
10 changed files with 699 additions and 493 deletions
|
@ -0,0 +1,43 @@
|
|||
// Copyright (c) 2014, Outercurve Foundation.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// - Redistributions of source code must retain the above copyright notice, this
|
||||
// list of conditions and the following disclaimer.
|
||||
//
|
||||
// - Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// - Neither the name of the Outercurve Foundation nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace WebsitePanel.Providers.Virtualization
|
||||
{
|
||||
public class DvdDriveInfo
|
||||
{
|
||||
public ControllerType ControllerType { get; set; }
|
||||
public int ControllerNumber { get; set; }
|
||||
public int ControllerLocation { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string Id { get; set; }
|
||||
}
|
||||
}
|
|
@ -36,5 +36,6 @@ namespace WebsitePanel.Providers.Virtualization
|
|||
{
|
||||
public string Name { get; set; }
|
||||
public string MacAddress { get; set; }
|
||||
public string SwitchName { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -309,6 +309,7 @@
|
|||
<Compile Include="Virtualization\KvpExchangeDataItem.cs" />
|
||||
<Compile Include="Virtualization\LibraryItem.cs" />
|
||||
<Compile Include="Virtualization\LogicalDisk.cs" />
|
||||
<Compile Include="Virtualization\DvdDriveInfo.cs" />
|
||||
<Compile Include="Virtualization\MemoryInfo.cs" />
|
||||
<Compile Include="Virtualization\MonitoredObjectAlert.cs" />
|
||||
<Compile Include="Virtualization\MonitoredObjectEvent.cs" />
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Management.Automation;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace WebsitePanel.Providers.Virtualization
|
||||
{
|
||||
static class PSObjectExtension
|
||||
{
|
||||
public static object GetProperty(this PSObject obj, string name)
|
||||
{
|
||||
return obj.Members[name].Value;
|
||||
}
|
||||
public static T GetProperty<T>(this PSObject obj, string name)
|
||||
{
|
||||
return (T)obj.Members[name].Value;
|
||||
}
|
||||
public static T GetEnum<T>(this PSObject obj, string name) where T : struct
|
||||
{
|
||||
return (T)Enum.Parse(typeof(T), GetProperty(obj, name).ToString());
|
||||
}
|
||||
public static int GetInt(this PSObject obj, string name)
|
||||
{
|
||||
return Convert.ToInt32(obj.Members[name].Value);
|
||||
}
|
||||
public static long GetLong(this PSObject obj, string name)
|
||||
{
|
||||
return Convert.ToInt64(obj.Members[name].Value);
|
||||
}
|
||||
public static string GetString(this PSObject obj, string name)
|
||||
{
|
||||
return obj.Members[name].Value == null ? "" : obj.Members[name].Value.ToString();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
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 DvdDriveHelper
|
||||
{
|
||||
public static DvdDriveInfo Get(PowerShellManager powerShell, string vmName)
|
||||
{
|
||||
DvdDriveInfo info = new DvdDriveInfo();
|
||||
|
||||
Command cmd = new Command("Get-VMDvdDrive");
|
||||
|
||||
cmd.Parameters.Add("VMName", vmName);
|
||||
|
||||
Collection<PSObject> result = powerShell.Execute(cmd, false);
|
||||
|
||||
if (result != null && result.Count > 0)
|
||||
{
|
||||
info.Id = result[0].GetString("Id");
|
||||
info.Name = result[0].GetString("Name");
|
||||
info.ControllerType = result[0].GetEnum<ControllerType>("ControllerType");
|
||||
info.ControllerNumber = result[0].GetInt("ControllerNumber");
|
||||
info.ControllerLocation = result[0].GetInt("ControllerLocation");
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
public static void Set(PowerShellManager powerShell, string vmName, string path)
|
||||
{
|
||||
var dvd = Get(powerShell, vmName);
|
||||
|
||||
Command cmd = new Command("Set-VMDvdDrive");
|
||||
|
||||
cmd.Parameters.Add("VMName", vmName);
|
||||
cmd.Parameters.Add("Path", path);
|
||||
cmd.Parameters.Add("ControllerNumber", dvd.ControllerNumber);
|
||||
cmd.Parameters.Add("ControllerLocation", dvd.ControllerLocation);
|
||||
|
||||
powerShell.Execute(cmd, false);
|
||||
}
|
||||
|
||||
public static void Update(PowerShellManager powerShell, VirtualMachine vm, bool dvdDriveShouldBeInstalled)
|
||||
{
|
||||
if (!vm.DvdDriveInstalled && dvdDriveShouldBeInstalled)
|
||||
Add(powerShell, vm.Name);
|
||||
else if (vm.DvdDriveInstalled && !dvdDriveShouldBeInstalled)
|
||||
Remove(powerShell, vm.Name);
|
||||
}
|
||||
|
||||
public static void Add(PowerShellManager powerShell, string vmName)
|
||||
{
|
||||
var dvd = Get(powerShell, vmName);
|
||||
|
||||
Command cmd = new Command("Add-VMDvdDrive");
|
||||
|
||||
cmd.Parameters.Add("VMName", vmName);
|
||||
cmd.Parameters.Add("ControllerNumber", dvd.ControllerNumber);
|
||||
cmd.Parameters.Add("ControllerLocation", dvd.ControllerLocation);
|
||||
|
||||
powerShell.Execute(cmd, false);
|
||||
}
|
||||
|
||||
public static void Remove(PowerShellManager powerShell, string vmName)
|
||||
{
|
||||
var dvd = Get(powerShell, vmName);
|
||||
|
||||
Command cmd = new Command("Remove-VMDvdDrive");
|
||||
|
||||
cmd.Parameters.Add("VMName", vmName);
|
||||
cmd.Parameters.Add("ControllerNumber", dvd.ControllerNumber);
|
||||
cmd.Parameters.Add("ControllerLocation", dvd.ControllerLocation);
|
||||
|
||||
powerShell.Execute(cmd, false);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,104 @@
|
|||
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 NetworkAdapterHelper
|
||||
{
|
||||
#region Constants
|
||||
|
||||
private const string EXTERNAL_NETWORK_ADAPTER_NAME = "External Network Adapter";
|
||||
private const string PRIVATE_NETWORK_ADAPTER_NAME = "Private Network Adapter";
|
||||
private const string MANAGEMENT_NETWORK_ADAPTER_NAME = "Management Network Adapter";
|
||||
|
||||
#endregion
|
||||
|
||||
public static VirtualMachineNetworkAdapter[] Get(PowerShellManager powerShell, string vmName)
|
||||
{
|
||||
List<VirtualMachineNetworkAdapter> adapters = new List<VirtualMachineNetworkAdapter>();
|
||||
|
||||
Command cmd = new Command("Get-VMNetworkAdapter");
|
||||
if (!string.IsNullOrEmpty(vmName)) cmd.Parameters.Add("VMName", vmName);
|
||||
|
||||
Collection<PSObject> result = powerShell.Execute(cmd, false);
|
||||
if (result != null && result.Count > 0)
|
||||
{
|
||||
foreach (PSObject psAdapter in result)
|
||||
{
|
||||
VirtualMachineNetworkAdapter adapter = new VirtualMachineNetworkAdapter();
|
||||
|
||||
adapter.Name = psAdapter.GetString("Name");
|
||||
adapter.MacAddress = psAdapter.GetString("MacAddress");
|
||||
adapter.SwitchName = psAdapter.GetString("SwitchName");
|
||||
|
||||
adapters.Add(adapter);
|
||||
}
|
||||
}
|
||||
return adapters.ToArray();
|
||||
}
|
||||
|
||||
public static VirtualMachineNetworkAdapter Get(PowerShellManager powerShell, string vmName, string macAddress)
|
||||
{
|
||||
var adapters = Get(powerShell, vmName);
|
||||
return adapters.FirstOrDefault(a => a.MacAddress == macAddress);
|
||||
}
|
||||
|
||||
public static void Update(PowerShellManager powerShell, VirtualMachine vm, string switchId, string portName, string macAddress, string adapterName, bool legacyAdapter)
|
||||
{
|
||||
// External NIC
|
||||
if (!vm.ExternalNetworkEnabled && !String.IsNullOrEmpty(vm.ExternalNicMacAddress))
|
||||
{
|
||||
// delete adapter
|
||||
Delete(powerShell, vm.Name, vm.ExternalNicMacAddress);
|
||||
vm.ExternalNicMacAddress = null; // reset MAC
|
||||
}
|
||||
else if (vm.ExternalNetworkEnabled && !String.IsNullOrEmpty(vm.ExternalNicMacAddress))
|
||||
{
|
||||
// add external adapter
|
||||
Add(powerShell, vm.Name, vm.ExternalSwitchId, vm.ExternalNicMacAddress, EXTERNAL_NETWORK_ADAPTER_NAME, vm.LegacyNetworkAdapter);
|
||||
}
|
||||
|
||||
// Private NIC
|
||||
if (!vm.PrivateNetworkEnabled && !String.IsNullOrEmpty(vm.PrivateNicMacAddress))
|
||||
{
|
||||
Delete(powerShell, vm.Name, vm.PrivateNicMacAddress);
|
||||
vm.PrivateNicMacAddress = null; // reset MAC
|
||||
}
|
||||
else if (vm.PrivateNetworkEnabled && !String.IsNullOrEmpty(vm.PrivateNicMacAddress))
|
||||
{
|
||||
Add(powerShell, vm.Name, vm.ExternalSwitchId, vm.ExternalNicMacAddress, PRIVATE_NETWORK_ADAPTER_NAME, vm.LegacyNetworkAdapter);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Add(PowerShellManager powerShell, string vmName, string switchId, string macAddress, string adapterName, bool legacyAdapter)
|
||||
{
|
||||
//var dvd = Get(powerShell, vmName);
|
||||
|
||||
//Command cmd = new Command("Add-VMDvdDrive");
|
||||
|
||||
//cmd.Parameters.Add("VMName", vmName);
|
||||
//cmd.Parameters.Add("ControllerNumber", dvd.ControllerNumber);
|
||||
//cmd.Parameters.Add("ControllerLocation", dvd.ControllerLocation);
|
||||
|
||||
//powerShell.Execute(cmd, false);
|
||||
}
|
||||
public static void Delete(PowerShellManager powerShell, string vmName, string macAddress)
|
||||
{
|
||||
//var dvd = Get(powerShell, vmName);
|
||||
|
||||
//Command cmd = new Command("Add-VMDvdDrive");
|
||||
|
||||
//cmd.Parameters.Add("VMName", vmName);
|
||||
//cmd.Parameters.Add("ControllerNumber", dvd.ControllerNumber);
|
||||
//cmd.Parameters.Add("ControllerLocation", dvd.ControllerLocation);
|
||||
|
||||
//powerShell.Execute(cmd, false);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,195 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
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 VirtualMachineHelper
|
||||
{
|
||||
#region Constants
|
||||
|
||||
private const Int64 Size1G = 0x40000000;
|
||||
private const Int64 Size1M = 0x100000;
|
||||
|
||||
#endregion
|
||||
|
||||
public static OperationalStatus GetVMHeartBeatStatus(PowerShellManager powerShell, string name)
|
||||
{
|
||||
|
||||
OperationalStatus status = OperationalStatus.None;
|
||||
|
||||
Command cmd = new Command("Get-VMIntegrationService");
|
||||
|
||||
cmd.Parameters.Add("VMName", name);
|
||||
cmd.Parameters.Add("Name", "HeartBeat");
|
||||
|
||||
Collection<PSObject> result = powerShell.Execute(cmd, false);
|
||||
if (result != null && result.Count > 0)
|
||||
{
|
||||
var statusString = result[0].GetProperty("PrimaryOperationalStatus");
|
||||
|
||||
if (statusString != null)
|
||||
status = (OperationalStatus)Enum.Parse(typeof(OperationalStatus), statusString.ToString());
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
public static int GetVMProcessors(PowerShellManager powerShell, string name)
|
||||
{
|
||||
|
||||
int procs = 0;
|
||||
|
||||
Command cmd = new Command("Get-VMProcessor");
|
||||
|
||||
cmd.Parameters.Add("VMName", name);
|
||||
|
||||
Collection<PSObject> result = powerShell.Execute(cmd, false);
|
||||
if (result != null && result.Count > 0)
|
||||
{
|
||||
procs = Convert.ToInt32(result[0].GetProperty("Count"));
|
||||
|
||||
}
|
||||
return procs;
|
||||
}
|
||||
|
||||
public static MemoryInfo GetVMMemory(PowerShellManager powerShell, string name)
|
||||
{
|
||||
MemoryInfo info = new MemoryInfo();
|
||||
|
||||
Command cmd = new Command("Get-VMMemory");
|
||||
|
||||
cmd.Parameters.Add("VMName", name);
|
||||
|
||||
Collection<PSObject> result = powerShell.Execute(cmd, false);
|
||||
if (result != null && result.Count > 0)
|
||||
{
|
||||
info.DynamicMemoryEnabled = Convert.ToBoolean(result[0].GetProperty("DynamicMemoryEnabled"));
|
||||
info.Startup = Convert.ToInt64(result[0].GetProperty("Startup"));
|
||||
info.Minimum = Convert.ToInt64(result[0].GetProperty("Minimum"));
|
||||
info.Maximum = Convert.ToInt64(result[0].GetProperty("Maximum"));
|
||||
info.Buffer = Convert.ToInt32(result[0].GetProperty("Buffer"));
|
||||
info.Priority = Convert.ToInt32(result[0].GetProperty("Priority"));
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
public static BiosInfo GetVMBios(PowerShellManager powerShell, string name)
|
||||
{
|
||||
BiosInfo info = new BiosInfo();
|
||||
|
||||
Command cmd = new Command("Get-VMBios");
|
||||
|
||||
cmd.Parameters.Add("VMName", name);
|
||||
|
||||
Collection<PSObject> result = powerShell.Execute(cmd, false);
|
||||
if (result != null && result.Count > 0)
|
||||
{
|
||||
info.NumLockEnabled = Convert.ToBoolean(result[0].GetProperty("NumLockEnabled"));
|
||||
|
||||
List<string> startupOrders = new List<string>();
|
||||
|
||||
foreach (var item in (IEnumerable)result[0].GetProperty("StartupOrder"))
|
||||
startupOrders.Add(item.ToString());
|
||||
|
||||
info.StartupOrder = startupOrders.ToArray();
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
public static VirtualHardDiskInfo[] GetVirtualHardDisks(PowerShellManager powerShell, string name)
|
||||
{
|
||||
|
||||
List<VirtualHardDiskInfo> disks = new List<VirtualHardDiskInfo>();
|
||||
|
||||
Command cmd = new Command("Get-VMHardDiskDrive");
|
||||
cmd.Parameters.Add("VMName", name);
|
||||
|
||||
Collection<PSObject> result = powerShell.Execute(cmd, false);
|
||||
if (result != null && result.Count > 0)
|
||||
{
|
||||
foreach (PSObject d in result)
|
||||
{
|
||||
VirtualHardDiskInfo disk = new VirtualHardDiskInfo();
|
||||
|
||||
disk.SupportPersistentReservations = Convert.ToBoolean(d.GetProperty("SupportPersistentReservations"));
|
||||
disk.MaximumIOPS = Convert.ToUInt64(d.GetProperty("MaximumIOPS"));
|
||||
disk.MinimumIOPS = Convert.ToUInt64(d.GetProperty("MinimumIOPS"));
|
||||
disk.VHDControllerType = d.GetEnum<ControllerType>("ControllerType");
|
||||
disk.ControllerNumber = Convert.ToInt32(d.GetProperty("ControllerNumber"));
|
||||
disk.ControllerLocation = Convert.ToInt32(d.GetProperty("ControllerLocation"));
|
||||
disk.Path = d.GetProperty("Path").ToString();
|
||||
disk.Name = d.GetProperty("Name").ToString();
|
||||
|
||||
GetVirtualHardDiskDetail(powerShell, disk.Path, ref disk);
|
||||
|
||||
disks.Add(disk);
|
||||
}
|
||||
}
|
||||
return disks.ToArray();
|
||||
}
|
||||
|
||||
public static void GetVirtualHardDiskDetail(PowerShellManager powerShell, string path, ref VirtualHardDiskInfo disk)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(path))
|
||||
{
|
||||
Command cmd = new Command("Get-VHD");
|
||||
cmd.Parameters.Add("Path", path);
|
||||
Collection<PSObject> result = powerShell.Execute(cmd, false);
|
||||
if (result != null && result.Count > 0)
|
||||
{
|
||||
disk.DiskFormat = result[0].GetEnum<VirtualHardDiskFormat>("VhdFormat");
|
||||
disk.DiskType = result[0].GetEnum<VirtualHardDiskType>("VhdType");
|
||||
disk.ParentPath = result[0].GetProperty<string>("ParentPath");
|
||||
disk.MaxInternalSize = Convert.ToInt64(result[0].GetProperty("Size")) / Size1G;
|
||||
disk.FileSize = Convert.ToInt64(result[0].GetProperty("FileSize")) / Size1G;
|
||||
disk.Attached = Convert.ToBoolean(result[0].GetProperty("Attached"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public static void UpdateBios(PowerShellManager powerShell, VirtualMachine vm, bool bootFromCD, bool numLockEnabled)
|
||||
{
|
||||
Command cmd = new Command("Set-VMBios");
|
||||
|
||||
cmd.Parameters.Add("VMName", vm.Name);
|
||||
cmd.Parameters.Add(numLockEnabled ? "EnableNumLock" : "DisableNumLock");
|
||||
var bootOrder = bootFromCD
|
||||
? new[] { "CD", "IDE", "LegacyNetworkAdapter", "Floppy" }
|
||||
: new[] { "IDE", "CD", "LegacyNetworkAdapter", "Floppy" };
|
||||
cmd.Parameters.Add("StartupOrder", bootOrder);
|
||||
|
||||
powerShell.Execute(cmd, false);
|
||||
}
|
||||
public static void UpdateProcessors(PowerShellManager powerShell, VirtualMachine vm, int cpuCores, int cpuLimitSettings, int cpuReserveSettings, int cpuWeightSettings)
|
||||
{
|
||||
Command cmd = new Command("Set-VMProcessor");
|
||||
|
||||
cmd.Parameters.Add("VMName", vm.Name);
|
||||
cmd.Parameters.Add("Count", cpuCores);
|
||||
cmd.Parameters.Add("Maximum", Convert.ToInt64(cpuLimitSettings * 1000));
|
||||
cmd.Parameters.Add("Reserve", Convert.ToInt64(cpuReserveSettings * 1000));
|
||||
cmd.Parameters.Add("RelativeWeight", cpuWeightSettings);
|
||||
|
||||
powerShell.Execute(cmd, false);
|
||||
}
|
||||
public static void UpdateMemory(PowerShellManager powerShell, VirtualMachine vm, long ramMB)
|
||||
{
|
||||
Command cmd = new Command("Set-VMMemory");
|
||||
|
||||
cmd.Parameters.Add("VMName", vm.Name);
|
||||
cmd.Parameters.Add("StartupBytes", ramMB);
|
||||
|
||||
powerShell.Execute(cmd, false);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -70,8 +70,6 @@ namespace WebsitePanel.Providers.Virtualization
|
|||
|
||||
private const string KVP_RAM_SUMMARY_KEY = "VM-RAM-Summary";
|
||||
private const string KVP_HDD_SUMMARY_KEY = "VM-HDD-Summary";
|
||||
private const Int64 Size1G = 0x40000000;
|
||||
private const Int64 Size1M = 0x100000;
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -141,49 +139,51 @@ namespace WebsitePanel.Providers.Virtualization
|
|||
|
||||
public VirtualMachine GetVirtualMachine(string vmId)
|
||||
{
|
||||
return GetVirtualMachineInternal( vmId, false);
|
||||
return GetVirtualMachineInternal(vmId, false);
|
||||
}
|
||||
|
||||
public VirtualMachine GetVirtualMachineInternal(string vmId, bool extendedInfo)
|
||||
public VirtualMachine GetVirtualMachineEx(string vmId)
|
||||
{
|
||||
return GetVirtualMachineInternal(vmId, true);
|
||||
}
|
||||
|
||||
protected VirtualMachine GetVirtualMachineInternal(string vmId, bool extendedInfo)
|
||||
{
|
||||
HostedSolutionLog.LogStart("GetVirtualMachine");
|
||||
HostedSolutionLog.DebugInfo("Virtual Machine: {0}", vmId);
|
||||
|
||||
Runspace runSpace = null;
|
||||
VirtualMachine vm = new VirtualMachine();
|
||||
|
||||
try
|
||||
{
|
||||
runSpace = OpenRunspace();
|
||||
Command cmd = new Command("Get-VM");
|
||||
|
||||
cmd.Parameters.Add("Id", vmId);
|
||||
|
||||
Collection<PSObject> result = ExecuteShellCommand(runSpace, cmd, false);
|
||||
|
||||
Collection<PSObject> result = PowerShell.Execute(cmd, false);
|
||||
if (result != null && result.Count > 0)
|
||||
{
|
||||
vm.Name = GetPSObjectProperty(result[0], "Name").ToString();
|
||||
vm.State = (VirtualMachineState)Enum.Parse(typeof(VirtualMachineState), GetPSObjectProperty(result[0], "State").ToString());
|
||||
vm.CpuUsage = ConvertNullableToInt32(GetPSObjectProperty(result[0], "CpuUsage"));
|
||||
vm.RamUsage = ConvertNullableToInt64(GetPSObjectProperty(result[0], "MemoryAssigned"));
|
||||
vm.Uptime = TimeSpan.Parse(GetPSObjectProperty(result[0], "Uptime").ToString()).Ticks;
|
||||
vm.Status = GetPSObjectProperty(result[0], "Status").ToString();
|
||||
vm.ReplicationState = GetPSObjectProperty(result[0], "ReplicationState").ToString();
|
||||
|
||||
vm.Heartbeat = GetVMHeartBeatStatus(runSpace, vm.Name);
|
||||
vm.Name = result[0].GetProperty("Name").ToString();
|
||||
vm.State = result[0].GetEnum<VirtualMachineState>("State");
|
||||
vm.CpuUsage = ConvertNullableToInt32(result[0].GetProperty("CpuUsage"));
|
||||
vm.RamUsage = ConvertNullableToInt64(result[0].GetProperty("MemoryAssigned"));
|
||||
vm.Uptime = Convert.ToInt64(result[0].GetProperty<TimeSpan>("UpTime").TotalMilliseconds);
|
||||
vm.Status = result[0].GetProperty("Status").ToString();
|
||||
vm.ReplicationState = result[0].GetProperty("ReplicationState").ToString();
|
||||
|
||||
vm.Heartbeat = VirtualMachineHelper.GetVMHeartBeatStatus(PowerShell, vm.Name);
|
||||
|
||||
vm.CreatedDate = DateTime.Now;
|
||||
|
||||
if (extendedInfo)
|
||||
{
|
||||
vm.CpuCores = GetVMProcessors(runSpace, vm.Name);
|
||||
vm.CpuCores = VirtualMachineHelper.GetVMProcessors(PowerShell, vm.Name);
|
||||
|
||||
MemoryInfo memoryInfo = GetVMMemory(runSpace, vm.Name);
|
||||
MemoryInfo memoryInfo = VirtualMachineHelper.GetVMMemory(PowerShell, vm.Name);
|
||||
vm.RamSize = memoryInfo.Startup;
|
||||
|
||||
// BIOS
|
||||
BiosInfo biosInfo = GetVMBios(runSpace, vm.Name);
|
||||
BiosInfo biosInfo = VirtualMachineHelper.GetVMBios(PowerShell, vm.Name);
|
||||
vm.NumLockEnabled = biosInfo.NumLockEnabled;
|
||||
|
||||
vm.BootFromCD = false;
|
||||
|
@ -191,27 +191,21 @@ namespace WebsitePanel.Providers.Virtualization
|
|||
vm.BootFromCD = (biosInfo.StartupOrder[0] == "CD");
|
||||
|
||||
// DVD drive
|
||||
cmd = new Command("Get-VMDvdDrive");
|
||||
cmd.Parameters.Add("VMName", vm.Name);
|
||||
|
||||
result = ExecuteShellCommand(runSpace, cmd, false);
|
||||
vm.DvdDriveInstalled = (result != null && result.Count > 0);
|
||||
var dvdInfo = DvdDriveHelper.Get(PowerShell, vm.Name);
|
||||
vm.DvdDriveInstalled = dvdInfo != null;
|
||||
|
||||
// HDD
|
||||
vm.Disks = GetVirtualHardDisks(runSpace, vm.Name);
|
||||
vm.Disks = VirtualMachineHelper.GetVirtualHardDisks(PowerShell, vm.Name);
|
||||
|
||||
if ((vm.Disks != null) & (vm.Disks.GetLength(0) > 0))
|
||||
if (vm.Disks != null && vm.Disks.GetLength(0) > 0)
|
||||
{
|
||||
vm.VirtualHardDrivePath = vm.Disks[0].Path;
|
||||
vm.HddSize = Convert.ToInt32(vm.Disks[0].FileSize);
|
||||
}
|
||||
|
||||
// network adapters
|
||||
vm.Adapters = GetNetworkAdapters(runSpace, vm.Name);
|
||||
return vm;
|
||||
|
||||
vm.Adapters = NetworkAdapterHelper.Get(PowerShell, vm.Name);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
@ -219,201 +213,30 @@ namespace WebsitePanel.Providers.Virtualization
|
|||
HostedSolutionLog.LogError("GetVirtualMachine", ex);
|
||||
throw;
|
||||
}
|
||||
finally
|
||||
{
|
||||
CloseRunspace(runSpace);
|
||||
}
|
||||
|
||||
HostedSolutionLog.LogEnd("GetVirtualMachine");
|
||||
return vm;
|
||||
|
||||
}
|
||||
|
||||
internal OperationalStatus GetVMHeartBeatStatus(Runspace runSpace, string name)
|
||||
{
|
||||
|
||||
OperationalStatus status = OperationalStatus.None;
|
||||
|
||||
Command cmd = new Command("Get-VMIntegrationService");
|
||||
|
||||
cmd.Parameters.Add("VMName", name);
|
||||
cmd.Parameters.Add("Name", "HeartBeat");
|
||||
|
||||
Collection<PSObject> result = ExecuteShellCommand(runSpace, cmd, false);
|
||||
if (result != null && result.Count > 0)
|
||||
{
|
||||
var statusString = GetPSObjectProperty(result[0], "PrimaryOperationalStatus");
|
||||
|
||||
if (statusString != null)
|
||||
status = (OperationalStatus)Enum.Parse(typeof(OperationalStatus), statusString.ToString());
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
public VirtualMachine GetVirtualMachineEx(string vmId)
|
||||
{
|
||||
return GetVirtualMachineInternal( vmId, true);
|
||||
}
|
||||
|
||||
|
||||
internal int GetVMProcessors(Runspace runSpace, string name)
|
||||
{
|
||||
|
||||
int procs = 0;
|
||||
|
||||
Command cmd = new Command("Get-VMProcessor");
|
||||
|
||||
cmd.Parameters.Add("VMName", name);
|
||||
|
||||
Collection<PSObject> result = ExecuteShellCommand(runSpace, cmd, false);
|
||||
if (result != null && result.Count > 0)
|
||||
{
|
||||
procs = Convert.ToInt32(GetPSObjectProperty(result[0], "Count"));
|
||||
|
||||
}
|
||||
return procs;
|
||||
}
|
||||
|
||||
internal MemoryInfo GetVMMemory(Runspace runSpace, string name)
|
||||
{
|
||||
MemoryInfo info = new MemoryInfo();
|
||||
|
||||
Command cmd = new Command("Get-VMMemory");
|
||||
|
||||
cmd.Parameters.Add("VMName", name);
|
||||
|
||||
Collection<PSObject> result = ExecuteShellCommand(runSpace, cmd, false);
|
||||
if (result != null && result.Count > 0)
|
||||
{
|
||||
info.DynamicMemoryEnabled = Convert.ToBoolean(GetPSObjectProperty(result[0], "DynamicMemoryEnabled"));
|
||||
info.Startup = Convert.ToInt64(GetPSObjectProperty(result[0], "Startup"));
|
||||
info.Minimum = Convert.ToInt64(GetPSObjectProperty(result[0], "Minimum"));
|
||||
info.Maximum = Convert.ToInt64(GetPSObjectProperty(result[0], "Maximum"));
|
||||
info.Buffer = Convert.ToInt32(GetPSObjectProperty(result[0], "Buffer"));
|
||||
info.Priority = Convert.ToInt32(GetPSObjectProperty(result[0], "Priority"));
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
internal BiosInfo GetVMBios(Runspace runSpace, string name)
|
||||
{
|
||||
BiosInfo info = new BiosInfo();
|
||||
|
||||
Command cmd = new Command("Get-VMBios");
|
||||
|
||||
cmd.Parameters.Add("VMName", name);
|
||||
|
||||
Collection<PSObject> result = ExecuteShellCommand(runSpace, cmd, false);
|
||||
if (result != null && result.Count > 0)
|
||||
{
|
||||
info.NumLockEnabled = Convert.ToBoolean(GetPSObjectProperty(result[0], "NumLockEnabled"));
|
||||
|
||||
List<string> startupOrders = new List<string>();
|
||||
|
||||
foreach (var item in (IEnumerable)GetPSObjectProperty(result[0], "StartupOrder"))
|
||||
startupOrders.Add(item.ToString());
|
||||
|
||||
info.StartupOrder = startupOrders.ToArray();
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
internal VirtualHardDiskInfo[] GetVirtualHardDisks(Runspace runSpace, string name)
|
||||
{
|
||||
|
||||
List<VirtualHardDiskInfo> disks = new List<VirtualHardDiskInfo>();
|
||||
|
||||
Command cmd = new Command("Get-VMHardDiskDrive");
|
||||
cmd.Parameters.Add("VMName", name);
|
||||
|
||||
Collection<PSObject> result = ExecuteShellCommand(runSpace, cmd, false);
|
||||
if (result != null && result.Count > 0)
|
||||
{
|
||||
foreach(PSObject d in result)
|
||||
{
|
||||
VirtualHardDiskInfo disk = new VirtualHardDiskInfo();
|
||||
|
||||
disk.SupportPersistentReservations = Convert.ToBoolean(GetPSObjectProperty(d, "SupportPersistentReservations"));
|
||||
disk.MaximumIOPS = Convert.ToUInt64(GetPSObjectProperty(d, "MaximumIOPS"));
|
||||
disk.MinimumIOPS = Convert.ToUInt64(GetPSObjectProperty(d, "MinimumIOPS"));
|
||||
disk.VHDControllerType = (ControllerType)Enum.Parse(typeof(ControllerType), GetPSObjectProperty(d, "ControllerType").ToString());
|
||||
disk.ControllerNumber = Convert.ToInt32(GetPSObjectProperty(d, "ControllerNumber"));
|
||||
disk.ControllerLocation = Convert.ToInt32(GetPSObjectProperty(d, "ControllerLocation"));
|
||||
disk.Path = GetPSObjectProperty(d, "Path").ToString();
|
||||
disk.Name = GetPSObjectProperty(d, "Name").ToString();
|
||||
|
||||
GetVirtualHardDiskDetail(runSpace, disk.Path, ref disk);
|
||||
|
||||
disks.Add(disk);
|
||||
}
|
||||
}
|
||||
return disks.ToArray();
|
||||
}
|
||||
|
||||
internal void GetVirtualHardDiskDetail(Runspace runSpace, string path, ref VirtualHardDiskInfo disk)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(path))
|
||||
{
|
||||
Command cmd = new Command("Get-VHD");
|
||||
cmd.Parameters.Add("Path", path);
|
||||
Collection<PSObject> result = ExecuteShellCommand(runSpace, cmd, false);
|
||||
if (result != null && result.Count > 0)
|
||||
{
|
||||
disk.DiskFormat = (VirtualHardDiskFormat)Enum.Parse(typeof(VirtualHardDiskFormat), GetPSObjectProperty(result[0], "VhdFormat").ToString());
|
||||
disk.DiskType = (VirtualHardDiskType)Enum.Parse(typeof(VirtualHardDiskType), GetPSObjectProperty(result[0], "VhdType").ToString());
|
||||
disk.ParentPath = (string)GetPSObjectProperty(result[0], "ParentPath");
|
||||
disk.MaxInternalSize = Convert.ToInt64(GetPSObjectProperty(result[0], "Size")) / Size1G;
|
||||
disk.FileSize = Convert.ToInt64(GetPSObjectProperty(result[0], "FileSize")) / Size1G;
|
||||
disk.Attached = Convert.ToBoolean(GetPSObjectProperty(result[0], "Attached"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
internal VirtualMachineNetworkAdapter[] GetNetworkAdapters(Runspace runSpace, string name)
|
||||
{
|
||||
List<VirtualMachineNetworkAdapter> adapters = new List<VirtualMachineNetworkAdapter>();
|
||||
|
||||
Command cmd = new Command("Get-VMNetworkAdapter");
|
||||
cmd.Parameters.Add("VMName", name);
|
||||
|
||||
Collection<PSObject> result = ExecuteShellCommand(runSpace, cmd, false);
|
||||
if (result != null && result.Count > 0)
|
||||
{
|
||||
foreach(PSObject a in result)
|
||||
{
|
||||
VirtualMachineNetworkAdapter adapter = new VirtualMachineNetworkAdapter();
|
||||
|
||||
adapter.Name = GetPSObjectProperty(a, "Name").ToString();
|
||||
adapter.MacAddress = GetPSObjectProperty(a, "MacAddress").ToString();
|
||||
|
||||
adapters.Add(adapter);
|
||||
}
|
||||
}
|
||||
return adapters.ToArray();
|
||||
}
|
||||
|
||||
public List<VirtualMachine> GetVirtualMachines()
|
||||
{
|
||||
HostedSolutionLog.LogStart("GetVirtualMachines");
|
||||
|
||||
Runspace runSpace = null;
|
||||
List<VirtualMachine> vmachines = new List<VirtualMachine>();
|
||||
|
||||
try
|
||||
{
|
||||
runSpace = OpenRunspace();
|
||||
Command cmd = new Command("Get-VM");
|
||||
|
||||
Collection<PSObject> result = ExecuteShellCommand(runSpace, cmd, false);
|
||||
Collection<PSObject> result = PowerShell.Execute(cmd, false);
|
||||
foreach (PSObject current in result)
|
||||
{
|
||||
VirtualMachine vm = new VirtualMachine
|
||||
{
|
||||
VirtualMachineId = GetPSObjectProperty(current, "Id").ToString(),
|
||||
Name = GetPSObjectProperty(current, "Name").ToString(),
|
||||
State = (VirtualMachineState)Enum.Parse(typeof(VirtualMachineState), GetPSObjectProperty(current, "State").ToString()),
|
||||
Uptime = GetPSObjectProperty<TimeSpan>(current, "UpTime").Ticks
|
||||
VirtualMachineId = current.GetProperty("Id").ToString(),
|
||||
Name = current.GetProperty("Name").ToString(),
|
||||
State = (VirtualMachineState)Enum.Parse(typeof(VirtualMachineState), current.GetProperty("State").ToString()),
|
||||
Uptime = Convert.ToInt64(current.GetProperty<TimeSpan>("UpTime").TotalMilliseconds)
|
||||
};
|
||||
vmachines.Add(vm);
|
||||
}
|
||||
|
@ -423,10 +246,6 @@ namespace WebsitePanel.Providers.Virtualization
|
|||
HostedSolutionLog.LogError("GetVirtualMachines", ex);
|
||||
throw;
|
||||
}
|
||||
finally
|
||||
{
|
||||
CloseRunspace(runSpace);
|
||||
}
|
||||
|
||||
HostedSolutionLog.LogEnd("GetVirtualMachines");
|
||||
return vmachines;
|
||||
|
@ -549,11 +368,11 @@ namespace WebsitePanel.Providers.Virtualization
|
|||
vmID = (string)objVM["Name"];
|
||||
|
||||
// update general settings
|
||||
UpdateVirtualMachineGeneralSettings(vmID, objVM,
|
||||
vm.CpuCores,
|
||||
vm.RamSize,
|
||||
vm.BootFromCD,
|
||||
vm.NumLockEnabled);
|
||||
//UpdateVirtualMachineGeneralSettings(vmID, objVM,
|
||||
// vm.CpuCores,
|
||||
// vm.RamSize,
|
||||
// vm.BootFromCD,
|
||||
// vm.NumLockEnabled);
|
||||
|
||||
// hard disks
|
||||
// load IDE 0 controller
|
||||
|
@ -608,113 +427,32 @@ namespace WebsitePanel.Providers.Virtualization
|
|||
|
||||
public VirtualMachine UpdateVirtualMachine(VirtualMachine vm)
|
||||
{
|
||||
string vmId = vm.VirtualMachineId;
|
||||
HostedSolutionLog.LogStart("UpdateVirtualMachine");
|
||||
HostedSolutionLog.DebugInfo("Virtual Machine: {0}", vm.VirtualMachineId);
|
||||
|
||||
// get VM object
|
||||
ManagementObject objVM = GetVirtualMachineObject(vmId);
|
||||
Runspace runSpace = null;
|
||||
|
||||
// update general settings
|
||||
UpdateVirtualMachineGeneralSettings(vmId, objVM,
|
||||
vm.CpuCores,
|
||||
vm.RamSize,
|
||||
vm.BootFromCD,
|
||||
vm.NumLockEnabled);
|
||||
|
||||
// check DVD drive
|
||||
ManagementObject objDvdDrive = wmi.GetWmiObject(
|
||||
"Msvm_ResourceAllocationSettingData", "ResourceSubType = 'Microsoft Synthetic DVD Drive'"
|
||||
+ " and InstanceID like 'Microsoft:{0}%' and Address = 0", vmId);
|
||||
|
||||
if (vm.DvdDriveInstalled && objDvdDrive == null)
|
||||
AddVirtualMachineDvdDrive(vmId, objVM);
|
||||
else if (!vm.DvdDriveInstalled && objDvdDrive != null)
|
||||
RemoveVirtualMachineResources(objVM, objDvdDrive);
|
||||
|
||||
// External NIC
|
||||
if (!vm.ExternalNetworkEnabled
|
||||
&& !String.IsNullOrEmpty(vm.ExternalNicMacAddress))
|
||||
try
|
||||
{
|
||||
// delete adapter
|
||||
DeleteNetworkAdapter(objVM, vm.ExternalNicMacAddress);
|
||||
var realVm = GetVirtualMachine(vm.VirtualMachineId);
|
||||
|
||||
VirtualMachineHelper.UpdateBios(PowerShell, realVm, vm.BootFromCD, vm.NumLockEnabled);
|
||||
VirtualMachineHelper.UpdateProcessors(PowerShell, realVm, vm.CpuCores, CpuLimitSettings, CpuReserveSettings, CpuWeightSettings);
|
||||
VirtualMachineHelper.UpdateMemory(PowerShell, realVm, vm.RamSize);
|
||||
DvdDriveHelper.Update(PowerShell, realVm, vm.DvdDriveInstalled);
|
||||
|
||||
// reset MAC
|
||||
vm.ExternalNicMacAddress = null;
|
||||
}
|
||||
else if (vm.ExternalNetworkEnabled
|
||||
&& !String.IsNullOrEmpty(vm.ExternalNicMacAddress))
|
||||
catch (Exception ex)
|
||||
{
|
||||
// add external adapter
|
||||
AddNetworkAdapter(objVM, vm.ExternalSwitchId, vm.Name, vm.ExternalNicMacAddress, EXTERNAL_NETWORK_ADAPTER_NAME, vm.LegacyNetworkAdapter);
|
||||
}
|
||||
|
||||
|
||||
// Private NIC
|
||||
if (!vm.PrivateNetworkEnabled
|
||||
&& !String.IsNullOrEmpty(vm.PrivateNicMacAddress))
|
||||
{
|
||||
// delete adapter
|
||||
DeleteNetworkAdapter(objVM, vm.PrivateNicMacAddress);
|
||||
|
||||
// reset MAC
|
||||
vm.PrivateNicMacAddress = null;
|
||||
}
|
||||
else if (vm.PrivateNetworkEnabled
|
||||
&& !String.IsNullOrEmpty(vm.PrivateNicMacAddress))
|
||||
{
|
||||
// add private adapter
|
||||
AddNetworkAdapter(objVM, vm.PrivateSwitchId, vm.Name, vm.PrivateNicMacAddress, PRIVATE_NETWORK_ADAPTER_NAME, vm.LegacyNetworkAdapter);
|
||||
HostedSolutionLog.LogError("UpdateVirtualMachine", ex);
|
||||
throw;
|
||||
}
|
||||
|
||||
HostedSolutionLog.LogEnd("UpdateVirtualMachine");
|
||||
|
||||
return vm;
|
||||
}
|
||||
|
||||
private void UpdateVirtualMachineGeneralSettings(string vmId, ManagementObject objVM, int cpuCores, long ramMB, bool bootFromCD, bool numLockEnabled)
|
||||
{
|
||||
// request management service
|
||||
ManagementObject objVmsvc = GetVirtualSystemManagementService();
|
||||
|
||||
// VM resources
|
||||
List<string> vmConfig = new List<string>();
|
||||
|
||||
// get system settings
|
||||
ManagementObject objSettings = GetVirtualMachineSettingsObject(vmId);
|
||||
|
||||
// BIOS (num lock)
|
||||
objSettings["BIOSNumLock"] = numLockEnabled;
|
||||
|
||||
// BIOS (boot order)
|
||||
// BootOrder = 0 - Boot from floppy, 1 - Boot from CD, 2 - Boot from disk, 3 - PXE Boot
|
||||
objSettings["BootOrder"] = bootFromCD ? new int[] { 1, 2, 3, 0 } : new int[] { 2, 1, 3, 0 };
|
||||
|
||||
// modify machine settings
|
||||
ManagementBaseObject inParams = objVmsvc.GetMethodParameters("ModifyVirtualSystem");
|
||||
inParams["ComputerSystem"] = objVM;
|
||||
inParams["SystemSettingData"] = objSettings.GetText(TextFormat.CimDtd20);
|
||||
ManagementBaseObject outParams = objVmsvc.InvokeMethod("ModifyVirtualSystem", inParams, null);
|
||||
JobResult job = CreateJobResultFromWmiMethodResults(outParams);
|
||||
|
||||
// setup CPU
|
||||
ManagementObject objCpu = wmi.GetWmiObject("Msvm_ProcessorSettingData", "InstanceID Like 'Microsoft:{0}%'", vmId);
|
||||
objCpu["VirtualQuantity"] = cpuCores;
|
||||
objCpu["Limit"] = Convert.ToInt64(CpuLimitSettings * 1000);
|
||||
objCpu["Reservation"] = Convert.ToInt64(CpuReserveSettings * 1000);
|
||||
objCpu["Weight"] = CpuWeightSettings;
|
||||
vmConfig.Add(objCpu.GetText(TextFormat.CimDtd20));
|
||||
|
||||
// setup RAM
|
||||
ManagementObject objRam = wmi.GetWmiObject("Msvm_MemorySettingData", "InstanceID Like 'Microsoft:{0}%'", vmId);
|
||||
objRam["VirtualQuantity"] = ramMB.ToString();
|
||||
objRam["Reservation"] = ramMB.ToString();
|
||||
objRam["Limit"] = ramMB.ToString();
|
||||
vmConfig.Add(objRam.GetText(TextFormat.CimDtd20));
|
||||
|
||||
// modify machine resources
|
||||
inParams = objVmsvc.GetMethodParameters("ModifyVirtualSystemResources");
|
||||
inParams["ComputerSystem"] = objVM;
|
||||
inParams["ResourceSettingData"] = vmConfig.ToArray();
|
||||
outParams = objVmsvc.InvokeMethod("ModifyVirtualSystemResources", inParams, null);
|
||||
job = CreateJobResultFromWmiMethodResults(outParams);
|
||||
}
|
||||
|
||||
private void AddVirtualMachineDvdDrive(string vmId, ManagementObject objVM)
|
||||
{
|
||||
|
@ -883,12 +621,9 @@ namespace WebsitePanel.Providers.Virtualization
|
|||
var jobResult = new JobResult();
|
||||
|
||||
var vm = GetVirtualMachine(vmId);
|
||||
Runspace runSpace = null;
|
||||
|
||||
try
|
||||
{
|
||||
runSpace = OpenRunspace();
|
||||
|
||||
string cmdTxt;
|
||||
List<string> paramList = new List<string>();
|
||||
|
||||
|
@ -926,7 +661,7 @@ namespace WebsitePanel.Providers.Virtualization
|
|||
//cmd.Parameters.Add("AsJob");
|
||||
paramList.ForEach(p => cmd.Parameters.Add(p));
|
||||
|
||||
ExecuteShellCommand(runSpace, cmd, false);
|
||||
PowerShell.Execute(cmd, false);
|
||||
jobResult = CreateSuccessJobResult();
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
@ -934,10 +669,6 @@ namespace WebsitePanel.Providers.Virtualization
|
|||
HostedSolutionLog.LogError("ChangeVirtualMachineState", ex);
|
||||
throw;
|
||||
}
|
||||
finally
|
||||
{
|
||||
CloseRunspace(runSpace);
|
||||
}
|
||||
|
||||
HostedSolutionLog.LogEnd("ChangeVirtualMachineState");
|
||||
|
||||
|
@ -950,28 +681,22 @@ namespace WebsitePanel.Providers.Virtualization
|
|||
ReturnCode returnCode = ReturnCode.OK;
|
||||
|
||||
var vm = GetVirtualMachine(vmId);
|
||||
Runspace runSpace = null;
|
||||
|
||||
try
|
||||
{
|
||||
runSpace = OpenRunspace();
|
||||
|
||||
Command cmd = new Command("Stop-VM");
|
||||
|
||||
cmd.Parameters.Add("Name", vm.Name);
|
||||
if (force) cmd.Parameters.Add("Force");
|
||||
//if (!string.IsNullOrEmpty(reason)) cmd.Parameters.Add("Reason", reason);
|
||||
|
||||
ExecuteShellCommand(runSpace, cmd, false);
|
||||
PowerShell.Execute(cmd, false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HostedSolutionLog.LogError("ShutDownVirtualMachine", ex);
|
||||
throw;
|
||||
}
|
||||
finally
|
||||
{
|
||||
CloseRunspace(runSpace);
|
||||
}
|
||||
|
||||
HostedSolutionLog.LogEnd("ShutDownVirtualMachine");
|
||||
|
||||
|
@ -1351,19 +1076,19 @@ namespace WebsitePanel.Providers.Virtualization
|
|||
|
||||
try
|
||||
{
|
||||
runSpace = OpenRunspace();
|
||||
|
||||
Command cmd = new Command("Get-VMSwitch");
|
||||
|
||||
if (!string.IsNullOrEmpty(computerName)) cmd.Parameters.Add("ComputerName", computerName);
|
||||
if (!string.IsNullOrEmpty(type)) cmd.Parameters.Add("SwitchType", type);
|
||||
|
||||
Collection<PSObject> result = ExecuteShellCommand(runSpace, cmd,false);
|
||||
Collection<PSObject> result = PowerShell.Execute(cmd,false);
|
||||
foreach (PSObject current in result)
|
||||
{
|
||||
VirtualSwitch sw = new VirtualSwitch();
|
||||
sw.SwitchId = GetPSObjectProperty(current, "Name").ToString();
|
||||
sw.Name = GetPSObjectProperty(current, "Name").ToString();
|
||||
sw.SwitchType = GetPSObjectProperty(current, "SwitchType").ToString();
|
||||
sw.SwitchId = current.GetProperty("Name").ToString();
|
||||
sw.Name = current.GetProperty("Name").ToString();
|
||||
sw.SwitchType = current.GetProperty("SwitchType").ToString();
|
||||
switches.Add(sw);
|
||||
}
|
||||
}
|
||||
|
@ -1372,10 +1097,6 @@ namespace WebsitePanel.Providers.Virtualization
|
|||
HostedSolutionLog.LogError("GetSwitches", ex);
|
||||
throw;
|
||||
}
|
||||
finally
|
||||
{
|
||||
CloseRunspace(runSpace);
|
||||
}
|
||||
|
||||
HostedSolutionLog.LogEnd("GetSwitches");
|
||||
return switches;
|
||||
|
@ -2100,12 +1821,12 @@ exit", Convert.ToInt32(objDisk["Index"])));
|
|||
|
||||
try
|
||||
{
|
||||
runSpace = OpenRunspace();
|
||||
|
||||
Command cmd = new Command("Get-Job");
|
||||
|
||||
if (!string.IsNullOrEmpty(jobId)) cmd.Parameters.Add("Id", jobId);
|
||||
|
||||
Collection<PSObject> result = ExecuteShellCommand(runSpace, cmd, false);
|
||||
Collection<PSObject> result = PowerShell.Execute( cmd, false);
|
||||
job = CreateJobFromPSObject(result);
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
@ -2113,10 +1834,6 @@ exit", Convert.ToInt32(objDisk["Index"])));
|
|||
HostedSolutionLog.LogError("GetJob", ex);
|
||||
throw;
|
||||
}
|
||||
finally
|
||||
{
|
||||
CloseRunspace(runSpace);
|
||||
}
|
||||
|
||||
HostedSolutionLog.LogEnd("GetJob");
|
||||
return job;
|
||||
|
@ -2503,21 +2220,21 @@ exit", Convert.ToInt32(objDisk["Index"])));
|
|||
return null;
|
||||
|
||||
ConcreteJob job = new ConcreteJob();
|
||||
job.Id = GetPSObjectProperty<int>(objJob[0], "Id").ToString();
|
||||
job.JobState = GetPSObjectPropertyEnum<ConcreteJobState>(objJob[0], "JobStateInfo");
|
||||
job.Caption = GetPSObjectProperty<string>(objJob[0], "Name");
|
||||
job.Description = GetPSObjectProperty<string>(objJob[0], "Command");
|
||||
job.StartTime = GetPSObjectProperty<DateTime>(objJob[0], "PSBeginTime");
|
||||
job.ElapsedTime = GetPSObjectProperty<DateTime?>(objJob[0], "PSEndTime") ?? DateTime.Now;
|
||||
job.Id = objJob[0].GetProperty<int>("Id").ToString();
|
||||
job.JobState = objJob[0].GetEnum<ConcreteJobState>("JobStateInfo");
|
||||
job.Caption = objJob[0].GetProperty<string>("Name");
|
||||
job.Description = objJob[0].GetProperty<string>("Command");
|
||||
job.StartTime = objJob[0].GetProperty<DateTime>("PSBeginTime");
|
||||
job.ElapsedTime = objJob[0].GetProperty<DateTime?>("PSEndTime") ?? DateTime.Now;
|
||||
|
||||
// PercentComplete
|
||||
job.PercentComplete = 0;
|
||||
var progress = (PSDataCollection<ProgressRecord>)GetPSObjectProperty(objJob[0], "Progress");
|
||||
var progress = (PSDataCollection<ProgressRecord>)objJob[0].GetProperty("Progress");
|
||||
if (progress != null && progress.Count > 0)
|
||||
job.PercentComplete = progress[0].PercentComplete;
|
||||
|
||||
// Errors
|
||||
var errors = (PSDataCollection<ErrorRecord>)GetPSObjectProperty(objJob[0], "Error");
|
||||
var errors = (PSDataCollection<ErrorRecord>)objJob[0].GetProperty("Error");
|
||||
if (errors != null && errors.Count > 0)
|
||||
{
|
||||
job.ErrorDescription = errors[0].ErrorDetails.Message + ". " + errors[0].ErrorDetails.RecommendedAction;
|
||||
|
@ -2813,152 +2530,13 @@ exit", Convert.ToInt32(objDisk["Index"])));
|
|||
#endregion Hyper-V Cloud
|
||||
|
||||
#region PowerShell integration
|
||||
private static InitialSessionState session = null;
|
||||
|
||||
internal virtual Runspace OpenRunspace()
|
||||
private PowerShellManager _powerShell;
|
||||
protected PowerShellManager PowerShell
|
||||
{
|
||||
HostedSolutionLog.LogStart("OpenRunspace");
|
||||
|
||||
if (session == null)
|
||||
{
|
||||
session = InitialSessionState.CreateDefault();
|
||||
session.ImportPSModule(new string[] { "Hyper-V" });
|
||||
}
|
||||
Runspace runSpace = RunspaceFactory.CreateRunspace(session);
|
||||
//
|
||||
runSpace.Open();
|
||||
//
|
||||
runSpace.SessionStateProxy.SetVariable("ConfirmPreference", "none");
|
||||
HostedSolutionLog.LogEnd("OpenRunspace");
|
||||
return runSpace;
|
||||
get { return _powerShell ?? (_powerShell = new PowerShellManager()); }
|
||||
}
|
||||
|
||||
internal void CloseRunspace(Runspace runspace)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (runspace != null && runspace.RunspaceStateInfo.State == RunspaceState.Opened)
|
||||
{
|
||||
runspace.Close();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HostedSolutionLog.LogError("Runspace error", ex);
|
||||
}
|
||||
}
|
||||
|
||||
internal Collection<PSObject> ExecuteShellCommand(Runspace runSpace, Command cmd)
|
||||
{
|
||||
return ExecuteShellCommand(runSpace, cmd, true);
|
||||
}
|
||||
|
||||
internal Collection<PSObject> ExecuteShellCommand(Runspace runSpace, Command cmd, bool useDomainController)
|
||||
{
|
||||
object[] errors;
|
||||
return ExecuteShellCommand(runSpace, cmd, useDomainController, out errors);
|
||||
}
|
||||
|
||||
internal Collection<PSObject> ExecuteShellCommand(Runspace runSpace, Command cmd, out object[] errors)
|
||||
{
|
||||
return ExecuteShellCommand(runSpace, cmd, true, out errors);
|
||||
}
|
||||
|
||||
internal Collection<PSObject> ExecuteShellCommand(Runspace runSpace, Command cmd, bool useDomainController, out object[] errors)
|
||||
{
|
||||
HostedSolutionLog.LogStart("ExecuteShellCommand");
|
||||
List<object> errorList = new List<object>();
|
||||
|
||||
HostedSolutionLog.DebugCommand(cmd);
|
||||
Collection<PSObject> results = null;
|
||||
// Create a pipeline
|
||||
Pipeline pipeLine = runSpace.CreatePipeline();
|
||||
using (pipeLine)
|
||||
{
|
||||
// Add the command
|
||||
pipeLine.Commands.Add(cmd);
|
||||
// Execute the pipeline and save the objects returned.
|
||||
results = pipeLine.Invoke();
|
||||
|
||||
// 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
|
||||
// happened while executing the command.
|
||||
if (pipeLine.Error != null && pipeLine.Error.Count > 0)
|
||||
{
|
||||
foreach (object item in pipeLine.Error.ReadToEnd())
|
||||
{
|
||||
errorList.Add(item);
|
||||
string errorMessage = string.Format("Invoke error: {0}", item);
|
||||
HostedSolutionLog.LogWarning(errorMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
pipeLine = null;
|
||||
errors = errorList.ToArray();
|
||||
HostedSolutionLog.LogEnd("ExecuteShellCommand");
|
||||
return results;
|
||||
}
|
||||
|
||||
internal object GetPSObjectProperty(PSObject obj, string name)
|
||||
{
|
||||
return obj.Members[name].Value;
|
||||
}
|
||||
internal T GetPSObjectProperty<T>(PSObject obj, string name)
|
||||
{
|
||||
return (T)obj.Members[name].Value;
|
||||
}
|
||||
internal T GetPSObjectPropertyEnum<T>(PSObject obj, string name) where T : struct
|
||||
{
|
||||
return (T) Enum.Parse(typeof (T), GetPSObjectProperty(obj, name).ToString());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the identity of the object from the shell execution result
|
||||
/// </summary>
|
||||
/// <param name="result"></param>
|
||||
/// <returns></returns>
|
||||
internal string GetResultObjectIdentity(Collection<PSObject> result)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
internal string GetResultObjectDN(Collection<PSObject> 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;
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,159 @@
|
|||
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;
|
||||
using WebsitePanel.Providers.HostedSolution;
|
||||
|
||||
namespace WebsitePanel.Providers.Virtualization
|
||||
{
|
||||
public class PowerShellManager : IDisposable
|
||||
{
|
||||
protected static InitialSessionState session = null;
|
||||
|
||||
protected Runspace RunSpace { get; set; }
|
||||
|
||||
public PowerShellManager()
|
||||
{
|
||||
OpenRunspace();
|
||||
}
|
||||
|
||||
protected void OpenRunspace()
|
||||
{
|
||||
HostedSolutionLog.LogStart("OpenRunspace");
|
||||
|
||||
if (session == null)
|
||||
{
|
||||
session = InitialSessionState.CreateDefault();
|
||||
session.ImportPSModule(new[] {"Hyper-V"});
|
||||
}
|
||||
|
||||
Runspace runSpace = RunspaceFactory.CreateRunspace(session);
|
||||
runSpace.Open();
|
||||
runSpace.SessionStateProxy.SetVariable("ConfirmPreference", "none");
|
||||
|
||||
RunSpace = runSpace;
|
||||
|
||||
HostedSolutionLog.LogEnd("OpenRunspace");
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (RunSpace != null && RunSpace.RunspaceStateInfo.State == RunspaceState.Opened)
|
||||
{
|
||||
RunSpace.Close();
|
||||
RunSpace = null;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HostedSolutionLog.LogError("Runspace error", ex);
|
||||
}
|
||||
}
|
||||
|
||||
public Collection<PSObject> Execute(Command cmd)
|
||||
{
|
||||
return Execute(cmd, true);
|
||||
}
|
||||
|
||||
public Collection<PSObject> Execute(Command cmd, bool useDomainController)
|
||||
{
|
||||
object[] errors;
|
||||
return Execute(cmd, useDomainController, out errors);
|
||||
}
|
||||
|
||||
public Collection<PSObject> Execute(Command cmd, out object[] errors)
|
||||
{
|
||||
return Execute(cmd, true, out errors);
|
||||
}
|
||||
|
||||
public Collection<PSObject> Execute(Command cmd, bool useDomainController, out object[] errors)
|
||||
{
|
||||
HostedSolutionLog.LogStart("Execute");
|
||||
List<object> errorList = new List<object>();
|
||||
|
||||
HostedSolutionLog.DebugCommand(cmd);
|
||||
Collection<PSObject> results = null;
|
||||
// Create a pipeline
|
||||
Pipeline pipeLine = RunSpace.CreatePipeline();
|
||||
using (pipeLine)
|
||||
{
|
||||
// Add the command
|
||||
pipeLine.Commands.Add(cmd);
|
||||
// Execute the pipeline and save the objects returned.
|
||||
results = pipeLine.Invoke();
|
||||
|
||||
// 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
|
||||
// happened while executing the command.
|
||||
if (pipeLine.Error != null && pipeLine.Error.Count > 0)
|
||||
{
|
||||
foreach (object item in pipeLine.Error.ReadToEnd())
|
||||
{
|
||||
errorList.Add(item);
|
||||
string errorMessage = string.Format("Invoke error: {0}", item);
|
||||
HostedSolutionLog.LogWarning(errorMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
pipeLine = null;
|
||||
errors = errorList.ToArray();
|
||||
HostedSolutionLog.LogEnd("Execute");
|
||||
return results;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns the identity of the object from the shell execution result
|
||||
/// </summary>
|
||||
/// <param name="result"></param>
|
||||
/// <returns></returns>
|
||||
public static string GetResultObjectIdentity(Collection<PSObject> result)
|
||||
{
|
||||
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<PSObject> 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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -53,8 +53,13 @@
|
|||
<Compile Include="..\VersionInfo.cs">
|
||||
<Link>VersionInfo.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="Extensions\PSObjectExtension.cs" />
|
||||
<Compile Include="Helpers\NetworkAdapterHelper.cs" />
|
||||
<Compile Include="Helpers\DvdDriveHelper.cs" />
|
||||
<Compile Include="PowerShellManager.cs" />
|
||||
<Compile Include="HyperV2012R2.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Helpers\VirtualMachineHelper.cs" />
|
||||
<Compile Include="Wmi.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue