예제 #1
0
 public void Dispose()
 {
     if (_powerShellSupport != null)
     {
         _powerShellSupport.Dispose();
         _powerShellSupport = null;
     }
 }
예제 #2
0
        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;
                }
            }));
        }
예제 #3
0
        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);
                }
            });
        }
예제 #5
0
        /// <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);
        }