internal RemoteRunspacePoolInternal(Guid instanceId, string name, bool isDisconnected, ConnectCommandInfo[] connectCommands, RunspaceConnectionInfo connectionInfo, PSHost host, TypeTable typeTable) : base(1, 1)
 {
     this.applicationPrivateDataReceived = new ManualResetEvent(false);
     this.friendlyName = string.Empty;
     if (connectCommands == null)
     {
         throw PSTraceSource.NewArgumentNullException("ConnectCommandInfo[]");
     }
     if (connectionInfo == null)
     {
         throw PSTraceSource.NewArgumentNullException("WSManConnectionInfo");
     }
     if (connectionInfo is WSManConnectionInfo)
     {
         this.connectionInfo = ((WSManConnectionInfo) connectionInfo).Copy();
     }
     base.instanceId = instanceId;
     base.minPoolSz = -1;
     base.maxPoolSz = -1;
     PSEtwLog.LogOperationalVerbose(PSEventId.RunspacePoolConstructor, PSOpcode.Constructor, PSTask.CreateRunspace, PSKeyword.UseAlwaysOperational, new object[] { instanceId.ToString(), this.minPoolSz.ToString(CultureInfo.InvariantCulture), this.maxPoolSz.ToString(CultureInfo.InvariantCulture) });
     this.connectCommands = connectCommands;
     this.Name = name;
     base.host = host;
     this.dispatchTable = new DispatchTable<object>();
     this.SetRunspacePoolState(new RunspacePoolStateInfo(RunspacePoolState.Disconnected, null));
     this.CreateDSHandler(typeTable);
     this.availableForConnection = isDisconnected;
 }
Beispiel #2
0
 internal RemotePipeline(RemoteRunspace runspace) : this(runspace, false, false)
 {
     if (runspace.RemoteCommand == null)
     {
         throw new InvalidOperationException(PipelineStrings.InvalidRemoteCommand);
     }
     this._connectCmdInfo = runspace.RemoteCommand;
     this._commands.Add(this._connectCmdInfo.Command);
     this.SetPipelineState(PipelineState.Disconnected, null);
     this._powershell = new System.Management.Automation.PowerShell(this._connectCmdInfo, this._inputStream, this._outputStream, this._errorStream, ((RemoteRunspace) this._runspace).RunspacePool);
     this._powershell.InvocationStateChanged += new EventHandler<PSInvocationStateChangedEventArgs>(this.HandleInvocationStateChanged);
 }
 internal void ConnectAsync(ConnectCommandInfo connectCmdInfo)
 {
     if (connectCmdInfo == null)
     {
         this.dataStructureHandler.ReconnectAsync();
     }
     else
     {
         this.shell.RunspacePool.RemoteRunspacePoolInternal.AddRemotePowerShellDSHandler(this.InstanceId, this.dataStructureHandler);
         this.dataStructureHandler.ConnectAsync();
     }
 }
Beispiel #4
0
        /// <summary>
        /// Attempts to reconnect or connect to a running command on a remote server,
        /// which will resume events and data collection from the server.
        /// If connectCmdInfo parameter is null then a reconnection is attempted and
        /// it is assumed that the current client state is unchanged since disconnection.
        /// If connectCmdInfo parameter is non-null then a connection is attempted to
        /// the specified remote running command.
        /// This is an asynchronous call and results will be reported in the ReconnectCompleted
        /// or the ConnectCompleted call back as appropriate.
        /// </summary>
        /// <param name="connectCmdInfo">ConnectCommandInfo specifying remote command.</param>
        internal void ConnectAsync(ConnectCommandInfo connectCmdInfo)
        {
            if (connectCmdInfo == null)
            {
                // Attempt to do a reconnect with the current PSRP client state.
                this.dataStructureHandler.ReconnectAsync();
            }
            else
            {
                // First add this command DS handler to the remote runspace pool list.
                Dbg.Assert(this.shell.RunspacePool != null, "Invalid runspace pool for this powershell object.");
                this.shell.RunspacePool.RemoteRunspacePoolInternal.AddRemotePowerShellDSHandler(
                    this.InstanceId, this.dataStructureHandler);

                // Now do the asynchronous connect.
                this.dataStructureHandler.ConnectAsync();
            }
        }
        /// <summary>
        /// Attempts to reconnect or connect to a running command on a remote server, 
        /// which will resume events and data collection from the server.
        /// If connectCmdInfo parameter is null then a reconnection is attempted and
        /// it is assumed that the current client state is unchanged since disconnection.
        /// If connectCmdInfo parameter is non-null then a connection is attempted to
        /// the specified remote running command.
        /// This is an asynchronous call and results will be reported in the ReconnectCompleted
        /// or the ConnectCompleted call back as appropriate.
        /// </summary>
        /// <param name="connectCmdInfo">ConnectCommandInfo specifying remote command.</param>
        internal void ConnectAsync(ConnectCommandInfo connectCmdInfo)
        {
            if (connectCmdInfo == null)
            {
                // Attempt to do a reconnect with the current PSRP client state.
                this.dataStructureHandler.ReconnectAsync();
            }
            else
            {
                // First add this command DS handler to the remote runspace pool list.
                Dbg.Assert(this.shell.RunspacePool != null, "Invalid runspace pool for this powershell object.");
                this.shell.RunspacePool.RemoteRunspacePoolInternal.AddRemotePowerShellDSHandler(
                                            this.InstanceId, this.dataStructureHandler);

                // Now do the asynchronous connect.
                this.dataStructureHandler.ConnectAsync();
            }
        }
