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 { private readonly string _remoteComputerName; protected static InitialSessionState session = null; protected Runspace RunSpace { get; set; } public PowerShellManager(string remoteComputerName) { _remoteComputerName = remoteComputerName; 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 Execute(Command cmd) { return Execute(cmd, true); } public Collection Execute(Command cmd, bool addComputerNameParameter) { object[] errors; return Execute(cmd, addComputerNameParameter, out errors); } public Collection Execute(Command cmd, bool addComputerNameParameter, out object[] errors) { HostedSolutionLog.LogStart("Execute"); List errorList = new List(); HostedSolutionLog.DebugCommand(cmd); Collection results = null; // Add computerName parameter to command if it is remote server if (addComputerNameParameter) { if (!string.IsNullOrEmpty(_remoteComputerName)) cmd.Parameters.Add("ComputerName", _remoteComputerName); } // Create a pipeline Pipeline pipeLine = RunSpace.CreatePipeline(); using (pipeLine) { // Add the command pipeLine.Commands.Add(cmd); // Execute the pipeline and save the objects returned. results = pipeLine.Invoke(); // Only non-terminating errors are delivered here. // Terminating errors raise exceptions instead. // Log out any errors in the pipeline execution // NOTE: These errors are NOT thrown as exceptions! // Be sure to check this to ensure that no errors // 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; } public static void ExceptionIfErrors(object[] errors) { if (errors != null && errors.Length > 0) throw new Exception("Invoke error: " + string.Join("; ", errors.Select(e => e.ToString()))); } } }