Team Ai
Datasetpublic

MegaBites-AI/Windows-powershell

sourceHugging Facemitupdated 6mo agoView on Hugging Face
0likes372downloads
PushRunspaceCommand.cs1401 linesDownload Raw Back to commands
1// Copyright (c) Microsoft Corporation.2// Licensed under the MIT License.3 4using System;5using System.Collections;6using System.Collections.Generic;7using System.Collections.ObjectModel;8using System.Diagnostics.CodeAnalysis;9using System.Management.Automation;10using System.Management.Automation.Host;11using System.Management.Automation.Internal;12using System.Management.Automation.Remoting;13using System.Management.Automation.Runspaces;14using System.Threading;15 16using Microsoft.PowerShell.Commands.Internal.Format;17 18using Dbg = System.Management.Automation.Diagnostics;19 20namespace Microsoft.PowerShell.Commands21{22    /// <summary>23    /// Enter-PSSession cmdlet.24    /// </summary>25    [Cmdlet(VerbsCommon.Enter, "PSSession", DefaultParameterSetName = "ComputerName",26        HelpUri = "https://go.microsoft.com/fwlink/?LinkID=2096695", RemotingCapability = RemotingCapability.OwnedByCommand)]27    public class EnterPSSessionCommand : PSRemotingBaseCmdlet28    {29        #region Strings30 31        private const string InstanceIdParameterSet = "InstanceId";32        private const string IdParameterSet = "Id";33        private const string NameParameterSet = "Name";34 35        #endregion36 37        #region Members38 39        /// <summary>40        /// Disable ThrottleLimit parameter inherited from base class.41        /// </summary>42        public new int ThrottleLimit { get { return 0; } set { } }43 44        private ObjectStream _stream;45        private RemoteRunspace _tempRunspace;46 47        #endregion48 49        #region Parameters50 51        #region SSH Parameter Set52 53        /// <summary>54        /// Host name for an SSH remote connection.55        /// </summary>56        [Parameter(Position = 0, Mandatory = true, ValueFromPipeline = true,57            ParameterSetName = PSRemotingBaseCmdlet.SSHHostParameterSet)]58        [ValidateNotNullOrEmpty]59        public new string HostName { get; set; }60 61        /// <summary>62        /// Gets or sets the Hashtable containing options to be passed to OpenSSH.63        /// </summary>64        [Parameter(ParameterSetName = PSRemotingBaseCmdlet.SSHHostParameterSet)]65        [ValidateNotNullOrEmpty]66        public override Hashtable Options 67        { 68            get 69            {70                return base.Options;71            }72 73            set74            {75                base.Options = value;76            }77        }78 79        #endregion80 81        /// <summary>82        /// Computer name parameter.83        /// </summary>84        [Parameter(Position = 0, Mandatory = true, ValueFromPipeline = true,85            ValueFromPipelineByPropertyName = true, ParameterSetName = ComputerNameParameterSet)]86        [Alias("Cn")]87        [ValidateNotNullOrEmpty]88        public new string ComputerName { get; set; }89 90        /// <summary>91        /// Runspace parameter.92        /// </summary>93        [Parameter(Position = 0, ValueFromPipelineByPropertyName = true,94            ValueFromPipeline = true, ParameterSetName = SessionParameterSet)]95        [ValidateNotNullOrEmpty]96        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Runspace")]97        public new PSSession Session { get; set; }98 99        /// <summary>100        /// ConnectionUri parameter.101        /// </summary>102        [Parameter(Position = 1, ValueFromPipelineByPropertyName = true,103            ParameterSetName = UriParameterSet)]104        [ValidateNotNullOrEmpty]105        [Alias("URI", "CU")]106        public new Uri ConnectionUri { get; set; }107 108        /// <summary>109        /// RemoteRunspaceId of the remote runspace info object.110        /// </summary>111        [Parameter(ValueFromPipelineByPropertyName = true,112        ParameterSetName = InstanceIdParameterSet)]113        [ValidateNotNull]114        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Runspace")]115        public Guid InstanceId { get; set; }116 117        /// <summary>118        /// SessionId of the remote runspace info object.119        /// </summary>120        [Parameter(Position = 0,121            ValueFromPipelineByPropertyName = true,122             ParameterSetName = IdParameterSet)]123        [ValidateNotNull]124        public int Id { get; set; }125 126        /// <summary>127        /// Name of the remote runspace info object.128        /// </summary>129        [Parameter(ValueFromPipelineByPropertyName = true,130        ParameterSetName = NameParameterSet)]131        public string Name { get; set; }132 133        /// <summary>134        /// When set and in loopback scenario (localhost) this enables creation of WSMan135        /// host process with the user interactive token, allowing PowerShell script network access,136        /// i.e., allows going off box.  When this property is true and a PSSession is disconnected,137        /// reconnection is allowed only if reconnecting from a PowerShell session on the same box.138        /// </summary>139        [Parameter(ParameterSetName = ComputerNameParameterSet)]140        [Parameter(ParameterSetName = UriParameterSet)]141        public SwitchParameter EnableNetworkAccess { get; set; }142 143        /// <summary>144        /// Virtual machine ID.145        /// </summary>146        [ValidateNotNullOrEmpty]147        [Parameter(Position = 0, Mandatory = true, ValueFromPipeline = true,148            ValueFromPipelineByPropertyName = true, ParameterSetName = VMIdParameterSet)]149        [Alias("VMGuid")]150        public new Guid VMId { get; set; }151 152        /// <summary>153        /// Virtual machine name.154        /// </summary>155        [ValidateNotNullOrEmpty]156        [Parameter(Position = 0, Mandatory = true, ValueFromPipeline = true,157            ValueFromPipelineByPropertyName = true, ParameterSetName = VMNameParameterSet)]158        public new string VMName { get; set; }159 160        /// <summary>161        /// Specifies the credentials of the user to impersonate in the162        /// virtual machine. If this parameter is not specified then the163        /// credentials of the current user process will be assumed.164        /// </summary>165        [Parameter(ValueFromPipelineByPropertyName = true,166                   ParameterSetName = PSRemotingBaseCmdlet.ComputerNameParameterSet)]167        [Parameter(ValueFromPipelineByPropertyName = true,168                   ParameterSetName = PSRemotingBaseCmdlet.UriParameterSet)]169        [Parameter(Position = 1, Mandatory = true, ValueFromPipelineByPropertyName = true,170                   ParameterSetName = VMIdParameterSet)]171        [Parameter(Position = 1, Mandatory = true, ValueFromPipelineByPropertyName = true,172                   ParameterSetName = VMNameParameterSet)]173        [Credential]174        public override PSCredential Credential175        {176            get { return base.Credential; }177 178            set { base.Credential = value; }179        }180 181        /// <summary>182        /// The Id of the target container.183        /// </summary>184        [ValidateNotNullOrEmpty]185        [Parameter(Position = 0, Mandatory = true, ValueFromPipeline = true,186            ValueFromPipelineByPropertyName = true, ParameterSetName = ContainerIdParameterSet)]187        public new string ContainerId { get; set; }188 189        /// <summary>190        /// For WSMan sessions:191        /// If this parameter is not specified then the value specified in192        /// the environment variable DEFAULTREMOTESHELLNAME will be used. If193        /// this is not set as well, then Microsoft.PowerShell is used.194        ///195        /// For VM/Container sessions:196        /// If this parameter is not specified then no configuration is used.197        /// </summary>198        [Parameter(ValueFromPipelineByPropertyName = true,199                   ParameterSetName = EnterPSSessionCommand.ComputerNameParameterSet)]200        [Parameter(ValueFromPipelineByPropertyName = true,201                   ParameterSetName = EnterPSSessionCommand.UriParameterSet)]202        [Parameter(ValueFromPipelineByPropertyName = true,203                   ParameterSetName = EnterPSSessionCommand.ContainerIdParameterSet)]204        [Parameter(ValueFromPipelineByPropertyName = true,205                   ParameterSetName = EnterPSSessionCommand.VMIdParameterSet)]206        [Parameter(ValueFromPipelineByPropertyName = true,207                   ParameterSetName = EnterPSSessionCommand.VMNameParameterSet)]208        public string ConfigurationName { get; set; }209 210        #region Suppress PSRemotingBaseCmdlet SSH hash parameter set211 212        /// <summary>213        /// Suppress SSHConnection parameter set.214        /// </summary>215        public override Hashtable[] SSHConnection216        {217            get { return null; }218        }219 220        #endregion221 222        #endregion223 224        #region Overrides225 226        /// <summary>227        /// Resolves shellname and appname.228        /// </summary>229        protected override void BeginProcessing()230        {231            base.BeginProcessing();232 233            if (string.IsNullOrEmpty(ConfigurationName))234            {235                if ((ParameterSetName == EnterPSSessionCommand.ComputerNameParameterSet) ||236                    (ParameterSetName == EnterPSSessionCommand.UriParameterSet))237                {238                    // set to default value for WSMan session239                    ConfigurationName = ResolveShell(null);240                }241                else242                {243                    // convert null to string.Empty for VM/Container session244                    ConfigurationName = string.Empty;245                }246            }247        }248 249        /// <summary>250        /// Process record.251        /// </summary>252        protected override void ProcessRecord()253        {254            // Push the remote runspace on the local host.255            IHostSupportsInteractiveSession host = this.Host as IHostSupportsInteractiveSession;256            if (host == null)257            {258                WriteError(259                    new ErrorRecord(260                        new ArgumentException(GetMessage(RemotingErrorIdStrings.HostDoesNotSupportPushRunspace)),261                        nameof(PSRemotingErrorId.HostDoesNotSupportPushRunspace),262                        ErrorCategory.InvalidArgument,263                        null));264                return;265            }266 267            // for the console host and Graphical PowerShell host268            // we want to skip pushing into the runspace if269            // the host is in a nested prompt270            System.Management.Automation.Internal.Host.InternalHost chost =271                this.Host as System.Management.Automation.Internal.Host.InternalHost;272 273            if (!IsParameterSetForVM() &&274                !IsParameterSetForContainer() &&275                !IsParameterSetForVMContainerSession() &&276                chost != null && chost.HostInNestedPrompt())277            {278                ThrowTerminatingError(new ErrorRecord(279                    new InvalidOperationException(PSRemotingErrorInvariants.FormatResourceString(RemotingErrorIdStrings.HostInNestedPrompt)),280                    "HostInNestedPrompt", ErrorCategory.InvalidOperation, chost));281            }282 283            /*Microsoft.Windows.PowerShell.Gui.Internal.GPSHost ghost = this.Host as Microsoft.Windows.PowerShell.Gui.Internal.GPSHost;284 285            if (ghost != null && ghost.HostInNestedPrompt())286            {287                ThrowTerminatingError(new ErrorRecord(288                    new InvalidOperationException(PSRemotingErrorInvariants.FormatResourceString(PSRemotingErrorId.HostInNestedPrompt)),289                    "HostInNestedPrompt", ErrorCategory.InvalidOperation, wpshost));290            }*/291 292            // Get the remote runspace.293            RemoteRunspace remoteRunspace = null;294            switch (ParameterSetName)295            {296                case ComputerNameParameterSet:297                    remoteRunspace = CreateRunspaceWhenComputerNameParameterSpecified();298                    break;299 300                case UriParameterSet:301                    remoteRunspace = CreateRunspaceWhenUriParameterSpecified();302                    break;303 304                case SessionParameterSet:305                    remoteRunspace = (RemoteRunspace)Session.Runspace;306                    break;307 308                case InstanceIdParameterSet:309                    remoteRunspace = GetRunspaceMatchingRunspaceId(this.InstanceId);310                    break;311 312                case IdParameterSet:313                    remoteRunspace = GetRunspaceMatchingSessionId(this.Id);314                    break;315 316                case NameParameterSet:317                    remoteRunspace = GetRunspaceMatchingName(this.Name);318                    break;319 320                case VMIdParameterSet:321                case VMNameParameterSet:322                    remoteRunspace = GetRunspaceForVMSession();323                    break;324 325                case ContainerIdParameterSet:326                    remoteRunspace = GetRunspaceForContainerSession();327                    break;328 329                case SSHHostParameterSet:330                    remoteRunspace = GetRunspaceForSSHSession();331                    break;332            }333 334            // If runspace is null then the error record has already been written and we can exit.335            if (remoteRunspace == null)336            {337                return;338            }339 340            // If the runspace is in a disconnected state try to connect.341            bool runspaceConnected = false;342            if (remoteRunspace.RunspaceStateInfo.State == RunspaceState.Disconnected)343            {344                if (!remoteRunspace.CanConnect)345                {346                    string message = StringUtil.Format(RemotingErrorIdStrings.SessionNotAvailableForConnection);347                    WriteError(348                        new ErrorRecord(349                            new RuntimeException(message), "EnterPSSessionCannotConnectDisconnectedSession",350                                ErrorCategory.InvalidOperation, remoteRunspace));351 352                    return;353                }354 355                // Connect the runspace.356                Exception ex = null;357                try358                {359                    remoteRunspace.Connect();360                    runspaceConnected = true;361                }362                catch (System.Management.Automation.Remoting.PSRemotingTransportException e)363                {364                    ex = e;365                }366                catch (PSInvalidOperationException e)367                {368                    ex = e;369                }370                catch (InvalidRunspacePoolStateException e)371                {372                    ex = e;373                }374 375                if (ex != null)376                {377                    string message = StringUtil.Format(RemotingErrorIdStrings.SessionConnectFailed);378                    WriteError(379                        new ErrorRecord(380                            new RuntimeException(message, ex), "EnterPSSessionConnectSessionFailed",381                                ErrorCategory.InvalidOperation, remoteRunspace));382 383                    return;384                }385            }386 387            // Verify that the runspace is open.388            if (remoteRunspace.RunspaceStateInfo.State != RunspaceState.Opened)389            {390                if (ParameterSetName == SessionParameterSet)391                {392                    string sessionName = (Session != null) ? Session.Name : string.Empty;393                    WriteError(394                        new ErrorRecord(395                            new ArgumentException(GetMessage(RemotingErrorIdStrings.EnterPSSessionBrokenSession,396                                sessionName, remoteRunspace.ConnectionInfo.ComputerName, remoteRunspace.InstanceId)),397                            nameof(PSRemotingErrorId.PushedRunspaceMustBeOpen),398                            ErrorCategory.InvalidArgument,399                            null));400                }401                else402                {403                    WriteError(404                        new ErrorRecord(405                            new ArgumentException(GetMessage(RemotingErrorIdStrings.PushedRunspaceMustBeOpen)),406                            nameof(PSRemotingErrorId.PushedRunspaceMustBeOpen),407                            ErrorCategory.InvalidArgument,408                            null));409                }410 411                return;412            }413 414            Debugger debugger = null;415            try416            {417                if (host.Runspace != null)418                {419                    debugger = host.Runspace.Debugger;420                }421            }422            catch (PSNotImplementedException) { }423 424            bool supportRunningCommand = ((debugger != null) && ((debugger.DebugMode & DebugModes.RemoteScript) == DebugModes.RemoteScript));425            if (remoteRunspace.RunspaceAvailability != RunspaceAvailability.Available)426            {427                // Session has running command.428                if (!supportRunningCommand)429                {430                    // Host does not support remote debug and cannot connect to running command.431                    if (runspaceConnected)432                    {433                        // If we succeeded connecting the session (runspace) but it is already running a command,434                        // emit an error for this case because since it is disconnected this session object will435                        // never complete and the user must use *reconstruct* scenario to retrieve data.436                        string message = StringUtil.Format(RemotingErrorIdStrings.EnterPSSessionDisconnected,437                                                        remoteRunspace.PSSessionName);438                        WriteError(439                            new ErrorRecord(440                                new RuntimeException(message), "EnterPSSessionConnectSessionNotAvailable",441                                    ErrorCategory.InvalidOperation, Session));442 443                        // Leave session in original disconnected state.444                        remoteRunspace.DisconnectAsync();445 446                        return;447                    }448                    else449                    {450                        // If the remote runspace is currently not available then let user know that this command451                        // will not complete until it becomes available.452                        WriteWarning(GetMessage(RunspaceStrings.RunspaceNotReady));453                    }454                }455                else456                {457                    // Running commands supported.458                    // Warn user that they are entering a session that is running a command and output may459                    // be going to a job object.460                    Job job = FindJobForRunspace(remoteRunspace.InstanceId);461                    string msg;462                    if (job != null)463                    {464                        msg = StringUtil.Format(465                            RunspaceStrings.RunningCmdWithJob,466                            (!string.IsNullOrEmpty(job.Name)) ? job.Name : string.Empty);467                    }468                    else469                    {470                        if (remoteRunspace.RunspaceAvailability == RunspaceAvailability.RemoteDebug)471                        {472                            msg = StringUtil.Format(473                                RunspaceStrings.RunningCmdDebugStop);474                        }475                        else476                        {477                            msg = StringUtil.Format(478                                RunspaceStrings.RunningCmdWithoutJob);479                        }480                    }481 482                    WriteWarning(msg);483                }484            }485 486            // Make sure any PSSession object passed in is saved in the local runspace repository.487            if (Session != null)488            {489                this.RunspaceRepository.AddOrReplace(Session);490            }491 492            // prepare runspace for prompt493            SetRunspacePrompt(remoteRunspace);494 495            try496            {497                host.PushRunspace(remoteRunspace);498            }499            catch (Exception)500            {501                // A third-party host can throw any exception here..we should502                // clean the runspace created in this case.503                if ((remoteRunspace != null) && (remoteRunspace.ShouldCloseOnPop))504                {505                    remoteRunspace.Close();506                }507 508                // rethrow the exception after cleanup.509                throw;510            }511        }512 513        /// <summary>514        /// This method will until the runspace is opened and warnings if any515        /// are reported.516        /// </summary>517        protected override void EndProcessing()518        {519            if (_stream != null)520            {521                while (true)522                {523                    // Keep reading objects until end of stream is encountered524                    _stream.ObjectReader.WaitHandle.WaitOne();525 526                    if (!_stream.ObjectReader.EndOfPipeline)527                    {528                        object streamObject = _stream.ObjectReader.Read();529                        WriteStreamObject((Action<Cmdlet>)streamObject);530                    }531                    else532                    {533                        break;534                    }535                }536            }537        }538 539        /// <summary>540        /// </summary>541        protected override void StopProcessing()542        {543            var remoteRunspace = _tempRunspace;544            if (remoteRunspace != null)545            {546                try547                {548                    remoteRunspace.CloseAsync();549                }550                catch (InvalidRunspaceStateException) { }551 552                return;553            }554 555            IHostSupportsInteractiveSession host = this.Host as IHostSupportsInteractiveSession;556            if (host == null)557            {558                WriteError(559                    new ErrorRecord(560                        new ArgumentException(GetMessage(RemotingErrorIdStrings.HostDoesNotSupportPushRunspace)),561                        nameof(PSRemotingErrorId.HostDoesNotSupportPushRunspace),562                        ErrorCategory.InvalidArgument,563                        null));564                return;565            }566 567            host.PopRunspace();568        }569 570        #endregion571 572        #region Private Methods573 574        /// <summary>575        /// Create temporary remote runspace.576        /// </summary>577        private RemoteRunspace CreateTemporaryRemoteRunspace(PSHost host, WSManConnectionInfo connectionInfo)578        {579            // Create and open the runspace.580            int rsId;581            string rsName = PSSession.GenerateRunspaceName(out rsId);582            RemoteRunspace remoteRunspace = new RemoteRunspace(583                Utils.GetTypeTableFromExecutionContextTLS(),584                connectionInfo,585                host,586                this.SessionOption.ApplicationArguments,587                rsName,588                rsId);589            Dbg.Assert(remoteRunspace != null, "Expected remoteRunspace != null");590            remoteRunspace.URIRedirectionReported += HandleURIDirectionReported;591 592            _stream = new ObjectStream();593            try594            {595                remoteRunspace.Open();596 597                // Mark this temporary runspace so that it closes on pop.598                remoteRunspace.ShouldCloseOnPop = true;599            }600            finally601            {602                // unregister uri redirection handler603                remoteRunspace.URIRedirectionReported -= HandleURIDirectionReported;604                // close the internal object stream after runspace is opened605                // Runspace.Open() might throw exceptions..this will make sure606                // the stream is always closed.607                _stream.ObjectWriter.Close();608 609                // make sure we dispose the temporary runspace if something bad happens610                if (remoteRunspace.RunspaceStateInfo.State != RunspaceState.Opened)611                {612                    remoteRunspace.Dispose();613                    remoteRunspace = null;614                }615            }616 617            return remoteRunspace;618        }619 620        /// <summary>621        /// Write error create remote runspace failed.622        /// </summary>623        private void WriteErrorCreateRemoteRunspaceFailed(Exception exception, object argument)624        {625            // set the transport message in the error detail so that626            // the user can directly get to see the message without627            // having to mine through the error record details628            PSRemotingTransportException transException =629                        exception as PSRemotingTransportException;630            string errorDetails = null;631            if ((transException != null) &&632                (transException.ErrorCode ==633                    System.Management.Automation.Remoting.Client.WSManNativeApi.ERROR_WSMAN_REDIRECT_REQUESTED))634            {635                // Handling a special case for redirection..we should talk about636                // AllowRedirection parameter and WSManMaxRedirectionCount preference637                // variables638                string message = PSRemotingErrorInvariants.FormatResourceString(639                    RemotingErrorIdStrings.URIRedirectionReported,640                    transException.Message,641                    "MaximumConnectionRedirectionCount",642                    Microsoft.PowerShell.Commands.PSRemotingBaseCmdlet.DEFAULT_SESSION_OPTION,643                    "AllowRedirection");644 645                errorDetails = message;646            }647 648            ErrorRecord errorRecord = new ErrorRecord(exception, argument,649                "CreateRemoteRunspaceFailed",650                ErrorCategory.InvalidArgument,651                null, null, null, null, null, errorDetails, null);652 653            WriteError(errorRecord);654        }655 656        /// <summary>657        /// Write invalid argument error.658        /// </summary>659        private void WriteInvalidArgumentError(PSRemotingErrorId errorId, string resourceString, object errorArgument)660        {661            string message = GetMessage(resourceString, errorArgument);662            WriteError(new ErrorRecord(new ArgumentException(message), errorId.ToString(),663                ErrorCategory.InvalidArgument, errorArgument));664        }665 666        /// <summary>667        /// When the client remote session reports a URI redirection, this method will report the668        /// message to the user as a Warning using Host method calls.669        /// </summary>670        /// <param name="sender"></param>671        /// <param name="eventArgs"></param>672        private void HandleURIDirectionReported(object sender, RemoteDataEventArgs<Uri> eventArgs)673        {674            string message = StringUtil.Format(RemotingErrorIdStrings.URIRedirectWarningToHost, eventArgs.Data.OriginalString);675            Action<Cmdlet> streamObject = (Cmdlet cmdlet) => cmdlet.WriteWarning(message);676            _stream.Write(streamObject);677        }678 679        /// <summary>680        /// Create runspace when computer name parameter specified.681        /// </summary>682        private RemoteRunspace CreateRunspaceWhenComputerNameParameterSpecified()683        {684            RemoteRunspace remoteRunspace = null;685            string resolvedComputerName = ResolveComputerName(ComputerName);686            try687            {688                WSManConnectionInfo connectionInfo = null;689                connectionInfo = new WSManConnectionInfo();690                string scheme = UseSSL.IsPresent ? WSManConnectionInfo.HttpsScheme : WSManConnectionInfo.HttpScheme;691                connectionInfo.ComputerName = resolvedComputerName;692                connectionInfo.Port = Port;693                connectionInfo.AppName = ApplicationName;694                connectionInfo.ShellUri = ConfigurationName;695                connectionInfo.Scheme = scheme;696                if (CertificateThumbprint != null)697                {698                    connectionInfo.CertificateThumbprint = CertificateThumbprint;699                }700                else701                {702                    connectionInfo.Credential = Credential;703                }704 705                connectionInfo.AuthenticationMechanism = Authentication;706                UpdateConnectionInfo(connectionInfo);707 708                connectionInfo.EnableNetworkAccess = EnableNetworkAccess;709 710                remoteRunspace = CreateTemporaryRemoteRunspace(this.Host, connectionInfo);711            }712            catch (InvalidOperationException e)713            {714                WriteErrorCreateRemoteRunspaceFailed(e, resolvedComputerName);715            }716            catch (ArgumentException e)717            {718                WriteErrorCreateRemoteRunspaceFailed(e, resolvedComputerName);719            }720            catch (PSRemotingTransportException e)721            {722                WriteErrorCreateRemoteRunspaceFailed(e, resolvedComputerName);723            }724 725            return remoteRunspace;726        }727 728        /// <summary>729        /// Create runspace when uri parameter specified.730        /// </summary>731        private RemoteRunspace CreateRunspaceWhenUriParameterSpecified()732        {733            RemoteRunspace remoteRunspace = null;734            try735            {736                WSManConnectionInfo connectionInfo = new WSManConnectionInfo();737                connectionInfo.ConnectionUri = ConnectionUri;738                connectionInfo.ShellUri = ConfigurationName;739                if (CertificateThumbprint != null)740                {741                    connectionInfo.CertificateThumbprint = CertificateThumbprint;742                }743                else744                {745                    connectionInfo.Credential = Credential;746                }747 748                connectionInfo.AuthenticationMechanism = Authentication;749                UpdateConnectionInfo(connectionInfo);750                connectionInfo.EnableNetworkAccess = EnableNetworkAccess;751                remoteRunspace = CreateTemporaryRemoteRunspace(this.Host, connectionInfo);752            }753            catch (UriFormatException e)754            {755                WriteErrorCreateRemoteRunspaceFailed(e, ConnectionUri);756            }757            catch (InvalidOperationException e)758            {759                WriteErrorCreateRemoteRunspaceFailed(e, ConnectionUri);760            }761            catch (ArgumentException e)762            {763                WriteErrorCreateRemoteRunspaceFailed(e, ConnectionUri);764            }765            catch (PSRemotingTransportException e)766            {767                WriteErrorCreateRemoteRunspaceFailed(e, ConnectionUri);768            }769            catch (NotSupportedException e)770            {771                WriteErrorCreateRemoteRunspaceFailed(e, ConnectionUri);772            }773 774            return remoteRunspace;775        }776 777        /// <summary>778        /// Get runspace matching condition.779        /// </summary>780        private RemoteRunspace GetRunspaceMatchingCondition(781            Predicate<PSSession> condition,782            PSRemotingErrorId tooFew,783            PSRemotingErrorId tooMany,784            string tooFewResourceString,785            string tooManyResourceString,786            object errorArgument)787        {788            // Find matches.789            List<PSSession> matches = this.RunspaceRepository.Runspaces.FindAll(condition);790 791            // Validate.792            RemoteRunspace remoteRunspace = null;793            if (matches.Count == 0)794            {795                WriteInvalidArgumentError(tooFew, tooFewResourceString, errorArgument);796            }797            else if (matches.Count > 1)798            {799                WriteInvalidArgumentError(tooMany, tooManyResourceString, errorArgument);800            }801            else802            {803                remoteRunspace = (RemoteRunspace)matches[0].Runspace;804                Dbg.Assert(remoteRunspace != null, "Expected remoteRunspace != null");805            }806 807            return remoteRunspace;808        }809 810        /// <summary>811        /// Get runspace matching runspace id.812        /// </summary>813        private RemoteRunspace GetRunspaceMatchingRunspaceId(Guid remoteRunspaceId)814        {815            return GetRunspaceMatchingCondition(816                condition: info => info.InstanceId == remoteRunspaceId,817                tooFew: PSRemotingErrorId.RemoteRunspaceNotAvailableForSpecifiedRunspaceId,818                tooMany: PSRemotingErrorId.RemoteRunspaceHasMultipleMatchesForSpecifiedRunspaceId,819                tooFewResourceString: RemotingErrorIdStrings.RemoteRunspaceNotAvailableForSpecifiedRunspaceId,820                tooManyResourceString: RemotingErrorIdStrings.RemoteRunspaceHasMultipleMatchesForSpecifiedRunspaceId,821                errorArgument: remoteRunspaceId);822        }823 824        /// <summary>825        /// Get runspace matching session id.826        /// </summary>827        private RemoteRunspace GetRunspaceMatchingSessionId(int sessionId)828        {829            return GetRunspaceMatchingCondition(830                condition: info => info.Id == sessionId,831                tooFew: PSRemotingErrorId.RemoteRunspaceNotAvailableForSpecifiedSessionId,832                tooMany: PSRemotingErrorId.RemoteRunspaceHasMultipleMatchesForSpecifiedSessionId,833                tooFewResourceString: RemotingErrorIdStrings.RemoteRunspaceNotAvailableForSpecifiedSessionId,834                tooManyResourceString: RemotingErrorIdStrings.RemoteRunspaceHasMultipleMatchesForSpecifiedSessionId,835                errorArgument: sessionId);836        }837 838        /// <summary>839        /// Get runspace matching name.840        /// </summary>841        private RemoteRunspace GetRunspaceMatchingName(string name)842        {843            return GetRunspaceMatchingCondition(844                condition: info => info.Name.Equals(name, StringComparison.OrdinalIgnoreCase),845                tooFew: PSRemotingErrorId.RemoteRunspaceNotAvailableForSpecifiedName,846                tooMany: PSRemotingErrorId.RemoteRunspaceHasMultipleMatchesForSpecifiedName,847                tooFewResourceString: RemotingErrorIdStrings.RemoteRunspaceNotAvailableForSpecifiedName,848                tooManyResourceString: RemotingErrorIdStrings.RemoteRunspaceHasMultipleMatchesForSpecifiedName,849                errorArgument: name);850        }851 852        private Job FindJobForRunspace(Guid id)853        {854            foreach (var repJob in this.JobRepository.Jobs)855            {856                foreach (Job childJob in repJob.ChildJobs)857                {858                    PSRemotingChildJob remotingChildJob = childJob as PSRemotingChildJob;859 860                    if (remotingChildJob != null &&861                        remotingChildJob.Runspace != null &&862                        remotingChildJob.JobStateInfo.State == JobState.Running &&863                        remotingChildJob.Runspace.InstanceId.Equals(id))864                    {865                        return repJob;866                    }867                }868            }869 870            return null;871        }872 873        private bool IsParameterSetForVM()874        {875            return ((ParameterSetName == VMIdParameterSet) ||876                    (ParameterSetName == VMNameParameterSet));877        }878 879        private bool IsParameterSetForContainer()880        {881            return (ParameterSetName == ContainerIdParameterSet);882        }883 884        /// <summary>885        /// Whether the input is a session object or property that corresponds to886        /// VM or container.887        /// </summary>888        private bool IsParameterSetForVMContainerSession()889        {890            RemoteRunspace remoteRunspace = null;891 892            switch (ParameterSetName)893            {894                case SessionParameterSet:895                    if (this.Session != null)896                    {897                        remoteRunspace = (RemoteRunspace)this.Session.Runspace;898                    }899 900                    break;901 902                case InstanceIdParameterSet:903                    remoteRunspace = GetRunspaceMatchingRunspaceId(this.InstanceId);904                    break;905 906                case IdParameterSet:907                    remoteRunspace = GetRunspaceMatchingSessionId(this.Id);908                    break;909 910                case NameParameterSet:911                    remoteRunspace = GetRunspaceMatchingName(this.Name);912                    break;913 914                default:915                    break;916            }917 918            if ((remoteRunspace != null) &&919                (remoteRunspace.ConnectionInfo != null))920            {921                if ((remoteRunspace.ConnectionInfo is VMConnectionInfo) ||922                    (remoteRunspace.ConnectionInfo is ContainerConnectionInfo))923                {924                    return true;925                }926            }927 928            return false;929        }930 931        /// <summary>932        /// Create runspace for VM session.933        /// </summary>934        private RemoteRunspace GetRunspaceForVMSession()935        {936            RemoteRunspace remoteRunspace = null;937            string command;938            Collection<PSObject> results;939 940            if (ParameterSetName == VMIdParameterSet)941            {942                command = "Get-VM -Id $args[0]";943 944                try945                {946                    results = this.InvokeCommand.InvokeScript(947                        command, false, PipelineResultTypes.None, null, this.VMId);948                }949                catch (CommandNotFoundException)950                {951                    WriteError(952                        new ErrorRecord(953                            new ArgumentException(RemotingErrorIdStrings.HyperVModuleNotAvailable),954                            nameof(PSRemotingErrorId.HyperVModuleNotAvailable),955                            ErrorCategory.NotInstalled,956                            null));957 958                    return null;959                }960 961                if (results.Count != 1)962                {963                    WriteError(964                        new ErrorRecord(965                            new ArgumentException(RemotingErrorIdStrings.InvalidVMId),966                            nameof(PSRemotingErrorId.InvalidVMId),967                            ErrorCategory.InvalidArgument,968                            null));969 970                    return null;971                }972 973                this.VMName = (string)results[0].Properties["VMName"].Value;974            }975            else976            {977                Dbg.Assert(ParameterSetName == VMNameParameterSet, "Expected ParameterSetName == VMName");978 979                command = "Get-VM -Name $args";980 981                try982                {983                    results = this.InvokeCommand.InvokeScript(984                        command, false, PipelineResultTypes.None, null, this.VMName);985                }986                catch (CommandNotFoundException)987                {988                    WriteError(989                        new ErrorRecord(990                            new ArgumentException(RemotingErrorIdStrings.HyperVModuleNotAvailable),991                            nameof(PSRemotingErrorId.HyperVModuleNotAvailable),992                            ErrorCategory.NotInstalled,993                            null));994 995                    return null;996                }997 998                if (results.Count == 0)999                {1000                    WriteError(1001                        new ErrorRecord(1002                            new ArgumentException(RemotingErrorIdStrings.InvalidVMNameNoVM),1003                            nameof(PSRemotingErrorId.InvalidVMNameNoVM),1004                            ErrorCategory.InvalidArgument,1005                            null));1006 1007                    return null;1008                }1009                else if (results.Count > 1)1010                {1011                    WriteError(1012                        new ErrorRecord(1013                            new ArgumentException(RemotingErrorIdStrings.InvalidVMNameMultipleVM),1014                            nameof(PSRemotingErrorId.InvalidVMNameMultipleVM),1015                            ErrorCategory.InvalidArgument,1016                            null));1017 1018                    return null;1019                }1020 1021                this.VMId = (Guid)results[0].Properties["VMId"].Value;1022                this.VMName = (string)results[0].Properties["VMName"].Value;1023            }1024 1025            //1026            // VM should be in running state.1027            //1028            if (GetVMStateProperty(results[0]) != VMState.Running)1029            {1030                WriteError(1031                    new ErrorRecord(1032                        new ArgumentException(GetMessage(RemotingErrorIdStrings.InvalidVMState,1033                                                         this.VMName)),1034                        nameof(PSRemotingErrorId.InvalidVMState),1035                        ErrorCategory.InvalidArgument,1036                        null));1037 1038                return null;1039            }1040 1041            try1042            {1043                VMConnectionInfo connectionInfo;1044                connectionInfo = new VMConnectionInfo(this.Credential, this.VMId, this.VMName, this.ConfigurationName);1045 1046                remoteRunspace = CreateTemporaryRemoteRunspaceForPowerShellDirect(this.Host, connectionInfo);1047            }1048            catch (InvalidOperationException e)1049            {1050                ErrorRecord errorRecord = new ErrorRecord(e,1051                    "CreateRemoteRunspaceForVMFailed",1052                    ErrorCategory.InvalidOperation,1053                    null);1054 1055                WriteError(errorRecord);1056            }1057            catch (ArgumentException e)1058            {1059                ErrorRecord errorRecord = new ErrorRecord(e,1060                    "CreateRemoteRunspaceForVMFailed",1061                    ErrorCategory.InvalidArgument,1062                    null);1063 1064                WriteError(errorRecord);1065            }1066            catch (PSRemotingDataStructureException e)1067            {1068                ErrorRecord errorRecord;1069 1070                //1071                // In case of PSDirectException, we should output the precise error message1072                // in inner exception instead of the generic one in outer exception.1073                //1074                if ((e.InnerException != null) && (e.InnerException is PSDirectException))1075                {1076                    errorRecord = new ErrorRecord(e.InnerException,1077                        "CreateRemoteRunspaceForVMFailed",1078                        ErrorCategory.InvalidArgument,1079                        null);1080                }1081                else1082                {1083                    errorRecord = new ErrorRecord(e,1084                        "CreateRemoteRunspaceForVMFailed",1085                        ErrorCategory.InvalidOperation,1086                        null);1087                }1088 1089                WriteError(errorRecord);1090            }1091            catch (Exception e)1092            {1093                ErrorRecord errorRecord = new ErrorRecord(e,1094                    "CreateRemoteRunspaceForVMFailed",1095                    ErrorCategory.InvalidOperation,1096                    null);1097 1098                WriteError(errorRecord);1099            }1100 1101            return remoteRunspace;1102        }1103 1104        /// <summary>1105        /// Create temporary remote runspace.1106        /// </summary>1107        private static RemoteRunspace CreateTemporaryRemoteRunspaceForPowerShellDirect(PSHost host, RunspaceConnectionInfo connectionInfo)1108        {1109            // Create and open the runspace.1110            TypeTable typeTable = TypeTable.LoadDefaultTypeFiles();1111            RemoteRunspace remoteRunspace = RunspaceFactory.CreateRunspace(connectionInfo, host, typeTable) as RemoteRunspace;1112            remoteRunspace.Name = "PowerShellDirectAttach";1113 1114            Dbg.Assert(remoteRunspace != null, "Expected remoteRunspace != null");1115            try1116            {1117                remoteRunspace.Open();1118 1119                // Mark this temporary runspace so that it closes on pop.1120                remoteRunspace.ShouldCloseOnPop = true;1121            }1122            finally1123            {1124                // Make sure we dispose the temporary runspace if something bad happens.1125                if (remoteRunspace.RunspaceStateInfo.State != RunspaceState.Opened)1126                {1127                    remoteRunspace.Dispose();1128                    remoteRunspace = null;1129                }1130            }1131 1132            return remoteRunspace;1133        }1134 1135        /// <summary>1136        /// Set prompt for VM/Container sessions.1137        /// </summary>1138        private void SetRunspacePrompt(RemoteRunspace remoteRunspace)1139        {1140            if (IsParameterSetForVM() ||1141                IsParameterSetForContainer() ||1142                IsParameterSetForVMContainerSession())1143            {1144                string targetName = string.Empty;1145 1146                switch (ParameterSetName)1147                {1148                    case VMIdParameterSet:1149                    case VMNameParameterSet:1150                        targetName = this.VMName;1151                        break;1152 1153                    case ContainerIdParameterSet:1154                        targetName = (this.ContainerId.Length <= 15) ? this.ContainerId1155                                                                     : this.ContainerId.Remove(14) + PSObjectHelper.Ellipsis;1156                        break;1157 1158                    case SessionParameterSet:1159                        targetName = (this.Session != null) ? this.Session.ComputerName : string.Empty;1160                        break;1161 1162                    case InstanceIdParameterSet:1163                    case IdParameterSet:1164                    case NameParameterSet:1165                        if ((remoteRunspace != null) &&1166                            (remoteRunspace.ConnectionInfo != null))1167                        {1168                            targetName = remoteRunspace.ConnectionInfo.ComputerName;1169                        }1170 1171                        break;1172 1173                    default:1174                        Dbg.Assert(false, "Unrecognized parameter set.");1175                        break;1176                }1177 1178                string promptFn = StringUtil.Format(RemotingErrorIdStrings.EnterVMSessionPrompt,1179                    @"function global:prompt { """,1180                    targetName,1181                    @"PS $($executionContext.SessionState.Path.CurrentLocation)> "" }");1182 1183                // Set prompt in pushed named pipe runspace.1184                using (System.Management.Automation.PowerShell ps = System.Management.Automation.PowerShell.Create())1185                {1186                    ps.Runspace = remoteRunspace;1187 1188                    try1189                    {1190                        // Set pushed runspace prompt.1191                        ps.AddScript(promptFn).Invoke();1192                    }1193                    catch (Exception)1194                    {1195                    }1196                }1197            }1198 1199            return;1200        }

Showing the first 1,200 of 1401 lines. Download the file for the rest.