Beispiel #6
0
        /// <summary>
        /// Constructs a remote pipeline object associated with a remote running
        /// command but in a disconnected state.
        /// </summary>
        /// <param name="runspace">Remote runspace associated with running command.</param>
        internal RemotePipeline(RemoteRunspace runspace)
            : this(runspace, false, false)
        {
            if (runspace.RemoteCommand == null)
            {
                throw new InvalidOperationException(PipelineStrings.InvalidRemoteCommand);
            }

            _connectCmdInfo = runspace.RemoteCommand;
            _commands.Add(_connectCmdInfo.Command);

            // Beginning state will be disconnected.
            SetPipelineState(PipelineState.Disconnected, null);

            // Create the underlying powershell object.
            _powershell = new PowerShell(_connectCmdInfo, _inputStream, _outputStream, _errorStream,
                ((RemoteRunspace)_runspace).RunspacePool);

            _powershell.InvocationStateChanged +=
                new EventHandler<PSInvocationStateChangedEventArgs>(HandleInvocationStateChanged);
        }
Beispiel #7
0
 private List<PSSession> GetDisconnectedSessions(PSInvokeExpressionSyncJob job)
 {
     List<PSSession> list = new List<PSSession>();
     foreach (PowerShell shell in job.GetPowerShells())
     {
         string cmdStr = ((shell.Commands != null) && (shell.Commands.Commands.Count > 0)) ? shell.Commands.Commands[0].CommandText : string.Empty;
         ConnectCommandInfo info = new ConnectCommandInfo(shell.InstanceId, cmdStr);
         RunspacePool runspacePool = null;
         if (shell.RunspacePool != null)
         {
             runspacePool = shell.RunspacePool;
         }
         else
         {
             object runspaceConnection = shell.GetRunspaceConnection();
             RunspacePool pool2 = runspaceConnection as RunspacePool;
             if (pool2 != null)
             {
                 runspacePool = pool2;
             }
             else
             {
                 RemoteRunspace runspace = runspaceConnection as RemoteRunspace;
                 if (runspace != null)
                 {
                     runspacePool = runspace.RunspacePool;
                 }
             }
         }
         if (runspacePool != null)
         {
             if (runspacePool.RunspacePoolStateInfo.State != RunspacePoolState.Disconnected)
             {
                 if (!base.InvokeAndDisconnect || (runspacePool.RunspacePoolStateInfo.State != RunspacePoolState.Opened))
                 {
                     continue;
                 }
                 runspacePool.Disconnect();
             }
             string name = runspacePool.RemoteRunspacePoolInternal.Name;
             if (string.IsNullOrEmpty(name))
             {
                 int num;
                 name = PSSession.GenerateRunspaceName(out num);
             }
             RunspacePool pool3 = new RunspacePool(true, runspacePool.RemoteRunspacePoolInternal.InstanceId, name, new ConnectCommandInfo[] { info }, runspacePool.RemoteRunspacePoolInternal.ConnectionInfo, base.Host, base.Context.TypeTable);
             RemoteRunspace remoteRunspace = new RemoteRunspace(pool3);
             list.Add(new PSSession(remoteRunspace));
         }
     }
     return list;
 }
