Team Ai
Datasetpublic

MegaBites-AI/Windows-powershell

sourceHugging Facemitupdated 6mo agoView on Hugging Face
0likes372downloads
newrunspacecommand.cs1486 linesDownload Raw Back to commands
1// Copyright (c) Microsoft Corporation.2// Licensed under the MIT License.3 4using System;5using System.Collections.Generic;6using System.Collections.ObjectModel;7using System.Diagnostics.CodeAnalysis;8using System.Management.Automation;9using System.Management.Automation.Internal;10using System.Management.Automation.Remoting;11using System.Management.Automation.Remoting.Client;12using System.Management.Automation.Runspaces;13using System.Management.Automation.Runspaces.Internal;14using System.Threading;15 16using Dbg = System.Management.Automation.Diagnostics;17 18namespace Microsoft.PowerShell.Commands19{20    /// <summary>21    /// This cmdlet establishes a new Runspace either on the local machine or22    /// on the specified remote machine(s). The runspace established can be used23    /// to invoke expressions remotely.24    ///25    /// The cmdlet can be used in the following ways:26    ///27    /// Open a local runspace28    /// $rs = New-PSSession29    ///30    /// Open a runspace to a remote system.31    /// $rs = New-PSSession -Machine PowerShellWorld32    ///33    /// Create a runspace specifying that it is globally scoped.34    /// $global:rs = New-PSSession -Machine PowerShellWorld35    ///36    /// Create a collection of runspaces37    /// $runspaces = New-PSSession -Machine PowerShellWorld,PowerShellPublish,PowerShellRepo38    ///39    /// Create a set of Runspaces using the Secure Socket Layer by specifying the URI form.40    /// This assumes that an shell by the name of E12 exists on the remote server.41    ///     $serverURIs = 1..8 | ForEach-Object { "SSL://server${_}:443/E12" }42    ///     $rs = New-PSSession -URI $serverURIs43    ///44    /// Create a runspace by connecting to port 8081 on servers s1, s2 and s345    /// $rs = New-PSSession -computername s1,s2,s3 -port 808146    ///47    /// Create a runspace by connecting to port 443 using ssl on servers s1, s2 and s348    /// $rs = New-PSSession -computername s1,s2,s3 -port 443 -useSSL49    ///50    /// Create a runspace by connecting to port 8081 on server s1 and run shell named E12.51    /// This assumes that a shell by the name E12 exists on the remote server52    /// $rs = New-PSSession -computername s1 -port 8061 -ShellName E12.53    /// </summary>54    [Cmdlet(VerbsCommon.New, "PSSession", DefaultParameterSetName = "ComputerName",55        HelpUri = "https://go.microsoft.com/fwlink/?LinkID=2096484", RemotingCapability = RemotingCapability.OwnedByCommand)]56    [OutputType(typeof(PSSession))]57    public class NewPSSessionCommand : PSRemotingBaseCmdlet, IDisposable58    {59        #region Parameters60 61        /// <summary>62        /// This parameter represents the address(es) of the remote63        /// computer(s). The following formats are supported:64        ///      (a) Computer name65        ///      (b) IPv4 address : 132.3.4.566        ///      (c) IPv6 address: 3ffe:8311:ffff:f70f:0:5efe:172.30.162.18.67        /// </summary>68        [Parameter(Position = 0,69                   ValueFromPipeline = true,70                   ValueFromPipelineByPropertyName = true,71                   ParameterSetName = NewPSSessionCommand.ComputerNameParameterSet)]72        [Alias("Cn")]73        [ValidateNotNullOrEmpty]74        public override string[] ComputerName { get; set; }75 76        /// <summary>77        /// Specifies the credentials of the user to impersonate in the78        /// remote machine. If this parameter is not specified then the79        /// credentials of the current user process will be assumed.80        /// </summary>81        [Parameter(ValueFromPipelineByPropertyName = true,82                   ParameterSetName = PSRemotingBaseCmdlet.ComputerNameParameterSet)]83        [Parameter(ValueFromPipelineByPropertyName = true,84                   ParameterSetName = PSRemotingBaseCmdlet.UriParameterSet)]85        [Parameter(Mandatory = true,86                   ValueFromPipelineByPropertyName = true,87                   ParameterSetName = PSRemotingBaseCmdlet.VMIdParameterSet)]88        [Parameter(Mandatory = true,89                   ValueFromPipelineByPropertyName = true,90                   ParameterSetName = PSRemotingBaseCmdlet.VMNameParameterSet)]91        [Credential]92        public override PSCredential Credential93        {94            get95            {96                return base.Credential;97            }98 99            set100            {101                base.Credential = value;102            }103        }104 105        /// <summary>106        /// The PSSession object describing the remote runspace107        /// using which the specified cmdlet operation will be performed.108        /// </summary>109        [Parameter(Position = 0,110                   ValueFromPipelineByPropertyName = true,111                   ValueFromPipeline = true,112                   ParameterSetName = NewPSSessionCommand.SessionParameterSet)]113        [ValidateNotNullOrEmpty]114        public override PSSession[] Session115        {116            get117            {118                return _remoteRunspaceInfos;119            }120 121            set122            {123                _remoteRunspaceInfos = value;124            }125        }126 127        private PSSession[] _remoteRunspaceInfos;128 129        /// <summary>130        /// Friendly names for the new PSSessions.131        /// </summary>132        [Parameter]133        [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]134        public string[] Name { get; set; }135 136        /// <summary>137        /// When set and in loopback scenario (localhost) this enables creation of WSMan138        /// host process with the user interactive token, allowing PowerShell script network access,139        /// i.e., allows going off box.  When this property is true and a PSSession is disconnected,140        /// reconnection is allowed only if reconnecting from a PowerShell session on the same box.141        /// </summary>142        [Parameter(ParameterSetName = NewPSSessionCommand.ComputerNameParameterSet)]143        [Parameter(ParameterSetName = NewPSSessionCommand.SessionParameterSet)]144        [Parameter(ParameterSetName = NewPSSessionCommand.UriParameterSet)]145        public SwitchParameter EnableNetworkAccess { get; set; }146 147        /// <summary>148        /// For WSMan sessions:149        /// If this parameter is not specified then the value specified in150        /// the environment variable DEFAULTREMOTESHELLNAME will be used. If151        /// this is not set as well, then Microsoft.PowerShell is used.152        ///153        /// For VM/Container sessions:154        /// If this parameter is not specified then no configuration is used.155        /// </summary>156        [Parameter(ValueFromPipelineByPropertyName = true,157                   ParameterSetName = NewPSSessionCommand.ComputerNameParameterSet)]158        [Parameter(ValueFromPipelineByPropertyName = true,159                   ParameterSetName = NewPSSessionCommand.UriParameterSet)]160        [Parameter(ValueFromPipelineByPropertyName = true,161                   ParameterSetName = NewPSSessionCommand.ContainerIdParameterSet)]162        [Parameter(ValueFromPipelineByPropertyName = true,163                   ParameterSetName = NewPSSessionCommand.VMIdParameterSet)]164        [Parameter(ValueFromPipelineByPropertyName = true,165                   ParameterSetName = NewPSSessionCommand.VMNameParameterSet)]166        public string ConfigurationName { get; set; }167 168        /// <summary>169        /// Gets or sets parameter value that creates connection to a Windows PowerShell process.170        /// </summary>171        [Parameter(Mandatory = true, ParameterSetName = NewPSSessionCommand.UseWindowsPowerShellParameterSet)]172        public SwitchParameter UseWindowsPowerShell { get; set; }173 174        #endregion Parameters175 176        #region Cmdlet Overrides177 178        /// <summary>179        /// The throttle limit will be set here as it needs to be done180        /// only once per cmdlet and not for every call.181        /// </summary>182        protected override void BeginProcessing()183        {184            base.BeginProcessing();185            _operationsComplete.Reset();186            _throttleManager.ThrottleLimit = ThrottleLimit;187            _throttleManager.ThrottleComplete += HandleThrottleComplete;188 189            if (string.IsNullOrEmpty(ConfigurationName))190            {191                if ((ParameterSetName == NewPSSessionCommand.ComputerNameParameterSet) ||192                    (ParameterSetName == NewPSSessionCommand.UriParameterSet))193                {194                    // set to default value for WSMan session195                    ConfigurationName = ResolveShell(null);196                }197                else198                {199                    // convert null to string.Empty for VM/Container session200                    ConfigurationName = string.Empty;201                }202            }203        }204 205        /// <summary>206        /// The runspace objects will be created using OpenAsync.207        /// At the end, the method will check if any runspace208        /// opened has already become available. If so, then it209        /// will be written to the pipeline.210        /// </summary>211        protected override void ProcessRecord()212        {213            List<RemoteRunspace> remoteRunspaces = null;214            List<IThrottleOperation> operations = new List<IThrottleOperation>();215 216            switch (ParameterSetName)217            {218                case NewPSSessionCommand.SessionParameterSet:219                    {220                        remoteRunspaces = CreateRunspacesWhenRunspaceParameterSpecified();221                    }222 223                    break;224 225                case "Uri":226                    {227                        remoteRunspaces = CreateRunspacesWhenUriParameterSpecified();228                    }229 230                    break;231 232                case NewPSSessionCommand.ComputerNameParameterSet:233                    {234                        remoteRunspaces = CreateRunspacesWhenComputerNameParameterSpecified();235                    }236 237                    break;238 239                case NewPSSessionCommand.VMIdParameterSet:240                case NewPSSessionCommand.VMNameParameterSet:241                    {242                        remoteRunspaces = CreateRunspacesWhenVMParameterSpecified();243                    }244 245                    break;246 247                case NewPSSessionCommand.ContainerIdParameterSet:248                    {249                        remoteRunspaces = CreateRunspacesWhenContainerParameterSpecified();250                    }251 252                    break;253 254                case NewPSSessionCommand.SSHHostParameterSet:255                    {256                        remoteRunspaces = CreateRunspacesForSSHHostParameterSet();257                    }258 259                    break;260 261                case NewPSSessionCommand.SSHHostHashParameterSet:262                    {263                        remoteRunspaces = CreateRunspacesForSSHHostHashParameterSet();264                    }265 266                    break;267 268                case NewPSSessionCommand.UseWindowsPowerShellParameterSet:269                    {270                        if (UseWindowsPowerShell)271                        {272                            remoteRunspaces = CreateRunspacesForUseWindowsPowerShellParameterSet();273                        }274                        else275                        {276                            // When -UseWindowsPowerShell:$false is explicitly specified,277                            // fall back to the default ComputerName parameter set behavior278                            goto case NewPSSessionCommand.ComputerNameParameterSet;279                        }280                    }281 282                    break;283 284                default:285                    {286                        Dbg.Assert(false, "Missing parameter set in switch statement");287                        remoteRunspaces = new List<RemoteRunspace>(); // added to avoid prefast warning288                    }289 290                    break;291            }292 293            foreach (RemoteRunspace remoteRunspace in remoteRunspaces)294            {295                remoteRunspace.Events.ReceivedEvents.PSEventReceived += OnRunspacePSEventReceived;296 297                OpenRunspaceOperation operation = new OpenRunspaceOperation(remoteRunspace);298                // HandleRunspaceStateChanged callback is added before ThrottleManager complete299                // callback handlers so HandleRunspaceStateChanged will always be called first.300                operation.OperationComplete += HandleRunspaceStateChanged;301                remoteRunspace.URIRedirectionReported += HandleURIDirectionReported;302                operations.Add(operation);303            }304 305            // submit list of operations to throttle manager to start opening306            // runspaces307            _throttleManager.SubmitOperations(operations);308 309            // Add to list for clean up.310            _allOperations.Add(operations);311 312            // If there are any runspaces opened asynchronously313            // that are ready now, check their status and do314            // necessary action. If there are any error records315            // or verbose messages write them as well316            Collection<object> streamObjects =317                _stream.ObjectReader.NonBlockingRead();318 319            foreach (object streamObject in streamObjects)320            {321                WriteStreamObject((Action<Cmdlet>)streamObject);322            }323        }324 325        /// <summary>326        /// OpenAsync would have been called from ProcessRecord. This method327        /// will wait until all runspaces are opened and then write them to328        /// the pipeline as and when they become available.329        /// </summary>330        protected override void EndProcessing()331        {332            // signal to throttle manager end of submit operations333            _throttleManager.EndSubmitOperations();334 335            while (true)336            {337                // Keep reading objects until end of pipeline is encountered338                _stream.ObjectReader.WaitHandle.WaitOne();339 340                if (!_stream.ObjectReader.EndOfPipeline)341                {342                    object streamObject = _stream.ObjectReader.Read();343                    WriteStreamObject((Action<Cmdlet>)streamObject);344                }345                else346                {347                    break;348                }349            }350        }351 352        /// <summary>353        /// This method is called when the user sends a stop signal to the354        /// cmdlet. The cmdlet will not exit until it has completed355        /// creating all the runspaces (basically the runspaces its356        /// waiting on OpenAsync is made available). However, when a stop357        /// signal is sent, CloseAsyn needs to be called to close all the358        /// pending runspaces.359        /// </summary>360        /// <remarks>This is called from a separate thread so need to worry361        /// about concurrency issues362        /// </remarks>363        protected override void StopProcessing()364        {365            // close the outputStream so that further writes to the outputStream366            // are not possible367            _stream.ObjectWriter.Close();368 369            // for all the runspaces that have been submitted for opening370            // call StopOperation on each object and quit371            _throttleManager.StopAllOperations();372        }373 374        #endregion Cmdlet Overrides375 376        #region IDisposable Overrides377 378        /// <summary>379        /// Dispose method of IDisposable. Gets called in the following cases:380        ///     1. Pipeline explicitly calls dispose on cmdlets381        ///     2. Called by the garbage collector.382        /// </summary>383        public void Dispose()384        {385            Dispose(true);386 387            GC.SuppressFinalize(this);388        }389 390        #endregion IDisposable Overrides391 392        #region Private Methods393 394        /// <summary>395        /// Adds forwarded events to the local queue.396        /// </summary>397        private void OnRunspacePSEventReceived(object sender, PSEventArgs e) => this.Events?.AddForwardedEvent(e);398 399        /// <summary>400        /// When the client remote session reports a URI redirection, this method will report the401        /// message to the user as a Warning using Host method calls.402        /// </summary>403        /// <param name="sender"></param>404        /// <param name="eventArgs"></param>405        private void HandleURIDirectionReported(object sender, RemoteDataEventArgs<Uri> eventArgs)406        {407            string message = StringUtil.Format(RemotingErrorIdStrings.URIRedirectWarningToHost, eventArgs.Data.OriginalString);408            Action<Cmdlet> warningWriter = (Cmdlet cmdlet) => cmdlet.WriteWarning(message);409            _stream.Write(warningWriter);410        }411 412        /// <summary>413        /// Handles state changes for Runspace.414        /// </summary>415        /// <param name="sender">Sender of this event.</param>416        /// <param name="stateEventArgs">Event information object which describes417        /// the event which triggered this method</param>418        private void HandleRunspaceStateChanged(object sender, OperationStateEventArgs stateEventArgs)419        {420            if (sender == null)421            {422                throw PSTraceSource.NewArgumentNullException(nameof(sender));423            }424 425            if (stateEventArgs == null)426            {427                throw PSTraceSource.NewArgumentNullException(nameof(stateEventArgs));428            }429 430            RunspaceStateEventArgs runspaceStateEventArgs =431                        stateEventArgs.BaseEvent as RunspaceStateEventArgs;432            RunspaceStateInfo stateInfo = runspaceStateEventArgs.RunspaceStateInfo;433            RunspaceState state = stateInfo.State;434            OpenRunspaceOperation operation = sender as OpenRunspaceOperation;435            RemoteRunspace remoteRunspace = operation.OperatedRunspace;436 437            // since we got state changed event..we dont need to listen on438            // URI redirections anymore439            if (remoteRunspace != null)440            {441                remoteRunspace.URIRedirectionReported -= HandleURIDirectionReported;442            }443 444            PipelineWriter writer = _stream.ObjectWriter;445            Exception reason = runspaceStateEventArgs.RunspaceStateInfo.Reason;446 447            switch (state)448            {449                case RunspaceState.Opened:450                    {451                        // Indicates that runspace is successfully opened452                        // Write it to PipelineWriter to be handled in453                        // HandleRemoteRunspace454                        PSSession remoteRunspaceInfo = new PSSession(remoteRunspace);455 456                        this.RunspaceRepository.Add(remoteRunspaceInfo);457 458                        Action<Cmdlet> outputWriter = (Cmdlet cmdlet) => cmdlet.WriteObject(remoteRunspaceInfo);459                        if (writer.IsOpen)460                        {461                            writer.Write(outputWriter);462                        }463                    }464 465                    break;466 467                case RunspaceState.Broken:468                    {469                        // Open resulted in a broken state. Extract reason470                        // and write an error record471 472                        // set the transport message in the error detail so that473                        // the user can directly get to see the message without474                        // having to mine through the error record details475                        PSRemotingTransportException transException =476                            reason as PSRemotingTransportException;477                        string errorDetails = null;478                        int transErrorCode = 0;479                        if (transException != null)480                        {481                            OpenRunspaceOperation senderAsOp = sender as OpenRunspaceOperation;482                            transErrorCode = transException.ErrorCode;483                            if (senderAsOp != null)484                            {485                                string host = senderAsOp.OperatedRunspace.ConnectionInfo.ComputerName;486 487                                if (transException.ErrorCode ==488                                    System.Management.Automation.Remoting.Client.WSManNativeApi.ERROR_WSMAN_REDIRECT_REQUESTED)489                                {490                                    // Handling a special case for redirection..we should talk about491                                    // AllowRedirection parameter and WSManMaxRedirectionCount preference492                                    // variables493                                    string message = PSRemotingErrorInvariants.FormatResourceString(494                                        RemotingErrorIdStrings.URIRedirectionReported,495                                        transException.Message,496                                        "MaximumConnectionRedirectionCount",497                                        Microsoft.PowerShell.Commands.PSRemotingBaseCmdlet.DEFAULT_SESSION_OPTION,498                                        "AllowRedirection");499 500                                    errorDetails = "[" + host + "] " + message;501                                }502                                else503                                {504                                    errorDetails = "[" + host + "] ";505                                    if (!string.IsNullOrEmpty(transException.Message))506                                    {507                                        errorDetails += transException.Message;508                                    }509                                    else if (!string.IsNullOrEmpty(transException.TransportMessage))510                                    {511                                        errorDetails += transException.TransportMessage;512                                    }513                                }514                            }515                        }516 517                        // add host identification information in data structure handler message518                        PSRemotingDataStructureException protoException = reason as PSRemotingDataStructureException;519 520                        if (protoException != null)521                        {522                            OpenRunspaceOperation senderAsOp = sender as OpenRunspaceOperation;523 524                            if (senderAsOp != null)525                            {526                                string host = senderAsOp.OperatedRunspace.ConnectionInfo.ComputerName;527 528                                errorDetails = "[" + host + "] " + protoException.Message;529                            }530                        }531 532                        reason ??= new RuntimeException(this.GetMessage(RemotingErrorIdStrings.RemoteRunspaceOpenUnknownState, state));533 534                        string fullyQualifiedErrorId = WSManTransportManagerUtils.GetFQEIDFromTransportError(535                            transErrorCode,536                            _defaultFQEID);537 538                        if (transErrorCode == WSManNativeApi.ERROR_WSMAN_NO_LOGON_SESSION_EXIST)539                        {540                            errorDetails += System.Environment.NewLine + string.Format(System.Globalization.CultureInfo.CurrentCulture, RemotingErrorIdStrings.RemotingErrorNoLogonSessionExist);541                        }542 543                        ErrorRecord errorRecord = new ErrorRecord(reason,544                             remoteRunspace, fullyQualifiedErrorId,545                                   ErrorCategory.OpenError, null, null,546                                        null, null, null, errorDetails, null);547 548                        Action<Cmdlet> errorWriter = (Cmdlet cmdlet) =>549                        {550                            //551                            // In case of PSDirectException, we should output the precise error message552                            // in inner exception instead of the generic one in outer exception.553                            //554                            if ((errorRecord.Exception != null) &&555                                (errorRecord.Exception.InnerException != null))556                            {557                                PSDirectException ex = errorRecord.Exception.InnerException as PSDirectException;558                                if (ex != null)559                                {560                                    errorRecord = new ErrorRecord(errorRecord.Exception.InnerException,561                                                                  errorRecord.FullyQualifiedErrorId,562                                                                  errorRecord.CategoryInfo.Category,563                                                                  errorRecord.TargetObject);564                                }565                            }566 567                            cmdlet.WriteError(errorRecord);568                        };569                        if (writer.IsOpen)570                        {571                            writer.Write(errorWriter);572                        }573 574                        _toDispose.Add(remoteRunspace);575                    }576 577                    break;578 579                case RunspaceState.Closed:580                    {581                        // The runspace was closed possibly because the user582                        // hit ctrl-C when runspaces were being opened or Dispose has been583                        // called when there are open runspaces584                        Uri connectionUri = WSManConnectionInfo.ExtractPropertyAsWsManConnectionInfo<Uri>(remoteRunspace.ConnectionInfo,585                            "ConnectionUri", null);586                        string message =587                            GetMessage(RemotingErrorIdStrings.RemoteRunspaceClosed,588                                        (connectionUri != null) ?589                                        connectionUri.AbsoluteUri : string.Empty);590 591                        Action<Cmdlet> verboseWriter = (Cmdlet cmdlet) => cmdlet.WriteVerbose(message);592                        if (writer.IsOpen)593                        {594                            writer.Write(verboseWriter);595                        }596 597                        // runspace may not have been opened in certain cases598                        // like when the max memory is set to 25MB, in such599                        // cases write an error record600                        if (reason != null)601                        {602                            ErrorRecord errorRecord = new ErrorRecord(reason,603                                 "PSSessionStateClosed",604                                       ErrorCategory.OpenError, remoteRunspace);605 606                            Action<Cmdlet> errorWriter = (Cmdlet cmdlet) => cmdlet.WriteError(errorRecord);607                            if (writer.IsOpen)608                            {609                                writer.Write(errorWriter);610                            }611                        }612                    }613 614                    break;615            }616        }617 618        /// <summary>619        /// Creates the remote runspace objects when PSSession620        /// parameter is specified621        /// It now supports PSSession based on VM/container connection info as well.622        /// </summary>623        [SuppressMessage("Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly")]624        private List<RemoteRunspace> CreateRunspacesWhenRunspaceParameterSpecified()625        {626            List<RemoteRunspace> remoteRunspaces = new List<RemoteRunspace>();627 628            // validate the runspaces specified before processing them.629            // The function will result in terminating errors, if any630            // validation failure is encountered631            ValidateRemoteRunspacesSpecified();632 633            int rsIndex = 0;634            foreach (PSSession remoteRunspaceInfo in _remoteRunspaceInfos)635            {636                if (remoteRunspaceInfo == null || remoteRunspaceInfo.Runspace == null)637                {638                    ThrowTerminatingError(new ErrorRecord(639                        new ArgumentNullException("PSSession"), "PSSessionArgumentNull",640                            ErrorCategory.InvalidArgument, null));641                }642                else643                {644                    // clone the object based on what's specified in the input parameter645                    try646                    {647                        RemoteRunspace remoteRunspace = (RemoteRunspace)remoteRunspaceInfo.Runspace;648                        RunspaceConnectionInfo newConnectionInfo = null;649 650                        if (remoteRunspace.ConnectionInfo is VMConnectionInfo)651                        {652                            newConnectionInfo = remoteRunspace.ConnectionInfo.Clone();653                        }654                        else if (remoteRunspace.ConnectionInfo is ContainerConnectionInfo)655                        {656                            ContainerConnectionInfo newContainerConnectionInfo = remoteRunspace.ConnectionInfo.Clone() as ContainerConnectionInfo;657                            newContainerConnectionInfo.CreateContainerProcess();658                            newConnectionInfo = newContainerConnectionInfo;659                        }660                        else661                        {662                            // WSMan case663                            WSManConnectionInfo originalWSManConnectionInfo = remoteRunspace.ConnectionInfo as WSManConnectionInfo;664                            WSManConnectionInfo newWSManConnectionInfo = null;665 666                            if (originalWSManConnectionInfo != null)667                            {668                                newWSManConnectionInfo = originalWSManConnectionInfo.Copy();669                                newWSManConnectionInfo.EnableNetworkAccess = newWSManConnectionInfo.EnableNetworkAccess || EnableNetworkAccess;670                                newConnectionInfo = newWSManConnectionInfo;671                            }672                            else673                            {674                                Uri connectionUri = WSManConnectionInfo.ExtractPropertyAsWsManConnectionInfo<Uri>(remoteRunspace.ConnectionInfo,675                                            "ConnectionUri", null);676                                string shellUri = WSManConnectionInfo.ExtractPropertyAsWsManConnectionInfo<string>(remoteRunspace.ConnectionInfo,677                                    "ShellUri", string.Empty);678                                newWSManConnectionInfo = new WSManConnectionInfo(connectionUri,679                                                                shellUri,680                                                                remoteRunspace.ConnectionInfo.Credential);681                                UpdateConnectionInfo(newWSManConnectionInfo);682                                newWSManConnectionInfo.EnableNetworkAccess = EnableNetworkAccess;683                                newConnectionInfo = newWSManConnectionInfo;684                            }685                        }686 687                        RemoteRunspacePoolInternal rrsPool = remoteRunspace.RunspacePool.RemoteRunspacePoolInternal;688                        TypeTable typeTable = null;689                        if ((rrsPool != null) &&690                            (rrsPool.DataStructureHandler != null) &&691                            (rrsPool.DataStructureHandler.TransportManager != null))692                        {693                            typeTable = rrsPool.DataStructureHandler.TransportManager.Fragmentor.TypeTable;694                        }695 696                        // Create new remote runspace with name and Id.697                        int rsId;698                        string rsName = GetRunspaceName(rsIndex, out rsId);699                        RemoteRunspace newRemoteRunspace = new RemoteRunspace(700                            typeTable, newConnectionInfo, this.Host, this.SessionOption.ApplicationArguments,701                            rsName, rsId);702 703                        remoteRunspaces.Add(newRemoteRunspace);704                    }705                    catch (UriFormatException e)706                    {707                        PipelineWriter writer = _stream.ObjectWriter;708 709                        ErrorRecord errorRecord = new ErrorRecord(e, "CreateRemoteRunspaceFailed",710                                ErrorCategory.InvalidArgument, remoteRunspaceInfo);711 712                        Action<Cmdlet> errorWriter = (Cmdlet cmdlet) => cmdlet.WriteError(errorRecord);713                        writer.Write(errorWriter);714                    }715                }716 717                ++rsIndex;718            }719 720            return remoteRunspaces;721        }722 723        /// <summary>724        /// Creates the remote runspace objects when the URI parameter725        /// is specified.726        /// </summary>727        private List<RemoteRunspace> CreateRunspacesWhenUriParameterSpecified()728        {729            List<RemoteRunspace> remoteRunspaces = new List<RemoteRunspace>();730 731            // parse the Uri to obtain information about the runspace732            // required733            for (int i = 0; i < ConnectionUri.Length; i++)734            {735                try736                {737                    WSManConnectionInfo connectionInfo = new WSManConnectionInfo();738                    connectionInfo.ConnectionUri = ConnectionUri[i];739                    connectionInfo.ShellUri = ConfigurationName;740                    if (CertificateThumbprint != null)741                    {742                        connectionInfo.CertificateThumbprint = CertificateThumbprint;743                    }744                    else745                    {746                        connectionInfo.Credential = Credential;747                    }748 749                    connectionInfo.AuthenticationMechanism = Authentication;750                    UpdateConnectionInfo(connectionInfo);751 752                    connectionInfo.EnableNetworkAccess = EnableNetworkAccess;753 754                    // Create new remote runspace with name and Id.755                    int rsId;756                    string rsName = GetRunspaceName(i, out rsId);757                    RemoteRunspace remoteRunspace = new RemoteRunspace(758                        Utils.GetTypeTableFromExecutionContextTLS(), connectionInfo, this.Host,759                        this.SessionOption.ApplicationArguments, rsName, rsId);760 761                    Dbg.Assert(remoteRunspace != null,762                            "RemoteRunspace object created using URI is null");763 764                    remoteRunspaces.Add(remoteRunspace);765                }766                catch (UriFormatException e)767                {768                    WriteErrorCreateRemoteRunspaceFailed(e, ConnectionUri[i]);769                }770                catch (InvalidOperationException e)771                {772                    WriteErrorCreateRemoteRunspaceFailed(e, ConnectionUri[i]);773                }774                catch (ArgumentException e)775                {776                    WriteErrorCreateRemoteRunspaceFailed(e, ConnectionUri[i]);777                }778                catch (NotSupportedException e)779                {780                    WriteErrorCreateRemoteRunspaceFailed(e, ConnectionUri[i]);781                }782            }783 784            return remoteRunspaces;785        }786 787        /// <summary>788        /// Creates the remote runspace objects when the ComputerName parameter789        /// is specified.790        /// </summary>791        private List<RemoteRunspace> CreateRunspacesWhenComputerNameParameterSpecified()792        {793            List<RemoteRunspace> remoteRunspaces =794                new List<RemoteRunspace>();795 796            // Resolve all the machine names797            string[] resolvedComputerNames;798 799            ResolveComputerNames(ComputerName, out resolvedComputerNames);800 801            ValidateComputerName(resolvedComputerNames);802 803            // Do for each machine804            for (int i = 0; i < resolvedComputerNames.Length; i++)805            {806                try807                {808                    WSManConnectionInfo connectionInfo = null;809                    connectionInfo = new WSManConnectionInfo();810                    string scheme = UseSSL.IsPresent ? WSManConnectionInfo.HttpsScheme : WSManConnectionInfo.HttpScheme;811                    connectionInfo.ComputerName = resolvedComputerNames[i];812                    connectionInfo.Port = Port;813                    connectionInfo.AppName = ApplicationName;814                    connectionInfo.ShellUri = ConfigurationName;815                    connectionInfo.Scheme = scheme;816                    if (CertificateThumbprint != null)817                    {818                        connectionInfo.CertificateThumbprint = CertificateThumbprint;819                    }820                    else821                    {822                        connectionInfo.Credential = Credential;823                    }824 825                    connectionInfo.AuthenticationMechanism = Authentication;826                    UpdateConnectionInfo(connectionInfo);827 828                    connectionInfo.EnableNetworkAccess = EnableNetworkAccess;829 830                    // Create new remote runspace with name and Id.831                    int rsId;832                    string rsName = GetRunspaceName(i, out rsId);833                    RemoteRunspace runspace = new RemoteRunspace(834                        Utils.GetTypeTableFromExecutionContextTLS(), connectionInfo, this.Host,835                        this.SessionOption.ApplicationArguments, rsName, rsId);836 837                    remoteRunspaces.Add(runspace);838                }839                catch (UriFormatException e)840                {841                    PipelineWriter writer = _stream.ObjectWriter;842 843                    ErrorRecord errorRecord = new ErrorRecord(e, "CreateRemoteRunspaceFailed",844                            ErrorCategory.InvalidArgument, resolvedComputerNames[i]);845 846                    Action<Cmdlet> errorWriter = (Cmdlet cmdlet) => cmdlet.WriteError(errorRecord);847                    writer.Write(errorWriter);848                }849            }850 851            return remoteRunspaces;852        }853 854        /// <summary>855        /// Creates the remote runspace objects when the VMId or VMName parameter856        /// is specified.857        /// </summary>858        private List<RemoteRunspace> CreateRunspacesWhenVMParameterSpecified()859        {860            int inputArraySize;861            bool isVMIdSet = false;862            int index;863            string command;864            Collection<PSObject> results;865            List<RemoteRunspace> remoteRunspaces = new List<RemoteRunspace>();866 867            if (ParameterSetName == PSExecutionCmdlet.VMIdParameterSet)868            {869                isVMIdSet = true;870                inputArraySize = this.VMId.Length;871                this.VMName = new string[inputArraySize];872                command = "Get-VM -Id $args[0]";873            }874            else875            {876                Dbg.Assert((ParameterSetName == PSExecutionCmdlet.VMNameParameterSet),877                           "Expected ParameterSetName == VMId or VMName");878 879                inputArraySize = this.VMName.Length;880                this.VMId = new Guid[inputArraySize];881                command = "Get-VM -Name $args";882            }883 884            for (index = 0; index < inputArraySize; index++)885            {886                try887                {888                    results = this.InvokeCommand.InvokeScript(889                        command, false, PipelineResultTypes.None, null,890                        isVMIdSet ? this.VMId[index].ToString() : this.VMName[index]);891                }892                catch (CommandNotFoundException)893                {894                    ThrowTerminatingError(895                        new ErrorRecord(896                            new ArgumentException(RemotingErrorIdStrings.HyperVModuleNotAvailable),897                            nameof(PSRemotingErrorId.HyperVModuleNotAvailable),898                            ErrorCategory.NotInstalled,899                            null));900 901                    return null;902                }903 904                // handle invalid input905                if (results.Count != 1)906                {907                    if (isVMIdSet)908                    {909                        this.VMName[index] = string.Empty;910 911                        WriteError(912                            new ErrorRecord(913                                new ArgumentException(GetMessage(RemotingErrorIdStrings.InvalidVMIdNotSingle,914                                                                 this.VMId[index].ToString(null))),915                                nameof(PSRemotingErrorId.InvalidVMIdNotSingle),916                                ErrorCategory.InvalidArgument,917                                null));918 919                        continue;920                    }921                    else922                    {923                        this.VMId[index] = Guid.Empty;924 925                        WriteError(926                            new ErrorRecord(927                                new ArgumentException(GetMessage(RemotingErrorIdStrings.InvalidVMNameNotSingle,928                                                                 this.VMName[index])),929                                nameof(PSRemotingErrorId.InvalidVMNameNotSingle),930                                ErrorCategory.InvalidArgument,931                                null));932 933                        continue;934                    }935                }936                else937                {938                    this.VMId[index] = (Guid)results[0].Properties["VMId"].Value;939                    this.VMName[index] = (string)results[0].Properties["VMName"].Value;940 941                    //942                    // VM should be in running state.943                    //944                    if (GetVMStateProperty(results[0]) != VMState.Running)945                    {946                        WriteError(947                            new ErrorRecord(948                                new ArgumentException(GetMessage(RemotingErrorIdStrings.InvalidVMState,949                                                                 this.VMName[index])),950                                nameof(PSRemotingErrorId.InvalidVMState),951                                ErrorCategory.InvalidArgument,952                                null));953 954                        continue;955                    }956                }957 958                // create helper objects for VM GUIDs or names959                RemoteRunspace runspace = null;960                VMConnectionInfo connectionInfo;961                int rsId;962                string rsName = GetRunspaceName(index, out rsId);963 964                try965                {966                    connectionInfo = new VMConnectionInfo(this.Credential, this.VMId[index], this.VMName[index], this.ConfigurationName);967 968                    runspace = new RemoteRunspace(Utils.GetTypeTableFromExecutionContextTLS(),969                        connectionInfo, this.Host, null, rsName, rsId);970 971                    remoteRunspaces.Add(runspace);972                }973                catch (InvalidOperationException e)974                {975                    ErrorRecord errorRecord = new ErrorRecord(e,976                        "CreateRemoteRunspaceForVMFailed",977                        ErrorCategory.InvalidOperation,978                        null);979 980                    WriteError(errorRecord);981                }982                catch (ArgumentException e)983                {984                    ErrorRecord errorRecord = new ErrorRecord(e,985                        "CreateRemoteRunspaceForVMFailed",986                        ErrorCategory.InvalidArgument,987                        null);988 989                    WriteError(errorRecord);990                }991            }992 993            ResolvedComputerNames = this.VMName;994 995            return remoteRunspaces;996        }997 998        /// <summary>999        /// Creates the remote runspace objects when the ContainerId parameter is specified.1000        /// </summary>1001        private List<RemoteRunspace> CreateRunspacesWhenContainerParameterSpecified()1002        {1003            int index = 0;1004            List<string> resolvedNameList = new List<string>();1005            List<RemoteRunspace> remoteRunspaces = new List<RemoteRunspace>();1006 1007            Dbg.Assert((ParameterSetName == PSExecutionCmdlet.ContainerIdParameterSet),1008                       "Expected ParameterSetName == ContainerId");1009 1010            foreach (var input in ContainerId)1011            {1012                //1013                // Create helper objects for container ID or name.1014                //1015                RemoteRunspace runspace = null;1016                ContainerConnectionInfo connectionInfo = null;1017                int rsId;1018                string rsName = GetRunspaceName(index, out rsId);1019                index++;1020 1021                try1022                {1023                    //1024                    // Hyper-V container uses Hype-V socket as transport.1025                    // Windows Server container uses named pipe as transport.1026                    //1027                    connectionInfo = ContainerConnectionInfo.CreateContainerConnectionInfo(input, RunAsAdministrator.IsPresent, this.ConfigurationName);1028 1029                    resolvedNameList.Add(connectionInfo.ComputerName);1030 1031                    connectionInfo.CreateContainerProcess();1032 1033                    runspace = new RemoteRunspace(Utils.GetTypeTableFromExecutionContextTLS(),1034                        connectionInfo, this.Host, null, rsName, rsId);1035 1036                    remoteRunspaces.Add(runspace);1037                }1038                catch (InvalidOperationException e)1039                {1040                    ErrorRecord errorRecord = new ErrorRecord(e,1041                        "CreateRemoteRunspaceForContainerFailed",1042                        ErrorCategory.InvalidOperation,1043                        null);1044 1045                    WriteError(errorRecord);1046                    continue;1047                }1048                catch (ArgumentException e)1049                {1050                    ErrorRecord errorRecord = new ErrorRecord(e,1051                        "CreateRemoteRunspaceForContainerFailed",1052                        ErrorCategory.InvalidArgument,1053                        null);1054 1055                    WriteError(errorRecord);1056                    continue;1057                }1058                catch (Exception e)1059                {1060                    ErrorRecord errorRecord = new ErrorRecord(e,1061                        "CreateRemoteRunspaceForContainerFailed",1062                        ErrorCategory.InvalidOperation,1063                        null);1064 1065                    WriteError(errorRecord);1066                    continue;1067                }1068            }1069 1070            ResolvedComputerNames = resolvedNameList.ToArray();1071 1072            return remoteRunspaces;1073        }1074 1075        /// <summary>1076        /// CreateRunspacesForSSHHostParameterSet.1077        /// </summary>1078        /// <returns></returns>1079        private List<RemoteRunspace> CreateRunspacesForSSHHostParameterSet()1080        {1081            // Resolve all the machine names1082            string[] resolvedComputerNames;1083 1084            ResolveComputerNames(HostName, out resolvedComputerNames);1085 1086            var remoteRunspaces = new List<RemoteRunspace>();1087            int index = 0;1088            foreach (var computerName in resolvedComputerNames)1089            {1090                ParseSshHostName(computerName, out string host, out string userName, out int port);1091 1092                var sshConnectionInfo = new SSHConnectionInfo(1093                    userName,1094                    host,1095                    this.KeyFilePath,1096                    port,1097                    Subsystem,1098                    ConnectingTimeout,1099                    Options);1100                var typeTable = TypeTable.LoadDefaultTypeFiles();1101                string rsName = GetRunspaceName(index, out int rsIdUnused);1102                index++;1103                remoteRunspaces.Add(RunspaceFactory.CreateRunspace(connectionInfo: sshConnectionInfo,1104                                                                   host: this.Host,1105                                                                   typeTable: typeTable,1106                                                                   applicationArguments: null,1107                                                                   name: rsName) as RemoteRunspace);1108            }1109 1110            return remoteRunspaces;1111        }1112 1113        private List<RemoteRunspace> CreateRunspacesForSSHHostHashParameterSet()1114        {1115            var sshConnections = ParseSSHConnectionHashTable();1116            var remoteRunspaces = new List<RemoteRunspace>();1117            int index = 0;1118            foreach (var sshConnection in sshConnections)1119            {1120                var sshConnectionInfo = new SSHConnectionInfo(1121                    sshConnection.UserName,1122                    sshConnection.ComputerName,1123                    sshConnection.KeyFilePath,1124                    sshConnection.Port,1125                    sshConnection.Subsystem,1126                    sshConnection.ConnectingTimeout,1127                    sshConnection.Options);1128                var typeTable = TypeTable.LoadDefaultTypeFiles();1129                string rsName = GetRunspaceName(index, out int rsIdUnused);1130                index++;1131                remoteRunspaces.Add(RunspaceFactory.CreateRunspace(connectionInfo: sshConnectionInfo,1132                                                                   host: this.Host,1133                                                                   typeTable: typeTable,1134                                                                   applicationArguments: null,1135                                                                   name: rsName) as RemoteRunspace);1136            }1137 1138            return remoteRunspaces;1139        }1140 1141        /// <summary>1142        /// Helper method to create remote runspace based on UseWindowsPowerShell parameter set.1143        /// </summary>1144        /// <returns>Remote runspace that was created.</returns>1145        private List<RemoteRunspace> CreateRunspacesForUseWindowsPowerShellParameterSet()1146        {1147            var remoteRunspaces = new List<RemoteRunspace>();1148 1149            NewProcessConnectionInfo connectionInfo = new NewProcessConnectionInfo(this.Credential);1150            connectionInfo.AuthenticationMechanism = this.Authentication;1151#if !UNIX1152            connectionInfo.PSVersion = new Version(5, 1);1153#endif1154            var typeTable = TypeTable.LoadDefaultTypeFiles();1155            string runspaceName = GetRunspaceName(0, out int runspaceIdUnused);1156            remoteRunspaces.Add(RunspaceFactory.CreateRunspace(connectionInfo: connectionInfo,1157                                                               host: this.Host,1158                                                               typeTable: typeTable,1159                                                               applicationArguments: null,1160                                                               name: runspaceName) as RemoteRunspace);1161            return remoteRunspaces;1162        }1163 1164        /// <summary>1165        /// Helper method to either get a user supplied runspace/session name1166        /// or to generate one along with a unique Id.1167        /// </summary>1168        /// <param name="rsIndex">Runspace name array index.</param>1169        /// <param name="rsId">Runspace Id.</param>1170        /// <returns>Runspace name.</returns>1171        private string GetRunspaceName(int rsIndex, out int rsId)1172        {1173            // Get a unique session/runspace Id and default Name.1174            string rsName = PSSession.GenerateRunspaceName(out rsId);1175 1176            // If there is a friendly name for the runspace, we need to pass it to the1177            // runspace pool object, which in turn passes it on to the server during1178            // construction.  This way the friendly name can be returned when querying1179            // the sever for disconnected sessions/runspaces.1180            if (Name != null && rsIndex < Name.Length)1181            {1182                rsName = Name[rsIndex];1183            }1184 1185            return rsName;1186        }1187 1188        /// <summary>1189        /// Internal dispose method which does the actual1190        /// dispose operations and finalize suppressions.1191        /// </summary>1192        /// <param name="disposing">Whether method is called1193        /// from Dispose or destructor</param>1194        protected void Dispose(bool disposing)1195        {1196            if (disposing)1197            {1198                _throttleManager.Dispose();1199 1200                // wait for all runspace operations to be complete

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