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++;