Beispiel #8
0
 internal RunspacePool(bool isDisconnected, Guid instanceId, string name, ConnectCommandInfo[] connectCommands, RunspaceConnectionInfo connectionInfo, PSHost host, TypeTable typeTable)
 {
     this.syncObject = new object();
     if (!(connectionInfo is WSManConnectionInfo))
     {
         throw new NotSupportedException();
     }
     this.internalPool = new System.Management.Automation.Runspaces.Internal.RemoteRunspacePoolInternal(instanceId, name, isDisconnected, connectCommands, connectionInfo, host, typeTable);
     this.isRemote = true;
 }
        /// <summary>
        /// Creates a disconnected session for each disconnected PowerShell object in
        /// PSInvokeExpressionSyncJob.
        /// </summary>
        /// <param name="job"></param>
        /// <returns></returns>
        private List<PSSession> GetDisconnectedSessions(PSInvokeExpressionSyncJob job)
        {
            List<PSSession> discSessions = new List<PSSession>();

            Collection<System.Management.Automation.PowerShell> powershells = job.GetPowerShells();
            foreach (System.Management.Automation.PowerShell ps in powershells)
            {
                // Get the command information from the PowerShell object.
                string commandText = (ps.Commands != null && ps.Commands.Commands.Count > 0) ?
                    ps.Commands.Commands[0].CommandText : string.Empty;
                ConnectCommandInfo cmdInfo = new ConnectCommandInfo(ps.InstanceId, commandText);

                // Get the old RunspacePool object that the command was initially run on.
                RunspacePool oldRunspacePool = null;
                if (ps.RunspacePool != null)
                {
                    oldRunspacePool = ps.RunspacePool;
                }
                else
                {
                    object rsConnection = ps.GetRunspaceConnection();
                    RunspacePool rsPool = rsConnection as RunspacePool;
                    if (rsPool != null)
                    {
                        oldRunspacePool = rsPool;
                    }
                    else
                    {
                        RemoteRunspace remoteRs = rsConnection as RemoteRunspace;
                        if (remoteRs != null)
                        {
                            oldRunspacePool = remoteRs.RunspacePool;
                        }
                    }
                }

                // Create a new disconnected PSSession object and return to the user.
                // The user can use this object to connect to the command on the server
                // and retrieve data.
                if (oldRunspacePool != null)
                {
                    if (oldRunspacePool.RunspacePoolStateInfo.State != RunspacePoolState.Disconnected)
                    {
                        // InvokeAndDisconnect starts the command and immediately disconnects the command,
                        // but we need to disconnect the associated runspace/pool here.
                        if (InvokeAndDisconnect && oldRunspacePool.RunspacePoolStateInfo.State == RunspacePoolState.Opened)
                        {
                            oldRunspacePool.Disconnect();
                        }
                        else
                        {
                            // Skip runspace pools that have not been disconnected.
                            continue;
                        }
                    }

                    // Auto-generate a session name if one was not provided.
                    string sessionName = oldRunspacePool.RemoteRunspacePoolInternal.Name;
                    if (string.IsNullOrEmpty(sessionName))
                    {
                        int id;
                        sessionName = PSSession.GenerateRunspaceName(out id);
                    }

                    RunspacePool runspacePool = new RunspacePool(
                                                        true,
                                                        oldRunspacePool.RemoteRunspacePoolInternal.InstanceId,
                                                        sessionName,
                                                        new ConnectCommandInfo[1] { cmdInfo },
                                                        oldRunspacePool.RemoteRunspacePoolInternal.ConnectionInfo,
                                                        this.Host,
                                                        this.Context.TypeTable);
                    runspacePool.RemoteRunspacePoolInternal.IsRemoteDebugStop = oldRunspacePool.RemoteRunspacePoolInternal.IsRemoteDebugStop;

                    RemoteRunspace remoteRunspace = new RemoteRunspace(runspacePool);
                    discSessions.Add(new PSSession(remoteRunspace));
                }
            }

            return discSessions;
        }
        /// <summary>
        /// Create a runspacepool object in the disconnected state.
        /// </summary>
        /// <param name="instanceId">Identifies remote session to connect.</param>
        /// <param name="name">Friendly name for runspace pool.</param>
        /// <param name="isDisconnected">Indicates whether the runspacepool is disconnected.</param>
        /// <param name="connectCommands">Array of commands associated with this runspace pool.</param>
        /// <param name="connectionInfo">Connection information for remote server.</param>
        /// <param name="host">PSHost object.</param>
        /// <param name="typeTable">TypeTable for object serialization/deserialization.</param>
        internal RemoteRunspacePoolInternal(Guid instanceId, string name, bool isDisconnected,
            ConnectCommandInfo[] connectCommands, RunspaceConnectionInfo connectionInfo, PSHost host, TypeTable typeTable)
            : base(1, 1)
        {
            if (instanceId == null)
            {
                throw PSTraceSource.NewArgumentNullException("RunspacePool Guid");
            }
            if (connectCommands == null)
            {
                throw PSTraceSource.NewArgumentNullException("ConnectCommandInfo[]");
            }
            if (connectionInfo == null)
            {
                throw PSTraceSource.NewArgumentNullException("WSManConnectionInfo");
            }

            if (connectionInfo is WSManConnectionInfo)
            {
                _connectionInfo = connectionInfo.InternalCopy();
            }
            else
            {
                Dbg.Assert(false, "ConnectionInfo must be WSManConnectionInfo");
            }

            // Create the runspace pool object to have the same instanceId as the remote session.
            this.instanceId = instanceId;

            // This indicates that this is a disconnected remote runspace pool and min/max values
            // are currently unknown. These values will be updated once the object is connected.
            this.minPoolSz = -1;
            this.maxPoolSz = -1;

            PSEtwLog.LogOperationalVerbose(PSEventId.RunspacePoolConstructor,
                    PSOpcode.Constructor, PSTask.CreateRunspace,
                    PSKeyword.UseAlwaysOperational,
                    instanceId.ToString(),
                    minPoolSz.ToString(CultureInfo.InvariantCulture),
                    maxPoolSz.ToString(CultureInfo.InvariantCulture));

            ConnectCommands = connectCommands;
            this.Name = name;
            this.host = host;
            DispatchTable = new DispatchTable<object>();
            _runningPowerShells = new System.Collections.Concurrent.ConcurrentStack<PowerShell>();

            // Create this object in the disconnected state.
            SetRunspacePoolState(new RunspacePoolStateInfo(RunspacePoolState.Disconnected, null));

            CreateDSHandler(typeTable);

            AvailableForConnection = isDisconnected;
        }
