wsp-10323 Convert the VSP provider into one utilizing PowerShell. Step 2

This commit is contained in:
AlexanderTr 2015-03-06 15:03:07 +03:00
parent a96931786c
commit 5b09a543f8
10 changed files with 699 additions and 493 deletions

View file

@ -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; }
}
}

View file

@ -36,5 +36,6 @@ namespace WebsitePanel.Providers.Virtualization
{ {
public string Name { get; set; } public string Name { get; set; }
public string MacAddress { get; set; } public string MacAddress { get; set; }
public string SwitchName { get; set; }
} }
} }

View file

@ -309,6 +309,7 @@
<Compile Include="Virtualization\KvpExchangeDataItem.cs" /> <Compile Include="Virtualization\KvpExchangeDataItem.cs" />
<Compile Include="Virtualization\LibraryItem.cs" /> <Compile Include="Virtualization\LibraryItem.cs" />
<Compile Include="Virtualization\LogicalDisk.cs" /> <Compile Include="Virtualization\LogicalDisk.cs" />
<Compile Include="Virtualization\DvdDriveInfo.cs" />
<Compile Include="Virtualization\MemoryInfo.cs" /> <Compile Include="Virtualization\MemoryInfo.cs" />
<Compile Include="Virtualization\MonitoredObjectAlert.cs" /> <Compile Include="Virtualization\MonitoredObjectAlert.cs" />
<Compile Include="Virtualization\MonitoredObjectEvent.cs" /> <Compile Include="Virtualization\MonitoredObjectEvent.cs" />

View file

@ -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();
}
}
}

View file

@ -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);
}
}
}

View file

@ -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);
}
}
}

View file

@ -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);
}
}
}

View file

