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; }
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(); } }
/// <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> /// 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); }
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; }
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; }
/// <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; }