Beispiel #11
0
 internal void ConnectAsync(ConnectCommandInfo connectCmdInfo)
 {
     if (connectCmdInfo == null)
     {
         this.dataStructureHandler.ReconnectAsync();
     }
     else
     {
         this.shell.RunspacePool.RemoteRunspacePoolInternal.AddRemotePowerShellDSHandler(this.InstanceId, this.dataStructureHandler);
         this.dataStructureHandler.ConnectAsync();
     }
 }
Beispiel #12
0
        /// <summary>
        /// Creates a runspace pool object in a disconnected state that is
        /// ready to connect to a remote runspace pool session specified by
        /// the instanceId parameter.
        /// </summary>
        /// <param name="isDisconnected">Indicates whether the shell/runspace pool is disconnected.</param>
        /// <param name="instanceId">Identifies a remote runspace pool session to connect to.</param>
        /// <param name="name">Friendly name for runspace pool.</param>
        /// <param name="connectCommands">Runspace pool running commands information.</param>
        /// <param name="connectionInfo">Connection information of remote server.</param>
        /// <param name="host">PSHost object.</param>
        /// <param name="typeTable">TypeTable used for serialization/deserialization of remote objects.</param>
        internal RunspacePool(
            bool isDisconnected,
            Guid instanceId,
            string name,
            ConnectCommandInfo[] connectCommands,
            RunspaceConnectionInfo connectionInfo,
            PSHost host,
            TypeTable typeTable)
        {
            // Disconnect-Connect semantics are currently only supported in WSMan transport.
            if (!(connectionInfo is WSManConnectionInfo))
            {
                throw new NotSupportedException();
            }

            _internalPool = new RemoteRunspacePoolInternal(instanceId, name, isDisconnected, connectCommands,
                connectionInfo, host, typeTable);

            IsRemote = true;
        }