/// <summary> /// Create pipeline. /// </summary> internal Pipeline CreatePipeline(string line, bool addToHistory, bool useNestedPipelines) { // This method allows input commands to work against no-language runspaces. If a runspace // is pushed, it tries to parse the line using a ScriptBlock object. If a runspace is not // pushed, or if the parsing fails, in these cases it reverts to calling CreatePipeline // using the unparsed line. Pipeline pipeline = null; // In Start-PSSession scenario try to create a pipeline by parsing the line as a script block. if (this.IsRunspaceOverridden) { // Win8: exit should work to escape from the restrictive session if ((_runspaceRef.Value is RemoteRunspace) && (!string.IsNullOrEmpty(line) && string.Equals(line.Trim(), "exit", StringComparison.OrdinalIgnoreCase))) { line = "Exit-PSSession"; } PSCommand psCommand = ParsePsCommandUsingScriptBlock(line, null); if (psCommand != null) { pipeline = useNestedPipelines ? _runspaceRef.Value.CreateNestedPipeline(psCommand.Commands[0].CommandText, addToHistory) : _runspaceRef.Value.CreatePipeline(psCommand.Commands[0].CommandText, addToHistory); pipeline.Commands.Clear(); foreach (Command command in psCommand.Commands) { pipeline.Commands.Add(command); } } } // If that didn't work out fall-back to the traditional approach. if (pipeline is null) { pipeline = useNestedPipelines ? _runspaceRef.Value.CreateNestedPipeline(line, addToHistory) : _runspaceRef.Value.CreatePipeline(line, addToHistory); } // Add robust connection callback if this is a pushed runspace. RemotePipeline remotePipeline = pipeline as RemotePipeline; if (this.IsRunspaceOverridden && remotePipeline != null) { PowerShell shell = remotePipeline.PowerShell; if (shell.RemotePowerShell != null) { shell.RemotePowerShell.RCConnectionNotification += HandleRCConnectionNotification; } // Add callback to write robust connection errors from stream. shell.ErrorBuffer.DataAdded += (sender, eventArgs) => { RemoteRunspace remoteRunspace = _runspaceRef.Value as RemoteRunspace; PSDataCollection <ErrorRecord> erBuffer = sender as PSDataCollection <ErrorRecord>; if (remoteRunspace != null && erBuffer != null && remoteRunspace.RunspacePool.RemoteRunspacePoolInternal.Host != null) { Collection <ErrorRecord> erRecords = erBuffer.ReadAll(); foreach (var er in erRecords) { remoteRunspace.RunspacePool.RemoteRunspacePoolInternal.Host.UI.WriteErrorLine(er.ToString()); } } }; } pipeline.SetHistoryString(line); return(pipeline); }
private void ConnectSessionToHost(PSSession session, PSRemotingJob job = null) { RemoteRunspace runspace = session.Runspace as RemoteRunspace; if (job != null) { lock (this._syncObject) { this._job = job; } using (job) { Job job2 = job.ChildJobs[0]; job.ConnectJobs(); do { job2.Results.WaitHandle.WaitOne(); foreach (PSStreamObject obj2 in job2.ReadAll()) { if (obj2 != null) { obj2.WriteStreamObject(this, false); } } }while (!job.IsFinishedState(job.JobStateInfo.State)); } lock (this._syncObject) { this._job = null; } } else if (runspace.RemoteCommand != null) { lock (this._syncObject) { this._remotePipeline = (RemotePipeline)session.Runspace.CreateDisconnectedPipeline(); } using (this._remotePipeline) { this._remotePipeline.ConnectAsync(); runspace.RunspacePool.RemoteRunspacePoolInternal.ConnectCommands = null; while (!this._remotePipeline.Output.EndOfPipeline) { if (this._stopProcessing) { break; } this._remotePipeline.Output.WaitHandle.WaitOne(); while (this._remotePipeline.Output.Count > 0) { if (this._stopProcessing) { continue; } PSObject psObject = this._remotePipeline.Output.Read(); this.WriteRemoteObject(psObject, session); } } if (this._remotePipeline.Error.Count > 0) { while (!this._remotePipeline.Error.EndOfPipeline) { object obj4 = this._remotePipeline.Error.Read(); if (obj4 is Collection <ErrorRecord> ) { Collection <ErrorRecord> collection = (Collection <ErrorRecord>)obj4; foreach (ErrorRecord record in collection) { base.WriteError(record); } } else if (obj4 is ErrorRecord) { base.WriteError((ErrorRecord)obj4); } } } this._remotePipeline.PipelineFinishedEvent.WaitOne(); if (this._remotePipeline.PipelineStateInfo.State == PipelineState.Failed) { string pipelineFailedWithoutReason; Exception reason = this._remotePipeline.PipelineStateInfo.Reason; if ((reason != null) && !string.IsNullOrEmpty(reason.Message)) { pipelineFailedWithoutReason = StringUtil.Format(RemotingErrorIdStrings.PipelineFailedWithReason, reason.Message); } else { pipelineFailedWithoutReason = RemotingErrorIdStrings.PipelineFailedWithoutReason; } ErrorRecord errorRecord = new ErrorRecord(new RuntimeException(pipelineFailedWithoutReason, reason), "ReceivePSSessionPipelineFailed", ErrorCategory.OperationStopped, this._remotePipeline); base.WriteError(errorRecord); } } lock (this._syncObject) { this._remotePipeline = null; } } }