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); }
/// <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); }
internal ExecutionCmdletHelperComputerName(System.Management.Automation.RemoteRunspace remoteRunspace, Pipeline pipeline, bool invokeAndDisconnect = false) { this.invokeAndDisconnect = invokeAndDisconnect; this.remoteRunspace = remoteRunspace; remoteRunspace.StateChanged += new EventHandler<RunspaceStateEventArgs>(this.HandleRunspaceStateChanged); base.pipeline = pipeline; pipeline.StateChanged += new EventHandler<PipelineStateEventArgs>(this.HandlePipelineStateChanged); }
internal RemoteHelpInfo( ExecutionContext context, RemoteRunspace remoteRunspace, string localCommandName, string remoteHelpTopic, string remoteHelpCategory, HelpCategory localHelpCategory) : base(localHelpCategory) { Dbg.Assert(remoteRunspace != null, "Caller should verify arguments"); using (PowerShell powerShell = PowerShell.Create()) { powerShell.AddCommand("Get-Help"); powerShell.AddParameter("Name", remoteHelpTopic); if (!string.IsNullOrEmpty(remoteHelpCategory)) { powerShell.AddParameter("Category", remoteHelpCategory); } powerShell.Runspace = remoteRunspace; Collection<PSObject> helpResults; using (new PowerShellStopper(context, powerShell)) { helpResults = powerShell.Invoke(); } if ((helpResults == null) || (helpResults.Count == 0)) { throw new Microsoft.PowerShell.Commands.HelpNotFoundException(remoteHelpTopic); } Dbg.Assert(helpResults.Count == 1, "Remote help should return exactly one result"); _deserializedRemoteHelp = helpResults[0]; _deserializedRemoteHelp.Methods.Remove("ToString"); // Win8: bug9457: Remote proxy command's name can be changed locally using -Prefix // parameter of the Import-PSSession cmdlet. To give better user experience for // get-help (on par with get-command), it was decided to use the local command name // for the help content. PSPropertyInfo nameInfo = _deserializedRemoteHelp.Properties["Name"]; if (nameInfo != null) { nameInfo.Value = localCommandName; } PSObject commandDetails = this.Details; if (commandDetails != null) { nameInfo = commandDetails.Properties["Name"]; if (nameInfo != null) { nameInfo.Value = localCommandName; } else { commandDetails.InstanceMembers.Add(new PSNoteProperty("Name", localCommandName)); } } } }
internal bool InsertRunspace(RemoteRunspace remoteRunspace) { if ((remoteRunspace == null) || (remoteRunspace.InstanceId != this.remoteRunspace.InstanceId)) { return false; } this.remoteRunspace = remoteRunspace; return true; }
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); }
private List<RemoteRunspace> CreateRunspacesWhenComputerNameParameterSpecified() { string[] strArray; List<RemoteRunspace> list = new List<RemoteRunspace>(); base.ResolveComputerNames(this.ComputerName, out strArray); base.ValidateComputerName(strArray); for (int i = 0; i < strArray.Length; i++) { try { int num2; WSManConnectionInfo connectionInfo = null; connectionInfo = new WSManConnectionInfo(); string str = this.UseSSL.IsPresent ? "https" : "http"; connectionInfo.ComputerName = strArray[i]; connectionInfo.Port = this.Port; connectionInfo.AppName = this.ApplicationName; connectionInfo.ShellUri = this.ConfigurationName; connectionInfo.Scheme = str; if (this.CertificateThumbprint != null) { connectionInfo.CertificateThumbprint = this.CertificateThumbprint; } else { connectionInfo.Credential = this.Credential; } connectionInfo.AuthenticationMechanism = this.Authentication; base.UpdateConnectionInfo(connectionInfo); connectionInfo.EnableNetworkAccess = (bool) this.EnableNetworkAccess; string runspaceName = this.GetRunspaceName(i, out num2); RemoteRunspace item = new RemoteRunspace(Utils.GetTypeTableFromExecutionContextTLS(), connectionInfo, base.Host, this.SessionOption.ApplicationArguments, runspaceName, num2); list.Add(item); } catch (UriFormatException exception) { PipelineWriter objectWriter = this.stream.ObjectWriter; ErrorRecord errorRecord = new ErrorRecord(exception, "CreateRemoteRunspaceFailed", ErrorCategory.InvalidArgument, strArray[i]); Action<Cmdlet> action = delegate (Cmdlet cmdlet) { cmdlet.WriteError(errorRecord); }; objectWriter.Write(action); } } return list; }
internal RemoteHelpInfo(ExecutionContext context, RemoteRunspace remoteRunspace, string localCommandName, string remoteHelpTopic, string remoteHelpCategory, HelpCategory localHelpCategory) : base(localHelpCategory) { using (PowerShell shell = PowerShell.Create()) { Collection<PSObject> collection; shell.AddCommand("Get-Help"); shell.AddParameter("Name", remoteHelpTopic); if (!string.IsNullOrEmpty(remoteHelpCategory)) { shell.AddParameter("Category", remoteHelpCategory); } shell.Runspace = remoteRunspace; using (new PowerShellStopper(context, shell)) { collection = shell.Invoke(); } if ((collection == null) || (collection.Count == 0)) { throw new HelpNotFoundException(remoteHelpTopic); } this.deserializedRemoteHelp = collection[0]; this.deserializedRemoteHelp.Methods.Remove("ToString"); PSPropertyInfo info = this.deserializedRemoteHelp.Properties["Name"]; if (info != null) { info.Value = localCommandName; } PSObject details = base.Details; if (details != null) { info = details.Properties["Name"]; if (info != null) { info.Value = localCommandName; } else { details.InstanceMembers.Add(new PSNoteProperty("Name", localCommandName)); } } } }
internal PSSession(RemoteRunspace remoteRunspace) { this.remoteRunspace = remoteRunspace; if (remoteRunspace.Id != -1) { this.sessionid = remoteRunspace.Id; } else { this.sessionid = Interlocked.Increment(ref seed); remoteRunspace.Id = this.sessionid; } if (!string.IsNullOrEmpty(remoteRunspace.Name)) { this.name = remoteRunspace.Name; } else { this.name = this.AutoGenerateRunspaceName(); remoteRunspace.Name = this.name; } string shell = WSManConnectionInfo.ExtractPropertyAsWsManConnectionInfo<string>(remoteRunspace.ConnectionInfo, "ShellUri", string.Empty); this.shell = this.GetDisplayShellName(shell); }
} // CreateHelpersForSpecifiedUris /// <summary> /// Creates helper objects with the command for the specified /// VM GUIDs or VM names. /// </summary> protected virtual void CreateHelpersForSpecifiedVMSession() { int inputArraySize; int index; string command; bool[] vmIsRunning; Collection<PSObject> results; if ((ParameterSetName == PSExecutionCmdlet.VMIdParameterSet) || (ParameterSetName == PSExecutionCmdlet.FilePathVMIdParameterSet)) { inputArraySize = this.VMId.Length; this.VMName = new string[inputArraySize]; vmIsRunning = new bool[inputArraySize]; for (index = 0; index < inputArraySize; index++) { vmIsRunning[index] = false; command = "Get-VM -Id $args[0]"; try { results = this.InvokeCommand.InvokeScript( command, false, PipelineResultTypes.None, null, this.VMId[index]); } catch (CommandNotFoundException) { ThrowTerminatingError( new ErrorRecord( new ArgumentException(RemotingErrorIdStrings.HyperVModuleNotAvailable), PSRemotingErrorId.HyperVModuleNotAvailable.ToString(), ErrorCategory.NotInstalled, null)); return; } if (results.Count != 1) { this.VMName[index] = string.Empty; } else { this.VMName[index] = (string)results[0].Properties["VMName"].Value; if ((VMState)results[0].Properties["State"].Value == VMState.Running) { vmIsRunning[index] = true; } } } } else { Dbg.Assert((ParameterSetName == PSExecutionCmdlet.VMNameParameterSet) || (ParameterSetName == PSExecutionCmdlet.FilePathVMNameParameterSet), "Expected ParameterSetName == VMName or FilePathVMName"); inputArraySize = this.VMName.Length; this.VMId = new Guid[inputArraySize]; vmIsRunning = new bool[inputArraySize]; for (index = 0; index < inputArraySize; index++) { vmIsRunning[index] = false; command = "Get-VM -Name $args"; try { results = this.InvokeCommand.InvokeScript( command, false, PipelineResultTypes.None, null, this.VMName[index]); } catch (CommandNotFoundException) { ThrowTerminatingError( new ErrorRecord( new ArgumentException(RemotingErrorIdStrings.HyperVModuleNotAvailable), PSRemotingErrorId.HyperVModuleNotAvailable.ToString(), ErrorCategory.NotInstalled, null)); return; } if (results.Count != 1) { this.VMId[index] = Guid.Empty; } else { this.VMId[index] = (Guid)results[0].Properties["VMId"].Value; this.VMName[index] = (string)results[0].Properties["VMName"].Value; if ((VMState)results[0].Properties["State"].Value == VMState.Running) { vmIsRunning[index] = true; } } } } ResolvedComputerNames = this.VMName; for (index = 0; index < ResolvedComputerNames.Length; index++) { if ((this.VMId[index] == Guid.Empty) && ((ParameterSetName == PSExecutionCmdlet.VMNameParameterSet) || (ParameterSetName == PSExecutionCmdlet.FilePathVMNameParameterSet))) { WriteError( new ErrorRecord( new ArgumentException(GetMessage(RemotingErrorIdStrings.InvalidVMNameNotSingle, this.VMName[index])), PSRemotingErrorId.InvalidVMNameNotSingle.ToString(), ErrorCategory.InvalidArgument, null)); continue; } else if ((this.VMName[index] == string.Empty) && ((ParameterSetName == PSExecutionCmdlet.VMIdParameterSet) || (ParameterSetName == PSExecutionCmdlet.FilePathVMIdParameterSet))) { WriteError( new ErrorRecord( new ArgumentException(GetMessage(RemotingErrorIdStrings.InvalidVMIdNotSingle, this.VMId[index].ToString(null))), PSRemotingErrorId.InvalidVMIdNotSingle.ToString(), ErrorCategory.InvalidArgument, null)); continue; } else if (!vmIsRunning[index]) { WriteError( new ErrorRecord( new ArgumentException(GetMessage(RemotingErrorIdStrings.InvalidVMState, this.VMName[index])), PSRemotingErrorId.InvalidVMState.ToString(), ErrorCategory.InvalidArgument, null)); continue; } // create helper objects for VM GUIDs or names RemoteRunspace remoteRunspace = null; VMConnectionInfo connectionInfo; try { connectionInfo = new VMConnectionInfo(this.Credential, this.VMId[index], this.VMName[index], this.ConfigurationName); remoteRunspace = new RemoteRunspace(Utils.GetTypeTableFromExecutionContextTLS(), connectionInfo, this.Host, null, null, -1); remoteRunspace.Events.ReceivedEvents.PSEventReceived += OnRunspacePSEventReceived; } catch (InvalidOperationException e) { ErrorRecord errorRecord = new ErrorRecord(e, "CreateRemoteRunspaceForVMFailed", ErrorCategory.InvalidOperation, null); WriteError(errorRecord); } catch (ArgumentException e) { ErrorRecord errorRecord = new ErrorRecord(e, "CreateRemoteRunspaceForVMFailed", ErrorCategory.InvalidArgument, null); WriteError(errorRecord); } Pipeline pipeline = CreatePipeline(remoteRunspace); IThrottleOperation operation = new ExecutionCmdletHelperComputerName(remoteRunspace, pipeline, false); Operations.Add(operation); } }// CreateHelpersForSpecifiedVMSession
}// CreateHelpersForSpecifiedVMSession /// <summary> /// Creates helper objects with the command for the specified /// container IDs or names. /// </summary> protected virtual void CreateHelpersForSpecifiedContainerSession() { List<string> resolvedNameList = new List<string>(); Dbg.Assert((ParameterSetName == PSExecutionCmdlet.ContainerIdParameterSet) || (ParameterSetName == PSExecutionCmdlet.FilePathContainerIdParameterSet), "Expected ParameterSetName == ContainerId or FilePathContainerId"); foreach (var input in ContainerId) { // // Create helper objects for container ID or name. // RemoteRunspace remoteRunspace = null; ContainerConnectionInfo connectionInfo = null; try { // // Hyper-V container uses Hype-V socket as transport. // Windows Server container uses named pipe as transport. // connectionInfo = ContainerConnectionInfo.CreateContainerConnectionInfo(input, RunAsAdministrator.IsPresent, this.ConfigurationName); resolvedNameList.Add(connectionInfo.ComputerName); connectionInfo.CreateContainerProcess(); remoteRunspace = new RemoteRunspace(Utils.GetTypeTableFromExecutionContextTLS(), connectionInfo, this.Host, null, null, -1); remoteRunspace.Events.ReceivedEvents.PSEventReceived += OnRunspacePSEventReceived; } catch (InvalidOperationException e) { ErrorRecord errorRecord = new ErrorRecord(e, "CreateRemoteRunspaceForContainerFailed", ErrorCategory.InvalidOperation, null); WriteError(errorRecord); continue; } catch (ArgumentException e) { ErrorRecord errorRecord = new ErrorRecord(e, "CreateRemoteRunspaceForContainerFailed", ErrorCategory.InvalidArgument, null); WriteError(errorRecord); continue; } catch (Exception e) { ErrorRecord errorRecord = new ErrorRecord(e, "CreateRemoteRunspaceForContainerFailed", ErrorCategory.InvalidOperation, null); WriteError(errorRecord); continue; } Pipeline pipeline = CreatePipeline(remoteRunspace); IThrottleOperation operation = new ExecutionCmdletHelperComputerName(remoteRunspace, pipeline, false); Operations.Add(operation); } ResolvedComputerNames = resolvedNameList.ToArray(); }// CreateHelpersForSpecifiedContainerSession
/// <summary> /// Creates helper objects with the command for the specified /// remote computer names /// </summary> protected virtual void CreateHelpersForSpecifiedComputerNames() { ValidateComputerName(ResolvedComputerNames); // create helper objects for computer names RemoteRunspace remoteRunspace = null; string scheme = UseSSL.IsPresent ? WSManConnectionInfo.HttpsScheme : WSManConnectionInfo.HttpScheme; for (int i = 0; i < ResolvedComputerNames.Length; i++) { try { WSManConnectionInfo connectionInfo = new WSManConnectionInfo(); connectionInfo.Scheme = scheme; connectionInfo.ComputerName = ResolvedComputerNames[i]; connectionInfo.Port = Port; connectionInfo.AppName = ApplicationName; connectionInfo.ShellUri = ConfigurationName; if (CertificateThumbprint != null) { connectionInfo.CertificateThumbprint = CertificateThumbprint; } else { connectionInfo.Credential = Credential; } connectionInfo.AuthenticationMechanism = Authentication; UpdateConnectionInfo(connectionInfo); connectionInfo.EnableNetworkAccess = EnableNetworkAccess; // Use the provided session name or create one for this remote runspace so that // it can be easily identified if it becomes disconnected and is queried on the server. int rsId = PSSession.GenerateRunspaceId(); string rsName = (DisconnectedSessionName != null && DisconnectedSessionName.Length > i) ? DisconnectedSessionName[i] : PSSession.ComposeRunspaceName(rsId); remoteRunspace = new RemoteRunspace(Utils.GetTypeTableFromExecutionContextTLS(), connectionInfo, this.Host, this.SessionOption.ApplicationArguments, rsName, rsId); remoteRunspace.Events.ReceivedEvents.PSEventReceived += OnRunspacePSEventReceived; } catch (UriFormatException uriException) { ErrorRecord errorRecord = new ErrorRecord(uriException, "CreateRemoteRunspaceFailed", ErrorCategory.InvalidArgument, ResolvedComputerNames[i]); WriteError(errorRecord); continue; } Pipeline pipeline = CreatePipeline(remoteRunspace); IThrottleOperation operation = new ExecutionCmdletHelperComputerName(remoteRunspace, pipeline, InvokeAndDisconnect); Operations.Add(operation); } }// CreateHelpersForSpecifiedComputerNames
protected void CreateHelpersForSpecifiedRunspaces() { RemoteRunspace[] remoteRunspaces; Pipeline[] pipelines; // extract RemoteRunspace out of the PSSession objects int length = Session.Length; remoteRunspaces = new RemoteRunspace[length]; for (int i = 0; i < length; i++) { remoteRunspaces[i] = (RemoteRunspace)Session[i].Runspace; } // create the set of pipelines from the RemoteRunspace objects and // create IREHelperRunspace helper class to create operations pipelines = new Pipeline[length]; for (int i = 0; i < length; i++) { pipelines[i] = CreatePipeline(remoteRunspaces[i]); // create the operation object IThrottleOperation operation = new ExecutionCmdletHelperRunspace(pipelines[i]); Operations.Add(operation); } } // CreateHelpersForSpecifiedRunspaces
internal OpenRunspaceOperation(RemoteRunspace runspace) { _startComplete = true; _stopComplete = true; OperatedRunspace = runspace; OperatedRunspace.StateChanged += new EventHandler<RunspaceStateEventArgs>(HandleRunspaceStateChanged); }
private void RaiseOperationCompleteEvent(EventArgs baseEventArgs) { if (base.pipeline != null) { base.pipeline.StateChanged -= new EventHandler<PipelineStateEventArgs>(this.HandlePipelineStateChanged); base.pipeline.Dispose(); } if (this.remoteRunspace != null) { this.remoteRunspace.Dispose(); this.remoteRunspace = null; } OperationStateEventArgs eventArgs = new OperationStateEventArgs { OperationState = OperationState.StopComplete, BaseEvent = baseEventArgs }; this.OperationComplete.SafeInvoke<OperationStateEventArgs>(this, eventArgs); }
/// <summary> /// Constructor /// </summary> /// <param name="remoteRunspace">RemoteRunspace that is associated /// with this operation</param> /// <param name="pipeline">pipeline created from the remote runspace</param> /// <param name="invokeAndDisconnect">Indicates if pipeline should be disconnected after invoking command.</param> internal ExecutionCmdletHelperComputerName(RemoteRunspace remoteRunspace, Pipeline pipeline, bool invokeAndDisconnect = false) { Dbg.Assert(remoteRunspace != null, "RemoteRunspace reference cannot be null"); PipelineRunspace = remoteRunspace; _invokeAndDisconnect = invokeAndDisconnect; RemoteRunspace = remoteRunspace; remoteRunspace.StateChanged += new EventHandler<RunspaceStateEventArgs>(HandleRunspaceStateChanged); Dbg.Assert(pipeline != null, "Pipeline cannot be null or empty"); this.pipeline = pipeline; pipeline.StateChanged += new EventHandler<PipelineStateEventArgs>(HandlePipelineStateChanged); } // IREHelperComputerName
internal void Override(RemoteRunspace remoteRunspace) { bool isRunspacePushed = false; this.Override(remoteRunspace, null, out isRunspacePushed); }
private List<RemoteRunspace> CreateRunspacesWhenUriParameterSpecified() { List<RemoteRunspace> list = new List<RemoteRunspace>(); for (int i = 0; i < this.ConnectionUri.Length; i++) { try { int num2; WSManConnectionInfo connectionInfo = new WSManConnectionInfo { ConnectionUri = this.ConnectionUri[i], ShellUri = this.ConfigurationName }; if (this.CertificateThumbprint != null) { connectionInfo.CertificateThumbprint = this.CertificateThumbprint; } else { connectionInfo.Credential = this.Credential; } connectionInfo.AuthenticationMechanism = this.Authentication; base.UpdateConnectionInfo(connectionInfo); connectionInfo.EnableNetworkAccess = (bool) this.EnableNetworkAccess; string runspaceName = this.GetRunspaceName(i, out num2); RemoteRunspace item = new RemoteRunspace(Utils.GetTypeTableFromExecutionContextTLS(), connectionInfo, base.Host, this.SessionOption.ApplicationArguments, runspaceName, num2); list.Add(item); } catch (UriFormatException exception) { this.WriteErrorCreateRemoteRunspaceFailed(exception, this.ConnectionUri[i]); } catch (InvalidOperationException exception2) { this.WriteErrorCreateRemoteRunspaceFailed(exception2, this.ConnectionUri[i]); } catch (ArgumentException exception3) { this.WriteErrorCreateRemoteRunspaceFailed(exception3, this.ConnectionUri[i]); } catch (NotSupportedException exception4) { this.WriteErrorCreateRemoteRunspaceFailed(exception4, this.ConnectionUri[i]); } } return list; }
}// CreateHelpersForSpecifiedContainerSession /// <summary> /// Creates a pipeline from the powershell /// </summary> /// <param name="remoteRunspace">runspace on which to create the pipeline</param> /// <returns>a pipeline</returns> internal Pipeline CreatePipeline(RemoteRunspace remoteRunspace) { // The fix to WinBlue#475223 changed how UsingExpression is handled on the client/server sides, if the remote end is PSv5 // or later, we send the dictionary-form using values to the remote end. If the remote end is PSv3 or PSv4, then we send // the array-form using values if all UsingExpressions are in the same scope, otherwise, we handle the UsingExpression as // if the remote end is PSv2. string serverPsVersion = GetRemoteServerPsVersion(remoteRunspace); System.Management.Automation.PowerShell powershellToUse = (serverPsVersion == PSv2) ? GetPowerShellForPSv2() : GetPowerShellForPSv3OrLater(serverPsVersion); Pipeline pipeline = remoteRunspace.CreatePipeline(powershellToUse.Commands.Commands[0].CommandText, true); pipeline.Commands.Clear(); foreach (Command command in powershellToUse.Commands.Commands) { pipeline.Commands.Add(command); } pipeline.RedirectShellErrorOutputPipe = true; return pipeline; }
}// CreateRunspacesWhenVMParameterSpecified /// <summary> /// Creates the remote runspace objects when the ContainerId parameter is specified /// </summary> private List<RemoteRunspace> CreateRunspacesWhenContainerParameterSpecified() { int index = 0; List<string> resolvedNameList = new List<string>(); List<RemoteRunspace> remoteRunspaces = new List<RemoteRunspace>(); Dbg.Assert((ParameterSetName == PSExecutionCmdlet.ContainerIdParameterSet), "Expected ParameterSetName == ContainerId"); foreach (var input in ContainerId) { // // Create helper objects for container ID or name. // RemoteRunspace runspace = null; ContainerConnectionInfo connectionInfo = null; int rsId; string rsName = GetRunspaceName(index, out rsId); index++; try { // // Hyper-V container uses Hype-V socket as transport. // Windows Server container uses named pipe as transport. // connectionInfo = ContainerConnectionInfo.CreateContainerConnectionInfo(input, RunAsAdministrator.IsPresent, this.ConfigurationName); resolvedNameList.Add(connectionInfo.ComputerName); connectionInfo.CreateContainerProcess(); runspace = new RemoteRunspace(Utils.GetTypeTableFromExecutionContextTLS(), connectionInfo, this.Host, null, rsName, rsId); remoteRunspaces.Add(runspace); } catch (InvalidOperationException e) { ErrorRecord errorRecord = new ErrorRecord(e, "CreateRemoteRunspaceForContainerFailed", ErrorCategory.InvalidOperation, null); WriteError(errorRecord); continue; } catch (ArgumentException e) { ErrorRecord errorRecord = new ErrorRecord(e, "CreateRemoteRunspaceForContainerFailed", ErrorCategory.InvalidArgument, null); WriteError(errorRecord); continue; } catch (Exception e) { ErrorRecord errorRecord = new ErrorRecord(e, "CreateRemoteRunspaceForContainerFailed", ErrorCategory.InvalidOperation, null); WriteError(errorRecord); continue; } } ResolvedComputerNames = resolvedNameList.ToArray(); return remoteRunspaces; }// CreateRunspacesWhenContainerParameterSpecified
}// CreateRunspacesWhenComputerNameParameterSpecified /// <summary> /// Creates the remote runspace objects when the VMId or VMName parameter /// is specified /// </summary> private List<RemoteRunspace> CreateRunspacesWhenVMParameterSpecified() { int inputArraySize; bool isVMIdSet = false; int index; string command; Collection<PSObject> results; List<RemoteRunspace> remoteRunspaces = new List<RemoteRunspace>(); if (ParameterSetName == PSExecutionCmdlet.VMIdParameterSet) { isVMIdSet = true; inputArraySize = this.VMId.Length; this.VMName = new string[inputArraySize]; command = "Get-VM -Id $args[0]"; } else { Dbg.Assert((ParameterSetName == PSExecutionCmdlet.VMNameParameterSet), "Expected ParameterSetName == VMId or VMName"); inputArraySize = this.VMName.Length; this.VMId = new Guid[inputArraySize]; command = "Get-VM -Name $args"; } for (index = 0; index < inputArraySize; index++) { try { results = this.InvokeCommand.InvokeScript( command, false, PipelineResultTypes.None, null, isVMIdSet ? this.VMId[index].ToString() : this.VMName[index]); } catch (CommandNotFoundException) { ThrowTerminatingError( new ErrorRecord( new ArgumentException(RemotingErrorIdStrings.HyperVModuleNotAvailable), PSRemotingErrorId.HyperVModuleNotAvailable.ToString(), ErrorCategory.NotInstalled, null)); return null; } // handle invalid input if (results.Count != 1) { if (isVMIdSet) { this.VMName[index] = string.Empty; WriteError( new ErrorRecord( new ArgumentException(GetMessage(RemotingErrorIdStrings.InvalidVMIdNotSingle, this.VMId[index].ToString(null))), PSRemotingErrorId.InvalidVMIdNotSingle.ToString(), ErrorCategory.InvalidArgument, null)); continue; } else { this.VMId[index] = Guid.Empty; WriteError( new ErrorRecord( new ArgumentException(GetMessage(RemotingErrorIdStrings.InvalidVMNameNotSingle, this.VMName[index])), PSRemotingErrorId.InvalidVMNameNotSingle.ToString(), ErrorCategory.InvalidArgument, null)); continue; } } else { this.VMId[index] = (Guid)results[0].Properties["VMId"].Value; this.VMName[index] = (string)results[0].Properties["VMName"].Value; // // VM should be in running state. // if ((VMState)results[0].Properties["State"].Value != VMState.Running) { WriteError( new ErrorRecord( new ArgumentException(GetMessage(RemotingErrorIdStrings.InvalidVMState, this.VMName[index])), PSRemotingErrorId.InvalidVMState.ToString(), ErrorCategory.InvalidArgument, null)); continue; } } // create helper objects for VM GUIDs or names RemoteRunspace runspace = null; VMConnectionInfo connectionInfo; int rsId; string rsName = GetRunspaceName(index, out rsId); try { connectionInfo = new VMConnectionInfo(this.Credential, this.VMId[index], this.VMName[index], this.ConfigurationName); runspace = new RemoteRunspace(Utils.GetTypeTableFromExecutionContextTLS(), connectionInfo, this.Host, null, rsName, rsId); remoteRunspaces.Add(runspace); } catch (InvalidOperationException e) { ErrorRecord errorRecord = new ErrorRecord(e, "CreateRemoteRunspaceForVMFailed", ErrorCategory.InvalidOperation, null); WriteError(errorRecord); } catch (ArgumentException e) { ErrorRecord errorRecord = new ErrorRecord(e, "CreateRemoteRunspaceForVMFailed", ErrorCategory.InvalidArgument, null); WriteError(errorRecord); } } ResolvedComputerNames = this.VMName; return remoteRunspaces; }// CreateRunspacesWhenVMParameterSpecified
} // CreateRunspacesWhenUriParameterSpecified /// <summary> /// Creates the remote runspace objects when the ComputerName parameter /// is specified /// </summary> private List<RemoteRunspace> CreateRunspacesWhenComputerNameParameterSpecified() { List<RemoteRunspace> remoteRunspaces = new List<RemoteRunspace>(); // Resolve all the machine names String[] resolvedComputerNames; ResolveComputerNames(ComputerName, out resolvedComputerNames); ValidateComputerName(resolvedComputerNames); // Do for each machine for (int i = 0; i < resolvedComputerNames.Length; i++) { try { WSManConnectionInfo connectionInfo = null; connectionInfo = new WSManConnectionInfo(); string scheme = UseSSL.IsPresent ? WSManConnectionInfo.HttpsScheme : WSManConnectionInfo.HttpScheme; connectionInfo.ComputerName = resolvedComputerNames[i]; connectionInfo.Port = Port; connectionInfo.AppName = ApplicationName; connectionInfo.ShellUri = ConfigurationName; connectionInfo.Scheme = scheme; if (CertificateThumbprint != null) { connectionInfo.CertificateThumbprint = CertificateThumbprint; } else { connectionInfo.Credential = Credential; } connectionInfo.AuthenticationMechanism = Authentication; UpdateConnectionInfo(connectionInfo); connectionInfo.EnableNetworkAccess = EnableNetworkAccess; // Create new remote runspace with name and Id. int rsId; string rsName = GetRunspaceName(i, out rsId); RemoteRunspace runspace = new RemoteRunspace( Utils.GetTypeTableFromExecutionContextTLS(), connectionInfo, this.Host, this.SessionOption.ApplicationArguments, rsName, rsId); remoteRunspaces.Add(runspace); } catch (UriFormatException e) { PipelineWriter writer = _stream.ObjectWriter; ErrorRecord errorRecord = new ErrorRecord(e, "CreateRemoteRunspaceFailed", ErrorCategory.InvalidArgument, resolvedComputerNames[i]); Action<Cmdlet> errorWriter = delegate (Cmdlet cmdlet) { cmdlet.WriteError(errorRecord); }; writer.Write(errorWriter); } }// end of for return remoteRunspaces; }// CreateRunspacesWhenComputerNameParameterSpecified
} // CreateRunspacesWhenRunspaceParameterSpecified /// <summary> /// Creates the remote runspace objects when the URI parameter /// is specified /// </summary> private List<RemoteRunspace> CreateRunspacesWhenUriParameterSpecified() { List<RemoteRunspace> remoteRunspaces = new List<RemoteRunspace>(); // parse the Uri to obtain information about the runspace // required for (int i = 0; i < ConnectionUri.Length; i++) { try { WSManConnectionInfo connectionInfo = new WSManConnectionInfo(); connectionInfo.ConnectionUri = ConnectionUri[i]; connectionInfo.ShellUri = ConfigurationName; if (CertificateThumbprint != null) { connectionInfo.CertificateThumbprint = CertificateThumbprint; } else { connectionInfo.Credential = Credential; } connectionInfo.AuthenticationMechanism = Authentication; UpdateConnectionInfo(connectionInfo); connectionInfo.EnableNetworkAccess = EnableNetworkAccess; // Create new remote runspace with name and Id. int rsId; string rsName = GetRunspaceName(i, out rsId); RemoteRunspace remoteRunspace = new RemoteRunspace( Utils.GetTypeTableFromExecutionContextTLS(), connectionInfo, this.Host, this.SessionOption.ApplicationArguments, rsName, rsId); Dbg.Assert(remoteRunspace != null, "RemoteRunspace object created using URI is null"); remoteRunspaces.Add(remoteRunspace); } catch (UriFormatException e) { WriteErrorCreateRemoteRunspaceFailed(e, ConnectionUri[i]); } catch (InvalidOperationException e) { WriteErrorCreateRemoteRunspaceFailed(e, ConnectionUri[i]); } catch (ArgumentException e) { WriteErrorCreateRemoteRunspaceFailed(e, ConnectionUri[i]); } catch (NotSupportedException e) { WriteErrorCreateRemoteRunspaceFailed(e, ConnectionUri[i]); } } // for... return remoteRunspaces; } // CreateRunspacesWhenUriParameterSpecified
private List<RemoteRunspace> CreateRunspacesWhenRunspaceParameterSpecified() { List<RemoteRunspace> remoteRunspaces = new List<RemoteRunspace>(); // validate the runspaces specified before processing them. // The function will result in terminating errors, if any // validation failure is encountered ValidateRemoteRunspacesSpecified(); int rsIndex = 0; foreach (PSSession remoteRunspaceInfo in _remoteRunspaceInfos) { if (remoteRunspaceInfo == null || remoteRunspaceInfo.Runspace == null) { ThrowTerminatingError(new ErrorRecord( new ArgumentNullException("PSSession"), "PSSessionArgumentNull", ErrorCategory.InvalidArgument, null)); } else { // clone the object based on what's specified in the input parameter try { RemoteRunspace remoteRunspace = (RemoteRunspace)remoteRunspaceInfo.Runspace; RunspaceConnectionInfo newConnectionInfo = null; if (remoteRunspace.ConnectionInfo is VMConnectionInfo) { newConnectionInfo = remoteRunspace.ConnectionInfo.InternalCopy(); } else if (remoteRunspace.ConnectionInfo is ContainerConnectionInfo) { ContainerConnectionInfo newContainerConnectionInfo = remoteRunspace.ConnectionInfo.InternalCopy() as ContainerConnectionInfo; newContainerConnectionInfo.CreateContainerProcess(); newConnectionInfo = newContainerConnectionInfo; } else { // WSMan case WSManConnectionInfo originalWSManConnectionInfo = remoteRunspace.ConnectionInfo as WSManConnectionInfo; WSManConnectionInfo newWSManConnectionInfo = null; if (null != originalWSManConnectionInfo) { newWSManConnectionInfo = originalWSManConnectionInfo.Copy(); newWSManConnectionInfo.EnableNetworkAccess = (newWSManConnectionInfo.EnableNetworkAccess || EnableNetworkAccess) ? true : false; newConnectionInfo = newWSManConnectionInfo; } else { Uri connectionUri = WSManConnectionInfo.ExtractPropertyAsWsManConnectionInfo<Uri>(remoteRunspace.ConnectionInfo, "ConnectionUri", null); string shellUri = WSManConnectionInfo.ExtractPropertyAsWsManConnectionInfo<string>(remoteRunspace.ConnectionInfo, "ShellUri", string.Empty); newWSManConnectionInfo = new WSManConnectionInfo(connectionUri, shellUri, remoteRunspace.ConnectionInfo.Credential); UpdateConnectionInfo(newWSManConnectionInfo); newWSManConnectionInfo.EnableNetworkAccess = EnableNetworkAccess; newConnectionInfo = newWSManConnectionInfo; } } RemoteRunspacePoolInternal rrsPool = remoteRunspace.RunspacePool.RemoteRunspacePoolInternal; TypeTable typeTable = null; if ((rrsPool != null) && (rrsPool.DataStructureHandler != null) && (rrsPool.DataStructureHandler.TransportManager != null)) { typeTable = rrsPool.DataStructureHandler.TransportManager.Fragmentor.TypeTable; } // Create new remote runspace with name and Id. int rsId; string rsName = GetRunspaceName(rsIndex, out rsId); RemoteRunspace newRemoteRunspace = new RemoteRunspace( typeTable, newConnectionInfo, this.Host, this.SessionOption.ApplicationArguments, rsName, rsId); remoteRunspaces.Add(newRemoteRunspace); } catch (UriFormatException e) { PipelineWriter writer = _stream.ObjectWriter; ErrorRecord errorRecord = new ErrorRecord(e, "CreateRemoteRunspaceFailed", ErrorCategory.InvalidArgument, remoteRunspaceInfo); Action<Cmdlet> errorWriter = delegate (Cmdlet cmdlet) { cmdlet.WriteError(errorRecord); }; writer.Write(errorWriter); } } ++rsIndex; } // foreach return remoteRunspaces; } // CreateRunspacesWhenRunspaceParameterSpecified
/// <summary> /// Check the powershell version of the remote server /// </summary> private string GetRemoteServerPsVersion(RemoteRunspace remoteRunspace) { if (remoteRunspace.ConnectionInfo is NewProcessConnectionInfo) { // This is for Start-Job. The remote end is actually a child local powershell process, so it must be PSv5 or later return PSv5OrLater; } PSPrimitiveDictionary psApplicationPrivateData = remoteRunspace.GetApplicationPrivateData(); if (psApplicationPrivateData == null) { // The remote runspace is not opened yet, or it's disconnected before the private data is retrieved. // In this case we cannot validate if the remote server is running PSv5 or later, so for safety purpose, // we will handle the $using expressions as if the remote server is PSv2. return PSv2; } // Unfortunately, the PSVersion value in the private data from PSv3 and PSv4 server is always 2.0. // This got fixed in PSv5, so a PSv5 server will return 5.0. That means we need other way to tell // if the remote server is PSv2 or PSv3+. After PSv3, remote runspace supports connect/disconnect, // so we can use it to differentiate PSv2 from PSv3+. if (remoteRunspace.CanDisconnect) { Version serverPsVersion = null; PSPrimitiveDictionary.TryPathGet( psApplicationPrivateData, out serverPsVersion, PSVersionInfo.PSVersionTableName, PSVersionInfo.PSVersionName); if (serverPsVersion != null) { return serverPsVersion.Major >= 5 ? PSv5OrLater : PSv3Orv4; } // The private data is available but we failed to get the server powershell version. // This should never happen, but in case it happens, handle the $using expressions // as if the remote server is PSv2. Dbg.Assert(false, "Application private data is available but we failed to get the server powershell version. This should never happen."); } return PSv2; }
private List<RemoteRunspace> CreateRunspacesWhenRunspaceParameterSpecified() { List<RemoteRunspace> list = new List<RemoteRunspace>(); base.ValidateRemoteRunspacesSpecified(); int rsIndex = 0; foreach (PSSession session in this.remoteRunspaceInfos) { if ((session == null) || (session.Runspace == null)) { base.ThrowTerminatingError(new ErrorRecord(new ArgumentNullException("PSSession"), "PSSessionArgumentNull", ErrorCategory.InvalidArgument, null)); } else { try { int num2; RemoteRunspace runspace = (RemoteRunspace) session.Runspace; WSManConnectionInfo connectionInfo = runspace.ConnectionInfo as WSManConnectionInfo; WSManConnectionInfo info2 = null; if (connectionInfo != null) { info2 = connectionInfo.Copy(); info2.EnableNetworkAccess = info2.EnableNetworkAccess || (this.EnableNetworkAccess != false); } else { Uri uri = WSManConnectionInfo.ExtractPropertyAsWsManConnectionInfo<Uri>(runspace.ConnectionInfo, "ConnectionUri", null); string shellUri = WSManConnectionInfo.ExtractPropertyAsWsManConnectionInfo<string>(runspace.ConnectionInfo, "ShellUri", string.Empty); info2 = new WSManConnectionInfo(uri, shellUri, runspace.ConnectionInfo.Credential); base.UpdateConnectionInfo(info2); info2.EnableNetworkAccess = (bool) this.EnableNetworkAccess; } RemoteRunspacePoolInternal remoteRunspacePoolInternal = runspace.RunspacePool.RemoteRunspacePoolInternal; TypeTable typeTable = null; if (((remoteRunspacePoolInternal != null) && (remoteRunspacePoolInternal.DataStructureHandler != null)) && (remoteRunspacePoolInternal.DataStructureHandler.TransportManager != null)) { typeTable = remoteRunspacePoolInternal.DataStructureHandler.TransportManager.Fragmentor.TypeTable; } string runspaceName = this.GetRunspaceName(rsIndex, out num2); RemoteRunspace item = new RemoteRunspace(typeTable, info2, base.Host, this.SessionOption.ApplicationArguments, runspaceName, num2); list.Add(item); } catch (UriFormatException exception) { PipelineWriter objectWriter = this.stream.ObjectWriter; ErrorRecord errorRecord = new ErrorRecord(exception, "CreateRemoteRunspaceFailed", ErrorCategory.InvalidArgument, session); Action<Cmdlet> action = delegate (Cmdlet cmdlet) { cmdlet.WriteError(errorRecord); }; objectWriter.Write(action); } } rsIndex++; } return list; }
} // RaiseOperationCompleteEvent /// <summary> /// Raise an operation complete event. /// </summary> /// <param name="baseEventArgs">The event args which actually /// raises this operation complete</param> private void RaiseOperationCompleteEvent(EventArgs baseEventArgs) { if (pipeline != null) { // Dispose the pipeline object and release data and remoting resources. // Pipeline object remains to provide information on final state and any errors incurred. pipeline.StateChanged -= new EventHandler<PipelineStateEventArgs>(HandlePipelineStateChanged); pipeline.Dispose(); } if (RemoteRunspace != null) { // Dispose of the runspace object. RemoteRunspace.Dispose(); RemoteRunspace = null; } OperationStateEventArgs operationStateEventArgs = new OperationStateEventArgs(); operationStateEventArgs.OperationState = OperationState.StopComplete; operationStateEventArgs.BaseEvent = baseEventArgs; OperationComplete.SafeInvoke(this, operationStateEventArgs); } // RaiseOperationCompleteEvent
private void DisconnectAndStopRunningCmds(RemoteRunspace remoteRunspace) { // Disconnect runspace to stop command from running and to allow reconnect // via the Enter-PSSession cmdlet. if (remoteRunspace.RunspaceStateInfo.State == RunspaceState.Opened) { Job job; ManualResetEvent stopPipelineReceive; lock (_syncObject) { job = _job; stopPipelineReceive = _stopPipelineReceive; } remoteRunspace.Disconnect(); if (stopPipelineReceive != null) { try { stopPipelineReceive.Set(); } catch (ObjectDisposedException) { } } if (job != null) { job.StopJob(); } } }
internal void Override(RemoteRunspace remoteRunspace, object syncObject, out bool isRunspacePushed) { lock (this._localSyncObject) { this._stopInvoke = false; } try { if (syncObject != null) { lock (syncObject) { this._runspaceRef.Override(remoteRunspace); isRunspacePushed = true; goto Label_0063; } } this._runspaceRef.Override(remoteRunspace); isRunspacePushed = true; Label_0063: using (PowerShell shell = PowerShell.Create()) { shell.AddCommand("Get-Command"); shell.AddParameter("Name", new string[] { "Out-Default", "Exit-PSSession" }); shell.Runspace = this._runspaceRef.Value; bool flag2 = this._runspaceRef.Value.GetRemoteProtocolVersion() == RemotingConstants.ProtocolVersionWin7RC; shell.IsGetCommandMetadataSpecialPipeline = !flag2; int num = flag2 ? 2 : 3; shell.RemotePowerShell.HostCallReceived += new EventHandler<RemoteDataEventArgs<RemoteHostCall>>(this.HandleHostCall); IAsyncResult asyncResult = shell.BeginInvoke(); PSDataCollection<PSObject> datas = new PSDataCollection<PSObject>(); while (!this._stopInvoke) { asyncResult.AsyncWaitHandle.WaitOne(0x3e8); if (asyncResult.IsCompleted) { datas = shell.EndInvoke(asyncResult); break; } } if ((shell.Streams.Error.Count > 0) || (datas.Count < num)) { throw RemoteHostExceptions.NewRemoteRunspaceDoesNotSupportPushRunspaceException(); } return; } } catch (Exception) { this._runspaceRef.Revert(); isRunspacePushed = false; throw; } }
private Runspace CreateNamedPipeRunspace(int procId, string appDomainName) { NamedPipeConnectionInfo connectionInfo = new NamedPipeConnectionInfo(procId, appDomainName); TypeTable typeTable = TypeTable.LoadDefaultTypeFiles(); RemoteRunspace remoteRunspace = RunspaceFactory.CreateRunspace(connectionInfo, this.Host, typeTable) as RemoteRunspace; remoteRunspace.Name = NamedPipeRunspaceName; remoteRunspace.ShouldCloseOnPop = true; _connectingRemoteRunspace = remoteRunspace; try { remoteRunspace.Open(); remoteRunspace.Debugger.SetDebugMode(DebugModes.LocalScript | DebugModes.RemoteScript); } catch (RuntimeException e) { string msgAppDomainName = (!string.IsNullOrEmpty(appDomainName)) ? appDomainName : NamedPipeUtils.DefaultAppDomainName; // Unwrap inner exception for original error message, if any. string errorMessage = (e.InnerException != null) ? (e.InnerException.Message ?? string.Empty) : string.Empty; ThrowTerminatingError( new ErrorRecord( new RuntimeException( StringUtil.Format(RemotingErrorIdStrings.EnterPSHostProcessCannotConnectToProcess, msgAppDomainName, procId, errorMessage), e.InnerException), "EnterPSHostProcessCannotConnectToProcess", ErrorCategory.OperationTimeout, this)); } finally { _connectingRemoteRunspace = null; } return remoteRunspace; }