diff --git a/src/System.Management.Automation/engine/remoting/commands/PSRemotingCmdlet.cs b/src/System.Management.Automation/engine/remoting/commands/PSRemotingCmdlet.cs index b7fa3ffd81c..9ba8e7186b8 100644 --- a/src/System.Management.Automation/engine/remoting/commands/PSRemotingCmdlet.cs +++ b/src/System.Management.Automation/engine/remoting/commands/PSRemotingCmdlet.cs @@ -825,6 +825,42 @@ internal static void ValidateSpecifiedAuthentication(PSCredential credential, st #endregion + /// + /// Parse a hostname used with SSH Transport to get embedded + /// username and/or port. + /// + /// host name to parse + /// resolved target host + /// resolved target user name + /// resolved target port + protected void ParseSshHostName(string hostname, out string host, out string userName, out int port) + { + host = hostname; + userName = this.UserName; + port = this.Port; + try + { + Uri uri = new System.Uri("ssh://" + hostname); + host = ResolveComputerName(uri.Host); + ValidateComputerName(new string[]{host}); + if (uri.UserInfo != String.Empty) + { + userName = uri.UserInfo; + } + if (uri.Port != -1) + { + port = uri.Port; + } + } + catch (UriFormatException) + { + ThrowTerminatingError(new ErrorRecord( + new ArgumentException(PSRemotingErrorInvariants.FormatResourceString( + RemotingErrorIdStrings.InvalidComputerName)), "PSSessionInvalidComputerName", + ErrorCategory.InvalidArgument, hostname)); + } + } + /// /// Parse the Connection parameter HashTable array. /// @@ -856,8 +892,16 @@ internal SSHConnection[] ParseSSHConnectionHashTable() if (paramName.Equals(ComputerNameParameter, StringComparison.OrdinalIgnoreCase) || paramName.Equals(HostNameAlias, StringComparison.OrdinalIgnoreCase)) { var resolvedComputerName = ResolveComputerName(GetSSHConnectionStringParameter(item[paramName])); - ValidateComputerName(new string[] { resolvedComputerName }); - connectionInfo.ComputerName = resolvedComputerName; + ParseSshHostName(resolvedComputerName, out string host, out string userName, out int port); + connectionInfo.ComputerName = host; + if (userName != String.Empty) + { + connectionInfo.UserName = userName; + } + if (port != -1) + { + connectionInfo.Port = port; + } } else if (paramName.Equals(UserNameParameter, StringComparison.OrdinalIgnoreCase)) { @@ -1337,11 +1381,11 @@ protected virtual void CreateHelpersForSpecifiedComputerNames() /// protected void CreateHelpersForSpecifiedSSHComputerNames() { - ValidateComputerName(ResolvedComputerNames); - foreach (string computerName in ResolvedComputerNames) { - var sshConnectionInfo = new SSHConnectionInfo(this.UserName, computerName, this.KeyFilePath, this.Port); + ParseSshHostName(computerName, out string host, out string userName, out int port); + + var sshConnectionInfo = new SSHConnectionInfo(userName, host, this.KeyFilePath, port); var typeTable = TypeTable.LoadDefaultTypeFiles(); var remoteRunspace = RunspaceFactory.CreateRunspace(sshConnectionInfo, this.Host, typeTable) as RemoteRunspace; var pipeline = CreatePipeline(remoteRunspace); diff --git a/src/System.Management.Automation/engine/remoting/commands/PushRunspaceCommand.cs b/src/System.Management.Automation/engine/remoting/commands/PushRunspaceCommand.cs index 4014863e5d3..6e26b815ec9 100644 --- a/src/System.Management.Automation/engine/remoting/commands/PushRunspaceCommand.cs +++ b/src/System.Management.Automation/engine/remoting/commands/PushRunspaceCommand.cs @@ -1281,7 +1281,8 @@ private RemoteRunspace GetRunspaceForContainerSession() /// private RemoteRunspace GetRunspaceForSSHSession() { - var sshConnectionInfo = new SSHConnectionInfo(this.UserName, ResolveComputerName(HostName), this.KeyFilePath, this.Port); + ParseSshHostName(HostName, out string host, out string userName, out int port); + var sshConnectionInfo = new SSHConnectionInfo(userName, host, this.KeyFilePath, port); var typeTable = TypeTable.LoadDefaultTypeFiles(); // Use the class _tempRunspace field while the runspace is being opened so that StopProcessing can be handled at that time. diff --git a/src/System.Management.Automation/engine/remoting/commands/newrunspacecommand.cs b/src/System.Management.Automation/engine/remoting/commands/newrunspacecommand.cs index 9cc14e2afa4..f5840c7ea9a 100644 --- a/src/System.Management.Automation/engine/remoting/commands/newrunspacecommand.cs +++ b/src/System.Management.Automation/engine/remoting/commands/newrunspacecommand.cs @@ -1067,18 +1067,20 @@ private List CreateRunspacesForSSHHostParameterSet() { // Resolve all the machine names String[] resolvedComputerNames; + ResolveComputerNames(HostName, out resolvedComputerNames); - ValidateComputerName(resolvedComputerNames); var remoteRunspaces = new List(); int index = 0; foreach (var computerName in resolvedComputerNames) { + ParseSshHostName(computerName, out string host, out string userName, out int port); + var sshConnectionInfo = new SSHConnectionInfo( - this.UserName, - computerName, + userName, + host, this.KeyFilePath, - this.Port); + port); var typeTable = TypeTable.LoadDefaultTypeFiles(); string rsName = GetRunspaceName(index, out int rsIdUnused); index++;