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; } } }
/// <summary> /// Connects session, retrieves command output data and writes to host. /// </summary> /// <param name="session">PSSession object.</param> /// <param name="job">Job object associated with session.</param> private void ConnectSessionToHost(PSSession session, PSRemotingJob job = null) { RemoteRunspace remoteRunspace = session.Runspace as RemoteRunspace; Dbg.Assert(remoteRunspace != null, "PS sessions can only contain RemoteRunspace type."); if (job != null) { // If we have a job object associated with the session then this means // the user explicitly chose to connect and return data synchronously. // Reconnect the job object and stream data to host. lock (_syncObject) { _job = job; _stopPipelineReceive = new ManualResetEvent(false); } using (_stopPipelineReceive) using (job) { Job childJob = job.ChildJobs[0]; job.ConnectJobs(); if (CheckForDebugMode(session, true)) { return; } do { // Retrieve and display results from child job as they become // available. int index = WaitHandle.WaitAny(new WaitHandle[] { _stopPipelineReceive, childJob.Results.WaitHandle }); foreach (var result in childJob.ReadAll()) { if (result != null) { result.WriteStreamObject(this); } } if (index == 0) { WriteDebugStopWarning(); return; } } while (!job.IsFinishedState(job.JobStateInfo.State)); } lock (_syncObject) { _job = null; _stopPipelineReceive = null; } return; } // Otherwise this must be a new disconnected session object that has a running command // associated with it. if (remoteRunspace.RemoteCommand == null) { // There is no associated running command for this runspace, so we cannot proceed. // Check to see if session is in debug mode. CheckForDebugMode(session, false); return; } // Create a RemotePipeline object for this command and attempt to connect. lock (_syncObject) { _remotePipeline = (RemotePipeline)session.Runspace.CreateDisconnectedPipeline(); _stopPipelineReceive = new ManualResetEvent(false); } using (_stopPipelineReceive) { using (_remotePipeline) { // Connect to remote running command. ManualResetEvent pipelineConnectedEvent = new ManualResetEvent(false); using (pipelineConnectedEvent) { _remotePipeline.StateChanged += (sender, args) => { if (pipelineConnectedEvent != null && (args.PipelineStateInfo.State == PipelineState.Running || args.PipelineStateInfo.State == PipelineState.Stopped || args.PipelineStateInfo.State == PipelineState.Failed)) { pipelineConnectedEvent.Set(); } }; _remotePipeline.ConnectAsync(); pipelineConnectedEvent.WaitOne(); } pipelineConnectedEvent = null; if (CheckForDebugMode(session, true)) { return; } // Wait for remote command to complete, while writing any available data. while (!_remotePipeline.Output.EndOfPipeline) { if (_stopProcessing) { break; } int index = WaitHandle.WaitAny(new WaitHandle[] { _stopPipelineReceive, _remotePipeline.Output.WaitHandle }); if (index == 0) { WriteDebugStopWarning(); return; } while (_remotePipeline.Output.Count > 0) { if (_stopProcessing) { break; } PSObject psObject = _remotePipeline.Output.Read(); WriteRemoteObject(psObject, session); } } // Write pipeline object errors. if (_remotePipeline.Error.Count > 0) { while (!_remotePipeline.Error.EndOfPipeline) { object errorObj = _remotePipeline.Error.Read(); if (errorObj is Collection<ErrorRecord>) { Collection<ErrorRecord> errorCollection = (Collection<ErrorRecord>)errorObj; foreach (ErrorRecord errorRecord in errorCollection) { WriteError(errorRecord); } } else if (errorObj is ErrorRecord) { WriteError((ErrorRecord)errorObj); } else { Dbg.Assert(false, "Objects in pipeline Error collection must be ErrorRecord type."); } } } // Wait for pipeline to finish. int wIndex = WaitHandle.WaitAny(new WaitHandle[] { _stopPipelineReceive, _remotePipeline.PipelineFinishedEvent }); if (wIndex == 0) { WriteDebugStopWarning(); return; } // Set the runspace RemoteCommand to null. It is not needed anymore and it // allows the runspace to become available after pipeline completes. remoteRunspace.RunspacePool.RemoteRunspacePoolInternal.ConnectCommands = null; // Check for any terminating errors to report. if (_remotePipeline.PipelineStateInfo.State == PipelineState.Failed) { Exception reason = _remotePipeline.PipelineStateInfo.Reason; string msg; if (reason != null && !string.IsNullOrEmpty(reason.Message)) { msg = StringUtil.Format(RemotingErrorIdStrings.PipelineFailedWithReason, reason.Message); } else { msg = RemotingErrorIdStrings.PipelineFailedWithoutReason; } ErrorRecord errorRecord = new ErrorRecord(new RuntimeException(msg, reason), "ReceivePSSessionPipelineFailed", ErrorCategory.OperationStopped, _remotePipeline ); WriteError(errorRecord); } } } lock (_syncObject) { _remotePipeline = null; _stopPipelineReceive = null; } }
private void ConnectSessionToJob(PSSession session, PSRemotingJob job = null) { bool flag = false; if (job == null) { List<IThrottleOperation> helpers = new List<IThrottleOperation>(); Pipeline pipeline = session.Runspace.CreateDisconnectedPipeline(); helpers.Add(new DisconnectedJobOperation(pipeline)); job = new PSRemotingJob(helpers, 0, this.JobName, false); job.PSJobTypeName = InvokeCommandCommand.RemoteJobType; job.HideComputerName = false; flag = true; } if (job.JobStateInfo.State == JobState.Disconnected) { job.ConnectJob(session.Runspace.InstanceId); if (flag) { base.JobRepository.Add(job); } } base.WriteObject(job); }
/// <summary> /// Connects session, collects command output data in a job object. /// If a PSRemotingJob object is passed in then that job will be /// (re)connected. Otherwise a new job object will be created that /// will be connected to the session's running command. /// </summary> /// <param name="session">PSSession object.</param> /// <param name="job">Job object to connect to.</param> private void ConnectSessionToJob(PSSession session, PSRemotingJob job = null) { // Otherwise create a new job object in the disconnected state for this // session and then connect it. bool newJobCreated = false; if (job == null) { // The PSRemoting job object uses helper objects to track remote command execution. List<IThrottleOperation> helpers = new List<IThrottleOperation>(); // Create the remote pipeline object that will represent the running command // on the server machine. This object will be in the disconnected state. Pipeline remotePipeline = session.Runspace.CreateDisconnectedPipeline(); // Create a disconnected runspace helper for this remote command. helpers.Add(new DisconnectedJobOperation(remotePipeline)); // Create the job object in a disconnected state. Note that the job name // will be autogenerated. job = new PSRemotingJob(helpers, 0, JobName, false); job.PSJobTypeName = InvokeCommandCommand.RemoteJobType; job.HideComputerName = false; newJobCreated = true; } if (job.JobStateInfo.State == JobState.Disconnected) { // Connect the job to the remote command running on the server. job.ConnectJob(session.Runspace.InstanceId); // Add the created job to the store if it was connected successfully. if (newJobCreated) { JobRepository.Add(job); } } if (CheckForDebugMode(session, true)) { return; } // Write the job object to output. WriteObject(job); }
protected override void ProcessRecord() { if (!this.pipelineinvoked && !this.needToCollect) { this.pipelineinvoked = true; if (this.InputObject == AutomationNull.Value) { base.CloseAllInputStreams(); this.inputStreamClosed = true; } if (!base.ParameterSetName.Equals("InProcess")) { if (!this.asjob) { this.CreateAndRunSyncJob(); } else { string parameterSetName = base.ParameterSetName; if (parameterSetName != null) { if (!(parameterSetName == "ComputerName") && !(parameterSetName == "FilePathComputerName")) { if ((parameterSetName == "Session") || (parameterSetName == "FilePathRunspace")) { PSRemotingJob item = new PSRemotingJob(this.Session, base.Operations, this.ScriptBlock.ToString(), this.ThrottleLimit, this.name) { PSJobTypeName = RemoteJobType, HideComputerName = this.hideComputerName }; base.JobRepository.Add(item); base.WriteObject(item); } else if (((parameterSetName == "Uri") || (parameterSetName == "FilePathUri")) && (base.Operations.Count > 0)) { string[] computerNames = new string[this.ConnectionUri.Length]; for (int i = 0; i < computerNames.Length; i++) { computerNames[i] = this.ConnectionUri[i].ToString(); } PSRemotingJob job3 = new PSRemotingJob(computerNames, base.Operations, this.ScriptBlock.ToString(), this.ThrottleLimit, this.name) { PSJobTypeName = RemoteJobType, HideComputerName = this.hideComputerName }; base.JobRepository.Add(job3); base.WriteObject(job3); } } else if ((base.ResolvedComputerNames.Length != 0) && (base.Operations.Count > 0)) { PSRemotingJob job = new PSRemotingJob(base.ResolvedComputerNames, base.Operations, this.ScriptBlock.ToString(), this.ThrottleLimit, this.name) { PSJobTypeName = RemoteJobType, HideComputerName = this.hideComputerName }; base.JobRepository.Add(job); base.WriteObject(job); } } } } } if ((this.InputObject != AutomationNull.Value) && !this.inputStreamClosed) { if ((base.ParameterSetName.Equals("InProcess") && (this.steppablePipeline == null)) || this.needToCollect) { this.input.Add(this.InputObject); } else if (base.ParameterSetName.Equals("InProcess") && (this.steppablePipeline != null)) { this.steppablePipeline.Process(this.InputObject); } else { this.WriteInput(this.InputObject); if (!this.asjob) { this.WriteJobResults(true); } } } }
/// <summary> /// The expression will be executed in the remote computer if a /// remote runspace parameter or computer name or uri is specified. /// </summary> /// <remarks> /// 1. Identify if the command belongs to the same pipeline /// 2. If so, use the same GUID to create Pipeline/PowerShell /// </remarks> protected override void ProcessRecord() { // we should create the pipeline on first instance // and if there are no invoke-commands running // ahead in the pipeline if (!_pipelineinvoked && !_needToCollect) { _pipelineinvoked = true; if (InputObject == AutomationNull.Value) { CloseAllInputStreams(); _inputStreamClosed = true; } if (!ParameterSetName.Equals("InProcess")) { // at this point there is nothing to do for // inproc case. The script block is executed // in EndProcessing if (!_asjob) { CreateAndRunSyncJob(); } else { switch (ParameterSetName) { case InvokeCommandCommand.ComputerNameParameterSet: case InvokeCommandCommand.FilePathComputerNameParameterSet: case InvokeCommandCommand.VMIdParameterSet: case InvokeCommandCommand.VMNameParameterSet: case InvokeCommandCommand.ContainerIdParameterSet: case InvokeCommandCommand.FilePathVMIdParameterSet: case InvokeCommandCommand.FilePathVMNameParameterSet: case InvokeCommandCommand.FilePathContainerIdParameterSet: { if (ResolvedComputerNames.Length != 0 && Operations.Count > 0) { PSRemotingJob job = new PSRemotingJob(ResolvedComputerNames, Operations, ScriptBlock.ToString(), ThrottleLimit, _name); job.PSJobTypeName = RemoteJobType; job.HideComputerName = _hideComputerName; this.JobRepository.Add(job); WriteObject(job); } } break; case InvokeCommandCommand.SSHHostParameterSet: case InvokeCommandCommand.FilePathSSHHostParameterSet: { var job = new PSRemotingJob(new string[] { this.HostName }, Operations, ScriptBlock.ToString(), ThrottleLimit, _name); job.PSJobTypeName = RemoteJobType; job.HideComputerName = _hideComputerName; this.JobRepository.Add(job); WriteObject(job); } break; case InvokeCommandCommand.SessionParameterSet: case InvokeCommandCommand.FilePathSessionParameterSet: { PSRemotingJob job = new PSRemotingJob(Session, Operations, ScriptBlock.ToString(), ThrottleLimit, _name); job.PSJobTypeName = RemoteJobType; job.HideComputerName = _hideComputerName; this.JobRepository.Add(job); WriteObject(job); } break; case InvokeCommandCommand.UriParameterSet: case InvokeCommandCommand.FilePathUriParameterSet: { if (Operations.Count > 0) { String[] locations = new String[ConnectionUri.Length]; for (int i = 0; i < locations.Length; i++) { locations[i] = ConnectionUri[i].ToString(); } PSRemotingJob job = new PSRemotingJob(locations, Operations, ScriptBlock.ToString(), ThrottleLimit, _name); job.PSJobTypeName = RemoteJobType; job.HideComputerName = _hideComputerName; this.JobRepository.Add(job); WriteObject(job); } } break; } // switch ... } // else ... } } // if (!pipelineinvoked... if (InputObject != AutomationNull.Value && !_inputStreamClosed) { if ((ParameterSetName.Equals(InvokeCommandCommand.InProcParameterSet) && (_steppablePipeline == null)) || _needToCollect) { _input.Add(InputObject); } else if (ParameterSetName.Equals(InvokeCommandCommand.InProcParameterSet) && (_steppablePipeline != null)) { _steppablePipeline.Process(InputObject); } else { WriteInput(InputObject); // if not a job write out the results available thus far if (!_asjob) { WriteJobResults(true); } } } } // ProcessRecord
/// <summary> /// The expression will be executed in the remote computer if a /// remote runspace parameter or computer name is specified. If /// none other than command parameter is specified, then it /// just executes the command locally without creating a new /// remote runspace object. /// </summary> protected override void ProcessRecord() { if (ParameterSetName == DefinitionNameParameterSet) { // Get the Job2 object from the Job Manager for this definition name and start the job. string resolvedPath = null; if (!string.IsNullOrEmpty(_definitionPath)) { ProviderInfo provider = null; System.Collections.ObjectModel.Collection<string> paths = this.Context.SessionState.Path.GetResolvedProviderPathFromPSPath(_definitionPath, out provider); // Only file system paths are allowed. if (!provider.NameEquals(this.Context.ProviderNames.FileSystem)) { string message = StringUtil.Format(RemotingErrorIdStrings.StartJobDefinitionPathInvalidNotFSProvider, _definitionName, _definitionPath, provider.FullName); WriteError(new ErrorRecord(new RuntimeException(message), "StartJobFromDefinitionNamePathInvalidNotFileSystemProvider", ErrorCategory.InvalidArgument, null)); return; } // Only a single file path is allowed. if (paths.Count != 1) { string message = StringUtil.Format(RemotingErrorIdStrings.StartJobDefinitionPathInvalidNotSingle, _definitionName, _definitionPath); WriteError(new ErrorRecord(new RuntimeException(message), "StartJobFromDefinitionNamePathInvalidNotSingle", ErrorCategory.InvalidArgument, null)); return; } resolvedPath = paths[0]; } List<Job2> jobs = JobManager.GetJobToStart(_definitionName, resolvedPath, _definitionType, this, false); if (jobs.Count == 0) { string message = (_definitionType != null) ? StringUtil.Format(RemotingErrorIdStrings.StartJobDefinitionNotFound2, _definitionType, _definitionName) : StringUtil.Format(RemotingErrorIdStrings.StartJobDefinitionNotFound1, _definitionName); WriteError(new ErrorRecord(new RuntimeException(message), "StartJobFromDefinitionNameNotFound", ErrorCategory.ObjectNotFound, null)); return; } if (jobs.Count > 1) { string message = StringUtil.Format(RemotingErrorIdStrings.StartJobManyDefNameMatches, _definitionName); WriteError(new ErrorRecord(new RuntimeException(message), "StartJobFromDefinitionNameMoreThanOneMatch", ErrorCategory.InvalidResult, null)); return; } // Start job. Job2 job = jobs[0]; job.StartJob(); // Write job object to host. WriteObject(job); return; } if (_firstProcessRecord) { _firstProcessRecord = false; PSRemotingJob job = new PSRemotingJob(ResolvedComputerNames, Operations, ScriptBlock.ToString(), ThrottleLimit, _name); job.PSJobTypeName = s_startJobType; this.JobRepository.Add(job); WriteObject(job); } // inject input if (InputObject != AutomationNull.Value) { foreach (IThrottleOperation operation in Operations) { ExecutionCmdletHelper helper = (ExecutionCmdletHelper)operation; helper.Pipeline.Input.Write(InputObject); } } } // ProcessRecord
protected override void ProcessRecord() { if (base.ParameterSetName == "DefinitionName") { string definitionPath = null; if (!string.IsNullOrEmpty(this._definitionPath)) { ProviderInfo provider = null; Collection<string> resolvedProviderPathFromPSPath = base.Context.SessionState.Path.GetResolvedProviderPathFromPSPath(this._definitionPath, out provider); if (!provider.NameEquals(base.Context.ProviderNames.FileSystem)) { string message = StringUtil.Format(RemotingErrorIdStrings.StartJobDefinitionPathInvalidNotFSProvider, new object[] { this._definitionName, this._definitionPath, provider.FullName }); base.WriteError(new ErrorRecord(new RuntimeException(message), "StartJobFromDefinitionNamePathInvalidNotFileSystemProvider", ErrorCategory.InvalidArgument, null)); return; } if (resolvedProviderPathFromPSPath.Count != 1) { string str3 = StringUtil.Format(RemotingErrorIdStrings.StartJobDefinitionPathInvalidNotSingle, this._definitionName, this._definitionPath); base.WriteError(new ErrorRecord(new RuntimeException(str3), "StartJobFromDefinitionNamePathInvalidNotSingle", ErrorCategory.InvalidArgument, null)); return; } definitionPath = resolvedProviderPathFromPSPath[0]; } List<Job2> list = base.JobManager.GetJobToStart(this._definitionName, definitionPath, this._definitionType, this, false); if (list.Count == 0) { string str4 = (this._definitionType != null) ? StringUtil.Format(RemotingErrorIdStrings.StartJobDefinitionNotFound2, this._definitionType, this._definitionName) : StringUtil.Format(RemotingErrorIdStrings.StartJobDefinitionNotFound1, this._definitionName); base.WriteError(new ErrorRecord(new RuntimeException(str4), "StartJobFromDefinitionNameNotFound", ErrorCategory.ObjectNotFound, null)); } else if (list.Count > 1) { string str5 = StringUtil.Format(RemotingErrorIdStrings.StartJobManyDefNameMatches, this._definitionName); base.WriteError(new ErrorRecord(new RuntimeException(str5), "StartJobFromDefinitionNameMoreThanOneMatch", ErrorCategory.InvalidResult, null)); } else { Job2 sendToPipeline = list[0]; sendToPipeline.StartJob(); base.WriteObject(sendToPipeline); } } else { if (this.firstProcessRecord) { this.firstProcessRecord = false; PSRemotingJob item = new PSRemotingJob(base.ResolvedComputerNames, base.Operations, this.ScriptBlock.ToString(), this.ThrottleLimit, this.name) { PSJobTypeName = StartJobType }; base.JobRepository.Add(item); base.WriteObject(item); } if (this.InputObject != AutomationNull.Value) { foreach (IThrottleOperation operation in base.Operations) { ExecutionCmdletHelper helper = (ExecutionCmdletHelper) operation; helper.Pipeline.Input.Write(this.InputObject); } } } }