internal static void Dispatch(BaseClientTransportManager transportManager, PSHost clientHost, PSDataCollectionStream<ErrorRecord> errorStream, ObjectStream methodExecutorStream, bool isMethodExecutorStreamEnabled, RemoteRunspacePoolInternal runspacePool, Guid clientPowerShellId, System.Management.Automation.Remoting.RemoteHostCall remoteHostCall) { ClientMethodExecutor executor = new ClientMethodExecutor(transportManager, clientHost, runspacePool.InstanceId, clientPowerShellId, remoteHostCall); if (clientPowerShellId == Guid.Empty) { executor.Execute(errorStream); } else { bool flag = false; if (clientHost != null) { PSObject privateData = clientHost.PrivateData; if (privateData != null) { PSNoteProperty property = privateData.Properties["AllowSetShouldExitFromRemote"] as PSNoteProperty; flag = ((property != null) && (property.Value is bool)) ? ((bool) property.Value) : false; } } if ((remoteHostCall.IsSetShouldExit && isMethodExecutorStreamEnabled) && !flag) { runspacePool.Close(); } else if (isMethodExecutorStreamEnabled) { methodExecutorStream.Write(executor); } else { executor.Execute(errorStream); } } }
/// <summary> /// Create a pipeline initialized with a command string /// </summary> /// <param name="runspace">The associated Runspace/>.</param> /// <param name="command">command string</param> /// <param name="addToHistory">if true, add pipeline to history</param> /// <param name="isNested">True for nested pipeline</param> /// <exception cref="ArgumentNullException"> /// Command is null and add to history is true /// </exception> protected PipelineBase(Runspace runspace, string command, bool addToHistory, bool isNested) : base(runspace) { Initialize(runspace, command, addToHistory, isNested); //Initialize streams InputStream = new ObjectStream(); OutputStream = new ObjectStream(); ErrorStream = new ObjectStream(); }
internal void Start() { this.processOutput = new ObjectStream(0x80); lock (this.readerLock) { if (this.redirectOutput) { this.readerCount++; this.outputReader = new ProcessStreamReader(this.process.StandardOutput, this.processPath, true, this.processOutput.ObjectWriter, this); this.outputReader.Start(); } if (this.redirectError) { this.readerCount++; this.errorReader = new ProcessStreamReader(this.process.StandardError, this.processPath, false, this.processOutput.ObjectWriter, this); this.errorReader.Start(); } } }
public ObjectReader([In, Out] ObjectStream stream) : base((ObjectStreamBase)stream) { }
internal Collection<PSSession> GetDisconnectedSessions(Collection<WSManConnectionInfo> connectionInfos, PSHost host, ObjectStream stream, RunspaceRepository runspaceRepository, int throttleLimit, SessionFilterState filterState, Guid[] matchIds, string[] matchNames, string configurationName) { Collection<PSSession> collection = new Collection<PSSession>(); foreach (WSManConnectionInfo info in connectionInfos) { Runspace[] runspaceArray = null; try { runspaceArray = Runspace.GetRunspaces(info, host, BuiltInTypesTable); } catch (RuntimeException exception) { if (!(exception.InnerException is InvalidOperationException)) { throw; } if ((stream.ObjectWriter != null) && stream.ObjectWriter.IsOpen) { int num; string message = StringUtil.Format(RemotingErrorIdStrings.QueryForRunspacesFailed, info.ComputerName, ExtractMessage(exception.InnerException, out num)); string fQEIDFromTransportError = WSManTransportManagerUtils.GetFQEIDFromTransportError(num, "RemotePSSessionQueryFailed"); Exception exception2 = new RuntimeException(message, exception.InnerException); ErrorRecord errorRecord = new ErrorRecord(exception2, fQEIDFromTransportError, ErrorCategory.InvalidOperation, info); stream.ObjectWriter.Write(errorRecord); /* stream.ObjectWriter.Write(delegate (Cmdlet cmdlet) { cmdlet.WriteError(errorRecord); }); */ } } if (this.stopProcessing) { break; } if (runspaceArray != null) { string str3 = null; if (!string.IsNullOrEmpty(configurationName)) { str3 = (configurationName.IndexOf("http://schemas.microsoft.com/powershell/", StringComparison.OrdinalIgnoreCase) != -1) ? configurationName : ("http://schemas.microsoft.com/powershell/" + configurationName); } foreach (Runspace runspace in runspaceArray) { if (str3 != null) { WSManConnectionInfo connectionInfo = runspace.ConnectionInfo as WSManConnectionInfo; if ((connectionInfo != null) && !str3.Equals(connectionInfo.ShellUri, StringComparison.OrdinalIgnoreCase)) { continue; } } PSSession item = null; if (runspaceRepository != null) { item = runspaceRepository.GetItem(runspace.InstanceId); } if ((item != null) && UseExistingRunspace(item.Runspace, runspace)) { if (this.TestRunspaceState(item.Runspace, filterState)) { collection.Add(item); } } else if (this.TestRunspaceState(runspace, filterState)) { collection.Add(new PSSession(runspace as RemoteRunspace)); } } } } if ((matchIds != null) && (collection.Count > 0)) { Collection<PSSession> collection2 = new Collection<PSSession>(); foreach (Guid guid in matchIds) { bool flag = false; foreach (PSSession session2 in collection) { if (this.stopProcessing) { break; } if (session2.Runspace.InstanceId.Equals(guid)) { flag = true; collection2.Add(session2); break; } } if ((!flag && (stream.ObjectWriter != null)) && stream.ObjectWriter.IsOpen) { Exception exception3 = new RuntimeException(StringUtil.Format(RemotingErrorIdStrings.SessionIdMatchFailed, guid)); ErrorRecord errorRecord = new ErrorRecord(exception3, "PSSessionIdMatchFail", ErrorCategory.InvalidOperation, guid); stream.ObjectWriter.Write(errorRecord); /* stream.ObjectWriter.Write(delegate (Cmdlet cmdlet) { cmdlet.WriteError(errorRecord); }); */ } } return collection2; } if ((matchNames == null) || (collection.Count <= 0)) { return collection; } Collection<PSSession> collection3 = new Collection<PSSession>(); foreach (string str5 in matchNames) { WildcardPattern pattern = new WildcardPattern(str5, WildcardOptions.IgnoreCase); bool flag2 = false; foreach (PSSession session3 in collection) { if (this.stopProcessing) { break; } if (pattern.IsMatch(((RemoteRunspace) session3.Runspace).RunspacePool.RemoteRunspacePoolInternal.Name)) { flag2 = true; collection3.Add(session3); } } if ((!flag2 && (stream.ObjectWriter != null)) && stream.ObjectWriter.IsOpen) { Exception exception4 = new RuntimeException(StringUtil.Format(RemotingErrorIdStrings.SessionNameMatchFailed, str5)); ErrorRecord errorRecord = new ErrorRecord(exception4, "PSSessionNameMatchFail", ErrorCategory.InvalidOperation, str5); stream.ObjectWriter.Write(errorRecord); /* stream.ObjectWriter.Write(delegate (Cmdlet cmdlet) { cmdlet.WriteError(errorRecord); }); */ } } return collection3; }
internal DisconnectRunspaceOperation(PSSession session, ObjectStream stream) { _remoteSession = session; _writeStream = stream; _remoteSession.Runspace.StateChanged += StateCallBackHandler; }
internal DisconnectRunspaceOperation(PSSession session, ObjectStream stream) { this.remoteSession = session; this.writeStream = stream; this.remoteSession.Runspace.StateChanged += new EventHandler<RunspaceStateEventArgs>(this.StateCallBackHandler); }
/// <summary> /// Create temporary remote runspace. /// </summary> private RemoteRunspace CreateTemporaryRemoteRunspace(PSHost host, WSManConnectionInfo connectionInfo) { // Create and open the runspace. int rsId; string rsName = PSSession.GenerateRunspaceName(out rsId); RemoteRunspace remoteRunspace = new RemoteRunspace( Utils.GetTypeTableFromExecutionContextTLS(), connectionInfo, host, this.SessionOption.ApplicationArguments, rsName, rsId); Dbg.Assert(remoteRunspace != null, "Expected remoteRunspace != null"); remoteRunspace.URIRedirectionReported += HandleURIDirectionReported; _stream = new ObjectStream(); try { remoteRunspace.Open(); // Mark this temporary runspace so that it closes on pop. remoteRunspace.ShouldCloseOnPop = true; } finally { // unregister uri redirection handler remoteRunspace.URIRedirectionReported -= HandleURIDirectionReported; // close the internal object stream after runspace is opened // Runspace.Open() might throw exceptions..this will make sure // the stream is always closed. _stream.ObjectWriter.Close(); // make sure we dispose the temporary runspace if something bad happens if (remoteRunspace.RunspaceStateInfo.State != RunspaceState.Opened) { remoteRunspace.Dispose(); remoteRunspace = null; } } return remoteRunspace; }
internal ConnectRunspaceOperation( PSSession session, ObjectStream stream, PSHost host, QueryRunspaces queryRunspaces, Collection<PSSession> retryList) { _session = session; _writeStream = stream; _host = host; _queryRunspaces = queryRunspaces; _retryList = retryList; _session.Runspace.StateChanged += StateCallBackHandler; }
internal ConnectRunspaceOperation(PSSession session, ObjectStream stream, PSHost host, QueryRunspaces queryRunspaces, Collection<PSSession> retryList) { this._session = session; this._writeStream = stream; this._host = host; this._queryRunspaces = queryRunspaces; this._retryList = retryList; this._session.Runspace.StateChanged += new EventHandler<RunspaceStateEventArgs>(this.StateCallBackHandler); }
private RemoteRunspace CreateTemporaryRemoteRunspace(PSHost host, WSManConnectionInfo connectionInfo) { int num; string name = PSSession.GenerateRunspaceName(out num); RemoteRunspace runspace = new RemoteRunspace(Utils.GetTypeTableFromExecutionContextTLS(), connectionInfo, host, this.SessionOption.ApplicationArguments, name, num); runspace.URIRedirectionReported += new EventHandler<RemoteDataEventArgs<Uri>>(this.HandleURIDirectionReported); this.stream = new ObjectStream(); try { runspace.Open(); runspace.ShouldCloseOnPop = true; } finally { runspace.URIRedirectionReported -= new EventHandler<RemoteDataEventArgs<Uri>>(this.HandleURIDirectionReported); this.stream.ObjectWriter.Close(); if (runspace.RunspaceStateInfo.State != RunspaceState.Opened) { runspace.Dispose(); runspace = null; } } return runspace; }
/// <summary> /// Private constructor that does most of the work constructing a remote pipeline object. /// </summary> /// <param name="runspace">RemoteRunspace object</param> /// <param name="addToHistory">AddToHistory</param> /// <param name="isNested">IsNested</param> private RemotePipeline(RemoteRunspace runspace, bool addToHistory, bool isNested) : base(runspace) { _addToHistory = addToHistory; _isNested = isNested; _isSteppable = false; _runspace = runspace; _computerName = ((RemoteRunspace)_runspace).ConnectionInfo.ComputerName; _runspaceId = _runspace.InstanceId; //Initialize streams _inputCollection = new PSDataCollection<object>(); _inputCollection.ReleaseOnEnumeration = true; _inputStream = new PSDataCollectionStream<object>(Guid.Empty, _inputCollection); _outputCollection = new PSDataCollection<PSObject>(); _outputStream = new PSDataCollectionStream<PSObject>(Guid.Empty, _outputCollection); _errorCollection = new PSDataCollection<ErrorRecord>(); _errorStream = new PSDataCollectionStream<ErrorRecord>(Guid.Empty, _errorCollection); // Create object stream for method executor objects. MethodExecutorStream = new ObjectStream(); IsMethodExecutorStreamEnabled = false; SetCommandCollection(_commands); //Create event which will be signalled when pipeline execution //is completed/failed/stoped. //Note:Runspace.Close waits for all the running pipeline //to finish. This Event must be created before pipeline is //added to list of running pipelines. This avoids the race condition //where Close is called after pipeline is added to list of //running pipeline but before event is created. PipelineFinishedEvent = new ManualResetEvent(false); }
/// <summary> /// Create a new ClientMethodExecutor object and then dispatch it. /// </summary> internal static void Dispatch( BaseClientTransportManager transportManager, PSHost clientHost, PSDataCollectionStream<ErrorRecord> errorStream, ObjectStream methodExecutorStream, bool isMethodExecutorStreamEnabled, RemoteRunspacePoolInternal runspacePool, Guid clientPowerShellId, RemoteHostCall remoteHostCall) { ClientMethodExecutor methodExecutor = new ClientMethodExecutor(transportManager, clientHost, runspacePool.InstanceId, clientPowerShellId, remoteHostCall); // If the powershell id is not specified, this message is for the runspace pool, execute // it immediately and return if (clientPowerShellId == Guid.Empty) { methodExecutor.Execute(errorStream); return; } // Check client host to see if SetShouldExit should be allowed bool hostAllowSetShouldExit = false; if (clientHost != null) { PSObject hostPrivateData = clientHost.PrivateData as PSObject; if (hostPrivateData != null) { PSNoteProperty allowSetShouldExit = hostPrivateData.Properties["AllowSetShouldExitFromRemote"] as PSNoteProperty; hostAllowSetShouldExit = (allowSetShouldExit != null && allowSetShouldExit.Value is bool) ? (bool)allowSetShouldExit.Value : false; } } // Should we kill remote runspace? Check if "SetShouldExit" and if we are in the // cmdlet case. In the API case (when we are invoked from an API not a cmdlet) we // should not interpret "SetShouldExit" but should pass it on to the host. The // variable IsMethodExecutorStreamEnabled is only true in the cmdlet case. In the // API case it is false. if (remoteHostCall.IsSetShouldExit && isMethodExecutorStreamEnabled && !hostAllowSetShouldExit) { runspacePool.Close(); return; } // Cmdlet case: queue up the executor in the pipeline stream. if (isMethodExecutorStreamEnabled) { Dbg.Assert(!isMethodExecutorStreamEnabled || (isMethodExecutorStreamEnabled && methodExecutorStream != null), "method executor stream can't be null when enabled"); methodExecutorStream.Write(methodExecutor); } // API case: execute it immediately. else { methodExecutor.Execute(errorStream); } }
private RemotePipeline(RemoteRunspace runspace, bool addToHistory, bool isNested) : base(runspace) { this._syncRoot = new object(); this._pipelineStateInfo = new System.Management.Automation.Runspaces.PipelineStateInfo(PipelineState.NotStarted); this._commands = new CommandCollection(); this._executionEventQueue = new Queue<ExecutionEventQueueItem>(); this._performNestedCheck = true; this._addToHistory = addToHistory; this._isNested = isNested; this._isSteppable = false; this._runspace = runspace; this._computerName = ((RemoteRunspace) this._runspace).ConnectionInfo.ComputerName; this._runspaceId = this._runspace.InstanceId; this._inputCollection = new PSDataCollection<object>(); this._inputCollection.ReleaseOnEnumeration = true; this._inputStream = new PSDataCollectionStream<object>(Guid.Empty, this._inputCollection); this._outputCollection = new PSDataCollection<PSObject>(); this._outputStream = new PSDataCollectionStream<PSObject>(Guid.Empty, this._outputCollection); this._errorCollection = new PSDataCollection<ErrorRecord>(); this._errorStream = new PSDataCollectionStream<ErrorRecord>(Guid.Empty, this._errorCollection); this._methodExecutorStream = new ObjectStream(); this._isMethodExecutorStreamEnabled = false; base.SetCommandCollection(this._commands); this._pipelineFinishedEvent = new ManualResetEvent(false); }
public ObjectReader(ObjectStream stream) : base(stream) { }
/// <summary> /// Start reading the output/error. Note all the work is done asynchronously. /// </summary> internal void Start() { _processOutput = new ObjectStream(128); // Start async reading of error and output // readercount variable is used by multiple threads to close "processOutput" ObjectStream. // Without properly initializing the readercount, the ObjectStream might get // closed early. readerCount is protected here by using the lock. lock (_readerLock) { if (_redirectOutput) { _readerCount++; _outputReader = new ProcessStreamReader(_process.StandardOutput, _processPath, true, _processOutput.ObjectWriter, this); _outputReader.Start(); } if (_redirectError) { _readerCount++; _errorReader = new ProcessStreamReader(_process.StandardError, _processPath, false, _processOutput.ObjectWriter, this); _errorReader.Start(); } } }
/// <summary> /// Queries all remote computers specified in collection of WSManConnectionInfo objects /// and returns disconnected PSSession objects ready for connection to server. /// Returned sessions can be matched to Guids or Names. /// </summary> /// <param name="connectionInfos">Collection of WSManConnectionInfo objects.</param> /// <param name="host">Host for PSSession objects.</param> /// <param name="stream">Out stream object.</param> /// <param name="runspaceRepository">Runspace repository.</param> /// <param name="throttleLimit">Throttle limit.</param> /// <param name="filterState">Runspace state filter value.</param> /// <param name="matchIds">Array of session Guids to match to.</param> /// <param name="matchNames">Array of session Names to match to.</param> /// <param name="configurationName">Configuration name to match to.</param> /// <returns>Collection of disconnected PSSession objects.</returns> internal Collection<PSSession> GetDisconnectedSessions(Collection<WSManConnectionInfo> connectionInfos, PSHost host, ObjectStream stream, RunspaceRepository runspaceRepository, int throttleLimit, SessionFilterState filterState, Guid[] matchIds, string[] matchNames, string configurationName) { Collection<PSSession> filteredPSSesions = new Collection<PSSession>(); // Create a query operation for each connection information object. foreach (WSManConnectionInfo connectionInfo in connectionInfos) { Runspace[] runspaces = null; try { runspaces = Runspace.GetRunspaces(connectionInfo, host, BuiltInTypesTable); } catch (System.Management.Automation.RuntimeException e) { if (e.InnerException is InvalidOperationException) { // The Get-WSManInstance cmdlet used to query remote computers for runspaces will throw // an Invalid Operation (inner) exception if the connectInfo object is invalid, including // invalid computer names. // We don't want to propagate the exception so just write error here. if (stream.ObjectWriter != null && stream.ObjectWriter.IsOpen) { int errorCode; string msg = StringUtil.Format(RemotingErrorIdStrings.QueryForRunspacesFailed, connectionInfo.ComputerName, ExtractMessage(e.InnerException, out errorCode)); string FQEID = WSManTransportManagerUtils.GetFQEIDFromTransportError(errorCode, "RemotePSSessionQueryFailed"); Exception reason = new RuntimeException(msg, e.InnerException); ErrorRecord errorRecord = new ErrorRecord(reason, FQEID, ErrorCategory.InvalidOperation, connectionInfo); stream.ObjectWriter.Write((Action<Cmdlet>)(cmdlet => cmdlet.WriteError(errorRecord))); } } else { throw; } } if (_stopProcessing) { break; } // Add all runspaces meeting filter criteria to collection. if (runspaces != null) { // Convert configuration name into shell Uri for comparison. string shellUri = null; if (!string.IsNullOrEmpty(configurationName)) { shellUri = (configurationName.IndexOf( System.Management.Automation.Remoting.Client.WSManNativeApi.ResourceURIPrefix, StringComparison.OrdinalIgnoreCase) != -1) ? configurationName : System.Management.Automation.Remoting.Client.WSManNativeApi.ResourceURIPrefix + configurationName; } foreach (Runspace runspace in runspaces) { // Filter returned runspaces by ConfigurationName if provided. if (shellUri != null) { // Compare with returned shell Uri in connection info. WSManConnectionInfo wsmanConnectionInfo = runspace.ConnectionInfo as WSManConnectionInfo; if (wsmanConnectionInfo != null && !shellUri.Equals(wsmanConnectionInfo.ShellUri, StringComparison.OrdinalIgnoreCase)) { continue; } } // Check the repository for an existing viable PSSession for // this runspace (based on instanceId). Use the existing // local runspace instead of the one returned from the server // query. PSSession existingPSSession = null; if (runspaceRepository != null) { existingPSSession = runspaceRepository.GetItem(runspace.InstanceId); } if (existingPSSession != null && UseExistingRunspace(existingPSSession.Runspace, runspace)) { if (TestRunspaceState(existingPSSession.Runspace, filterState)) { filteredPSSesions.Add(existingPSSession); } } else if (TestRunspaceState(runspace, filterState)) { filteredPSSesions.Add(new PSSession(runspace as RemoteRunspace)); } } } } // Return only PSSessions that match provided Ids or Names. if ((matchIds != null) && (filteredPSSesions.Count > 0)) { Collection<PSSession> matchIdsSessions = new Collection<PSSession>(); foreach (Guid id in matchIds) { bool matchFound = false; foreach (PSSession psSession in filteredPSSesions) { if (_stopProcessing) { break; } if (psSession.Runspace.InstanceId.Equals(id)) { matchFound = true; matchIdsSessions.Add(psSession); break; } } if (!matchFound && stream.ObjectWriter != null && stream.ObjectWriter.IsOpen) { string msg = StringUtil.Format(RemotingErrorIdStrings.SessionIdMatchFailed, id); Exception reason = new RuntimeException(msg); ErrorRecord errorRecord = new ErrorRecord(reason, "PSSessionIdMatchFail", ErrorCategory.InvalidOperation, id); stream.ObjectWriter.Write((Action<Cmdlet>)(cmdlet => cmdlet.WriteError(errorRecord))); } } // Return all found sessions. return matchIdsSessions; } else if ((matchNames != null) && (filteredPSSesions.Count > 0)) { Collection<PSSession> matchNamesSessions = new Collection<PSSession>(); foreach (string name in matchNames) { WildcardPattern namePattern = WildcardPattern.Get(name, WildcardOptions.IgnoreCase); bool matchFound = false; foreach (PSSession psSession in filteredPSSesions) { if (_stopProcessing) { break; } if (namePattern.IsMatch(((RemoteRunspace)psSession.Runspace).RunspacePool.RemoteRunspacePoolInternal.Name)) { matchFound = true; matchNamesSessions.Add(psSession); } } if (!matchFound && stream.ObjectWriter != null && stream.ObjectWriter.IsOpen) { string msg = StringUtil.Format(RemotingErrorIdStrings.SessionNameMatchFailed, name); Exception reason = new RuntimeException(msg); ErrorRecord errorRecord = new ErrorRecord(reason, "PSSessionNameMatchFail", ErrorCategory.InvalidOperation, name); stream.ObjectWriter.Write((Action<Cmdlet>)(cmdlet => cmdlet.WriteError(errorRecord))); } } return matchNamesSessions; } else { // Return all collected sessions. return filteredPSSesions; } }
/// <summary> /// Construct with an existing ObjectStream. /// </summary> /// <param name="stream">The stream to read.</param> /// <exception cref="ArgumentNullException">Thrown if the specified stream is null.</exception> public PSObjectReader([In, Out] ObjectStream stream) : base(stream) { }
public ConnectPSSessionCommand() { this.allSessions = new Collection<PSSession>(); this.throttleManager = new ThrottleManager(); this.operationsComplete = new ManualResetEvent(true); this.queryRunspaces = new QueryRunspaces(); this.stream = new ObjectStream(); this.retryThrottleManager = new ThrottleManager(); this.failedSessions = new Collection<PSSession>(); }