public void Dispose() { if (_powerShellSupport != null) { _powerShellSupport.Dispose(); _powerShellSupport = null; } }
public async Task <Runspace> CreateRunspaceAsync() { return(await Task.Run( () => { var wSManConnectionInfo = PowerShellSupport.CreateConnectionInfo(_computer); Runspace runspace = null; try { runspace = RunspaceFactory.CreateRunspace(wSManConnectionInfo); runspace.Open(); return runspace; } catch { runspace?.Dispose(); throw; } })); }
internal ExchangePowerShellSupport(string configuredExchangeVersion, string exchangeUri, ConnectorMessages messageCatalog) { if (configuredExchangeVersion == null && exchangeUri != null) { LOGGER.TraceEvent(TraceEventType.Warning, CAT_DEFAULT, "No configured Exchange version. As auto-detection is not possible in remote mode, using 2010 as a default."); _exchangeVersion = ExchangeVersion.E2010; } else { _exchangeVersion = GetExchangeServerVersion(configuredExchangeVersion); } IList <string> snapins = new List <string>(); if (exchangeUri == null) { switch (_exchangeVersion) { case ExchangeVersion.E2007: // used for force load of the exchange dll's (untested in current version of the connector!) AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(AssemblyResolver2007); snapins.Add(Exchange2007SnapIn); break; case ExchangeVersion.E2010: snapins.Add(Exchange2010SnapIn); break; case ExchangeVersion.E2013: snapins.Add(Exchange2013SnapIn); break; default: throw new ArgumentException("Invalid server version: " + _exchangeVersion); } } _exchangeUri = exchangeUri; _messageCatalog = messageCatalog; _powerShellSupport = new PowerShellSupport(snapins, CreateExchangeRunspace, messageCatalog); }
private async Task RunPowershell(RemoteComputer powershellComputer) { var connectionInfo = PowerShellSupport.CreateConnectionInfo(powershellComputer); await Task.Run( () => { try { powershellComputer.JobStatus = PowerShellJobStatus.Connecting; cancellationTokenSource.Token.ThrowIfCancellationRequested(); using (var runspace = RunspaceFactory.CreateRunspace(connectionInfo)) { cancellationTokenSource.Token.ThrowIfCancellationRequested(); using (cancellationTokenSource.Token.Register( () => runspace.Close())) { runspace.Open(); } cancellationTokenSource.Token.ThrowIfCancellationRequested(); using (var powershell = PowerShell.Create()) { cancellationTokenSource.Token.ThrowIfCancellationRequested(); powershell.Runspace = runspace; foreach (var script in FileNames) { powershell.AddScript(File.ReadAllText(script)); } var input = new PSDataCollection <PSObject>(); var output = new PSDataCollection <PSObject>(); powershell.Streams.Error.DataAdded += (s, ev) => ErrorOnDataAdded(s, ev, powershellComputer); powershell.Streams.Debug.DataAdded += (s, ev) => DebugOnDataAdded(s, ev, powershellComputer); powershell.Streams.Progress.DataAdded += (s, ev) => ProgressOnDataAdded(s, ev, powershellComputer); powershell.Streams.Verbose.DataAdded += (s, ev) => VerboseOnDataAdded(s, ev, powershellComputer); powershell.Streams.Warning.DataAdded += (s, ev) => WarningOnDataAdded(s, ev, powershellComputer); powershellComputer.JobStatus = PowerShellJobStatus.Invoking; cancellationTokenSource.Token.ThrowIfCancellationRequested(); using (cancellationTokenSource.Token.Register( () => { powershell.InvocationStateChanged += (sender, args) => { switch (args.InvocationStateInfo.State) { case PSInvocationState.Failed: powershellComputer.JobStatus = PowerShellJobStatus.Failed; break; case PSInvocationState.Completed: powershellComputer.JobStatus = PowerShellJobStatus.Completed; break; case PSInvocationState.Stopping: powershellComputer.JobStatus = PowerShellJobStatus.Cancelling; break; case PSInvocationState.Stopped: powershellComputer.JobStatus = PowerShellJobStatus.Cancelled; break; } }; powershell.Stop(); })) { powershell.Invoke(input, output); } cancellationTokenSource.Token.ThrowIfCancellationRequested(); powershellComputer.JobStatus = PowerShellJobStatus.Completed; } } } catch (RemoteException e) { if (cancellationTokenSource.IsCancellationRequested) { powershellComputer.JobStatus = PowerShellJobStatus.Cancelled; return; } throw; } catch (PSRemotingDataStructureException ex) { if (ex?.ErrorRecord?.Exception?.Message == "The pipeline has been stopped.") { powershellComputer.JobStatus = PowerShellJobStatus.Cancelled; } } catch (PSRemotingTransportException ex) { if (ex.ErrorRecord != null) { WriteErrorRecord(powershellComputer, ex.ErrorRecord); } powershellComputer.JobStatus = PowerShellJobStatus.CouldntConnect; } catch (OperationCanceledException ex) { switch (powershellComputer.JobStatus) { case PowerShellJobStatus.Waiting: case PowerShellJobStatus.Invoking: case PowerShellJobStatus.Connecting: case PowerShellJobStatus.Cancelling: powershellComputer.JobStatus = PowerShellJobStatus.Cancelled; break; } } catch (Exception ex) { powershellComputer.JobStatus = PowerShellJobStatus.Failed; MessageBox.Show( "An internal error has occurred!\n" + ex, "Internal error", MessageBoxButton.OK, MessageBoxImage.Error); } }); }
/// <summary> /// Determines the version of the Exchange server. /// </summary> /// <remarks>As the remote management functionality is not utilized, the Exchange powershell snap-in must be registered /// on the local computer. Different snap-in is used to manage Exchange 2007 and 2010, hence the server version is determined by the /// registered snap-in. /// </remarks> /// <returns>The version of the Exchange server to manage.</returns> /// <exception cref="ConnectorException">Thrown when the version cannot be determined.</exception> private ExchangeVersion GetExchangeServerVersion(string configuredExchangeVersion) { const string MethodName = "GetExchangeServerVersion"; Debug.WriteLine(MethodName + ":entry", ClassName); if (configuredExchangeVersion != null) { LOGGER.TraceEvent(TraceEventType.Information, CAT_DEFAULT, "Using configured Exchange version: {0}", configuredExchangeVersion); switch (configuredExchangeVersion) { case "2007": return(ExchangeVersion.E2007); case "2010": return(ExchangeVersion.E2010); case "2013": return(ExchangeVersion.E2013); default: throw new ArgumentException("Invalid or unsupported Exchange version: " + configuredExchangeVersion + " (supported ones are: 2007, 2010, 2013)"); } } LOGGER.TraceEvent(TraceEventType.Information, CAT_DEFAULT, "Trying to determine Exchange version from registered PowerShell snapins"); const string ExchangeSnapinNamePrefix = "Microsoft.Exchange.Management.PowerShell."; ExchangeVersion?version = null; using (var runspace = RunspaceFactory.CreateRunspace()) { runspace.Open(); using (var pipeline = runspace.CreatePipeline()) { var getSnapinsCommand = new Command("Get-PSSnapin"); getSnapinsCommand.Parameters.Add("Registered"); pipeline.Commands.Add(getSnapinsCommand); var snapinList = pipeline.Invoke(); PipelineReader <object> reader = pipeline.Error; PowerShellSupport.CheckErrorsFromReader(reader); runspace.Close(); if ((snapinList == null) || (snapinList.Count == 0)) { LOGGER.TraceEvent(TraceEventType.Error, CAT_DEFAULT, "No snap-in returned"); throw new ConnectorException(_messageCatalog.Format("ex_NoPowerShellSnapins", "There are no registered PowerShell snap-ins.")); } foreach (var snapin in snapinList) { if (snapin.Properties["Name"] != null && snapin.Properties["Name"].Value != null) { var name = snapin.Properties["Name"].Value.ToString(); LOGGER.TraceEvent(TraceEventType.Verbose, CAT_DEFAULT, "Found registered snap-in: {0}", name); if (name.StartsWith(ExchangeSnapinNamePrefix, StringComparison.InvariantCultureIgnoreCase)) { switch (name.Substring(ExchangeSnapinNamePrefix.Length)) { case "Admin": //Microsoft.Exchange.Management.PowerShell.Admin snap-in is used to manage Exchange 2007 version = ExchangeVersion.E2007; break; case "SnapIn": // TODO test if this works version = ExchangeVersion.E2013; break; case "E2010": //Microsoft.Exchange.Management.PowerShell.E2010 snap-in is used to manage Exchange 2010 version = ExchangeVersion.E2010; break; } } } } } } if (!version.HasValue) { throw new ConnectorException(_messageCatalog.Format("ex_NoSupportedExchangeSnapin", "There is no supported Exchange PowerShell snap-in registered.")); } LOGGER.TraceEvent(TraceEventType.Information, CAT_DEFAULT, "Exchange version determined to be {0}", version.ToString()); Debug.WriteLine(MethodName + ":exit", ClassName); return(version.Value); }