@ -70,8 +70,6 @@ namespace WebsitePanel.Providers.Virtualization
private const string KVP_RAM_SUMMARY_KEY = "VM-RAM-Summary"; private const string KVP_RAM_SUMMARY_KEY = "VM-RAM-Summary";
private const string KVP_HDD_SUMMARY_KEY = "VM-HDD-Summary"; private const string KVP_HDD_SUMMARY_KEY = "VM-HDD-Summary";
private const Int64 Size1G = 0x40000000;
private const Int64 Size1M = 0x100000;
#endregion #endregion
@ -144,46 +142,48 @@ namespace WebsitePanel.Providers.Virtualization
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.LogStart("GetVirtualMachine");
HostedSolutionLog.DebugInfo("Virtual Machine: {0}", vmId); HostedSolutionLog.DebugInfo("Virtual Machine: {0}", vmId);
Runspace runSpace = null;
VirtualMachine vm = new VirtualMachine(); VirtualMachine vm = new VirtualMachine();
try try
{ {
runSpace = OpenRunspace();
Command cmd = new Command("Get-VM"); Command cmd = new Command("Get-VM");
cmd.Parameters.Add("Id", vmId); 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) if (result != null && result.Count > 0)
{ {
vm.Name = GetPSObjectProperty(result[0], "Name").ToString(); vm.Name = result[0].GetProperty("Name").ToString();
vm.State = (VirtualMachineState)Enum.Parse(typeof(VirtualMachineState), GetPSObjectProperty(result[0], "State").ToString()); vm.State = result[0].GetEnum<VirtualMachineState>("State");
vm.CpuUsage = ConvertNullableToInt32(GetPSObjectProperty(result[0], "CpuUsage")); vm.CpuUsage = ConvertNullableToInt32(result[0].GetProperty("CpuUsage"));
vm.RamUsage = ConvertNullableToInt64(GetPSObjectProperty(result[0], "MemoryAssigned")); vm.RamUsage = ConvertNullableToInt64(result[0].GetProperty("MemoryAssigned"));
vm.Uptime = TimeSpan.Parse(GetPSObjectProperty(result[0], "Uptime").ToString()).Ticks; vm.Uptime = Convert.ToInt64(result[0].GetProperty<TimeSpan>("UpTime").TotalMilliseconds);
vm.Status = GetPSObjectProperty(result[0], "Status").ToString(); vm.Status = result[0].GetProperty("Status").ToString();
vm.ReplicationState = GetPSObjectProperty(result[0], "ReplicationState").ToString(); vm.ReplicationState = result[0].GetProperty("ReplicationState").ToString();
vm.Heartbeat = GetVMHeartBeatStatus(runSpace, vm.Name); vm.Heartbeat = VirtualMachineHelper.GetVMHeartBeatStatus(PowerShell, vm.Name);
vm.CreatedDate = DateTime.Now; vm.CreatedDate = DateTime.Now;
if (extendedInfo) 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; vm.RamSize = memoryInfo.Startup;
// BIOS // BIOS
BiosInfo biosInfo = GetVMBios(runSpace, vm.Name); BiosInfo biosInfo = VirtualMachineHelper.GetVMBios(PowerShell, vm.Name);
vm.NumLockEnabled = biosInfo.NumLockEnabled; vm.NumLockEnabled = biosInfo.NumLockEnabled;
vm.BootFromCD = false; vm.BootFromCD = false;
@ -191,27 +191,21 @@ namespace WebsitePanel.Providers.Virtualization
vm.BootFromCD = (biosInfo.StartupOrder[0] == "CD"); vm.BootFromCD = (biosInfo.StartupOrder[0] == "CD");
// DVD drive // DVD drive
cmd = new Command("Get-VMDvdDrive"); var dvdInfo = DvdDriveHelper.Get(PowerShell, vm.Name);
cmd.Parameters.Add("VMName", vm.Name); vm.DvdDriveInstalled = dvdInfo != null;
result = ExecuteShellCommand(runSpace, cmd, false);
vm.DvdDriveInstalled = (result != null && result.Count > 0);
// HDD // 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.VirtualHardDrivePath = vm.Disks[0].Path;
vm.HddSize = Convert.ToInt32(vm.Disks[0].FileSize); vm.HddSize = Convert.ToInt32(vm.Disks[0].FileSize);
} }
// network adapters // network adapters
vm.Adapters = GetNetworkAdapters(runSpace, vm.Name); vm.Adapters = NetworkAdapterHelper.Get(PowerShell, vm.Name);
return vm;
} }
} }
} }
catch (Exception ex) catch (Exception ex)
@ -219,201 +213,30 @@ namespace WebsitePanel.Providers.Virtualization
HostedSolutionLog.LogError("GetVirtualMachine", ex); HostedSolutionLog.LogError("GetVirtualMachine", ex);
throw; throw;
} }
finally
{
CloseRunspace(runSpace);
}
HostedSolutionLog.LogEnd("GetVirtualMachine"); HostedSolutionLog.LogEnd("GetVirtualMachine");
return vm; 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() public List<VirtualMachine> GetVirtualMachines()
{ {
HostedSolutionLog.LogStart("GetVirtualMachines"); HostedSolutionLog.LogStart("GetVirtualMachines");
Runspace runSpace = null;
List<VirtualMachine> vmachines = new List<VirtualMachine>(); List<VirtualMachine> vmachines = new List<VirtualMachine>();
try try
{ {
runSpace = OpenRunspace();
Command cmd = new Command("Get-VM"); 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) foreach (PSObject current in result)
{ {
VirtualMachine vm = new VirtualMachine VirtualMachine vm = new VirtualMachine
{ {
VirtualMachineId = GetPSObjectProperty(current, "Id").ToString(), VirtualMachineId = current.GetProperty("Id").ToString(),
Name = GetPSObjectProperty(current, "Name").ToString(), Name = current.GetProperty("Name").ToString(),
State = (VirtualMachineState)Enum.Parse(typeof(VirtualMachineState), GetPSObjectProperty(current, "State").ToString()), State = (VirtualMachineState)Enum.Parse(typeof(VirtualMachineState), current.GetProperty("State").ToString()),
Uptime = GetPSObjectProperty<TimeSpan>(current, "UpTime").Ticks Uptime = Convert.ToInt64(current.GetProperty<TimeSpan>("UpTime").TotalMilliseconds)
}; };
vmachines.Add(vm); vmachines.Add(vm);
} }
@ -423,10 +246,6 @@ namespace WebsitePanel.Providers.Virtualization
HostedSolutionLog.LogError("GetVirtualMachines", ex); HostedSolutionLog.LogError("GetVirtualMachines", ex);
throw; throw;
} }
finally
{
CloseRunspace(runSpace);
}
HostedSolutionLog.LogEnd("GetVirtualMachines"); HostedSolutionLog.LogEnd("GetVirtualMachines");
return vmachines; return vmachines;
@ -549,11 +368,11 @@ namespace WebsitePanel.Providers.Virtualization
vmID = (string)objVM["Name"]; vmID = (string)objVM["Name"];
// update general settings // update general settings
UpdateVirtualMachineGeneralSettings(vmID, objVM, //UpdateVirtualMachineGeneralSettings(vmID, objVM,
vm.CpuCores, // vm.CpuCores,
vm.RamSize, // vm.RamSize,
vm.BootFromCD, // vm.BootFromCD,
vm.NumLockEnabled); // vm.NumLockEnabled);
// hard disks // hard disks
// load IDE 0 controller // load IDE 0 controller
@ -608,113 +427,32 @@ namespace WebsitePanel.Providers.Virtualization
public VirtualMachine UpdateVirtualMachine(VirtualMachine vm) public VirtualMachine UpdateVirtualMachine(VirtualMachine vm)
{ {
string vmId = vm.VirtualMachineId; HostedSolutionLog.LogStart("UpdateVirtualMachine");
HostedSolutionLog.DebugInfo("Virtual Machine: {0}", vm.VirtualMachineId);
// get VM object Runspace runSpace = null;
ManagementObject objVM = GetVirtualMachineObject(vmId);
// update general settings try
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))
{ {
// delete adapter var realVm = GetVirtualMachine(vm.VirtualMachineId);
DeleteNetworkAdapter(objVM, vm.ExternalNicMacAddress);
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 catch (Exception ex)
&& !String.IsNullOrEmpty(vm.ExternalNicMacAddress))
{ {
// add external adapter HostedSolutionLog.LogError("UpdateVirtualMachine", ex);
AddNetworkAdapter(objVM, vm.ExternalSwitchId, vm.Name, vm.ExternalNicMacAddress, EXTERNAL_NETWORK_ADAPTER_NAME, vm.LegacyNetworkAdapter); throw;
} }
HostedSolutionLog.LogEnd("UpdateVirtualMachine");
// 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);
}
return vm; 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) private void AddVirtualMachineDvdDrive(string vmId, ManagementObject objVM)
{ {
@ -883,12 +621,9 @@ namespace WebsitePanel.Providers.Virtualization
var jobResult = new JobResult(); var jobResult = new JobResult();
var vm = GetVirtualMachine(vmId); var vm = GetVirtualMachine(vmId);
Runspace runSpace = null;
try try
{ {
runSpace = OpenRunspace();
string cmdTxt; string cmdTxt;
List<string> paramList = new List<string>(); List<string> paramList = new List<string>();
@ -926,7 +661,7 @@ namespace WebsitePanel.Providers.Virtualization
//cmd.Parameters.Add("AsJob"); //cmd.Parameters.Add("AsJob");
paramList.ForEach(p => cmd.Parameters.Add(p)); paramList.ForEach(p => cmd.Parameters.Add(p));
ExecuteShellCommand(runSpace, cmd, false); PowerShell.Execute(cmd, false);
jobResult = CreateSuccessJobResult(); jobResult = CreateSuccessJobResult();
} }
catch (Exception ex) catch (Exception ex)
@ -934,10 +669,6 @@ namespace WebsitePanel.Providers.Virtualization
HostedSolutionLog.LogError("ChangeVirtualMachineState", ex); HostedSolutionLog.LogError("ChangeVirtualMachineState", ex);
throw; throw;
} }
finally
{
CloseRunspace(runSpace);
}
HostedSolutionLog.LogEnd("ChangeVirtualMachineState"); HostedSolutionLog.LogEnd("ChangeVirtualMachineState");
@ -950,28 +681,22 @@ namespace WebsitePanel.Providers.Virtualization
ReturnCode returnCode = ReturnCode.OK; ReturnCode returnCode = ReturnCode.OK;
var vm = GetVirtualMachine(vmId); var vm = GetVirtualMachine(vmId);
Runspace runSpace = null;
try try
{ {
runSpace = OpenRunspace();
Command cmd = new Command("Stop-VM"); Command cmd = new Command("Stop-VM");
cmd.Parameters.Add("Name", vm.Name); cmd.Parameters.Add("Name", vm.Name);
if (force) cmd.Parameters.Add("Force"); 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) catch (Exception ex)
{ {
HostedSolutionLog.LogError("ShutDownVirtualMachine", ex); HostedSolutionLog.LogError("ShutDownVirtualMachine", ex);
throw; throw;
} }
finally
{
CloseRunspace(runSpace);
}
HostedSolutionLog.LogEnd("ShutDownVirtualMachine"); HostedSolutionLog.LogEnd("ShutDownVirtualMachine");
@ -1351,19 +1076,19 @@ namespace WebsitePanel.Providers.Virtualization
try try
{ {
runSpace = OpenRunspace();
Command cmd = new Command("Get-VMSwitch"); Command cmd = new Command("Get-VMSwitch");
if (!string.IsNullOrEmpty(computerName)) cmd.Parameters.Add("ComputerName", computerName); if (!string.IsNullOrEmpty(computerName)) cmd.Parameters.Add("ComputerName", computerName);
if (!string.IsNullOrEmpty(type)) cmd.Parameters.Add("SwitchType", type); 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) foreach (PSObject current in result)
{ {
VirtualSwitch sw = new VirtualSwitch(); VirtualSwitch sw = new VirtualSwitch();
sw.SwitchId = GetPSObjectProperty(current, "Name").ToString(); sw.SwitchId = current.GetProperty("Name").ToString();
sw.Name = GetPSObjectProperty(current, "Name").ToString(); sw.Name = current.GetProperty("Name").ToString();
sw.SwitchType = GetPSObjectProperty(current, "SwitchType").ToString(); sw.SwitchType = current.GetProperty("SwitchType").ToString();
switches.Add(sw); switches.Add(sw);
} }
} }
@ -1372,10 +1097,6 @@ namespace WebsitePanel.Providers.Virtualization
HostedSolutionLog.LogError("GetSwitches", ex); HostedSolutionLog.LogError("GetSwitches", ex);
throw; throw;
} }
finally
{
CloseRunspace(runSpace);
}
HostedSolutionLog.LogEnd("GetSwitches"); HostedSolutionLog.LogEnd("GetSwitches");
return switches; return switches;
@ -2100,12 +1821,12 @@ exit", Convert.ToInt32(objDisk["Index"])));
try try
{ {
runSpace = OpenRunspace();
Command cmd = new Command("Get-Job"); Command cmd = new Command("Get-Job");
if (!string.IsNullOrEmpty(jobId)) cmd.Parameters.Add("Id", jobId); 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); job = CreateJobFromPSObject(result);
} }
catch (Exception ex) catch (Exception ex)
@ -2113,10 +1834,6 @@ exit", Convert.ToInt32(objDisk["Index"])));
HostedSolutionLog.LogError("GetJob", ex); HostedSolutionLog.LogError("GetJob", ex);
throw; throw;
} }
finally
{
CloseRunspace(runSpace);
}
HostedSolutionLog.LogEnd("GetJob"); HostedSolutionLog.LogEnd("GetJob");
return job; return job;
@ -2503,21 +2220,21 @@ exit", Convert.ToInt32(objDisk["Index"])));
return null; return null;
ConcreteJob job = new ConcreteJob(); ConcreteJob job = new ConcreteJob();
job.Id = GetPSObjectProperty<int>(objJob[0], "Id").ToString(); job.Id = objJob[0].GetProperty<int>("Id").ToString();
job.JobState = GetPSObjectPropertyEnum<ConcreteJobState>(objJob[0], "JobStateInfo"); job.JobState = objJob[0].GetEnum<ConcreteJobState>("JobStateInfo");
job.Caption = GetPSObjectProperty<string>(objJob[0], "Name"); job.Caption = objJob[0].GetProperty<string>("Name");
job.Description = GetPSObjectProperty<string>(objJob[0], "Command"); job.Description = objJob[0].GetProperty<string>("Command");
job.StartTime = GetPSObjectProperty<DateTime>(objJob[0], "PSBeginTime"); job.StartTime = objJob[0].GetProperty<DateTime>("PSBeginTime");
job.ElapsedTime = GetPSObjectProperty<DateTime?>(objJob[0], "PSEndTime") ?? DateTime.Now; job.ElapsedTime = objJob[0].GetProperty<DateTime?>("PSEndTime") ?? DateTime.Now;
// PercentComplete // PercentComplete
job.PercentComplete = 0; 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) if (progress != null && progress.Count > 0)
job.PercentComplete = progress[0].PercentComplete; job.PercentComplete = progress[0].PercentComplete;
// Errors // Errors
var errors = (PSDataCollection<ErrorRecord>)GetPSObjectProperty(objJob[0], "Error"); var errors = (PSDataCollection<ErrorRecord>)objJob[0].GetProperty("Error");
if (errors != null && errors.Count > 0) if (errors != null && errors.Count > 0)
{ {
job.ErrorDescription = errors[0].ErrorDetails.Message + ". " + errors[0].ErrorDetails.RecommendedAction; job.ErrorDescription = errors[0].ErrorDetails.Message + ". " + errors[0].ErrorDetails.RecommendedAction;
@ -2813,152 +2530,13 @@ exit", Convert.ToInt32(objDisk["Index"])));
#endregion Hyper-V Cloud #endregion Hyper-V Cloud
#region PowerShell integration #region PowerShell integration
private static InitialSessionState session = null;
internal virtual Runspace OpenRunspace() private PowerShellManager _powerShell;
protected PowerShellManager PowerShell
{ {
HostedSolutionLog.LogStart("OpenRunspace"); get { return _powerShell ?? (_powerShell = new PowerShellManager()); }
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;
} }
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 #endregion

View file

@ -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;
}
}
}

View file

@ -53,8 +53,13 @@
<Compile Include="..\VersionInfo.cs"> <Compile Include="..\VersionInfo.cs">
<Link>VersionInfo.cs</Link> <Link>VersionInfo.cs</Link>
</Compile> </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="HyperV2012R2.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Helpers\VirtualMachineHelper.cs" />
<Compile Include="Wmi.cs" /> <Compile Include="Wmi.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>