Skip to content

Commit c80cecf

Browse files
SteveL-MSFTTravisEz13
authored andcommitted
Enable specifying sshd subsystem to use via -Subsystem (#6603)
The current implementation of PSRP over SSH only enables remoting to one version of PowerShell Core 6. sshd_config allows specifying multiple subsystems that can start different versions of PowerShell Core 6 (or same versions with different parameters). Enable use of a new -Subsystem parameter to specify the subsystem to use with ssh.
1 parent 313a859 commit c80cecf

4 files changed

Lines changed: 45 additions & 10 deletions

File tree

src/System.Management.Automation/engine/remoting/commands/PSRemotingCmdlet.cs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,7 @@ internal struct SSHConnection
275275
public string UserName;
276276
public string KeyFilePath;
277277
public int Port;
278+
public string Subsystem;
278279
}
279280

280281
/// <summary>
@@ -763,6 +764,13 @@ public virtual Hashtable[] SSHConnection
763764
set;
764765
}
765766

767+
/// <summary>
768+
/// This parameter specifies the SSH subsystem to use for the remote connection.
769+
/// </summary>
770+
[Parameter(ValueFromPipelineByPropertyName = true,
771+
ParameterSetName = InvokeCommandCommand.SSHHostParameterSet)]
772+
public String Subsystem { get; set; }
773+
766774
#endregion
767775

768776
#endregion Properties
@@ -822,6 +830,7 @@ internal static void ValidateSpecifiedAuthentication(PSCredential credential, st
822830
private const string KeyFilePathParameter = "KeyFilePath";
823831
private const string IdentityFilePathAlias = "IdentityFilePath";
824832
private const string PortParameter = "Port";
833+
private const string SubsystemParameter = "Subsystem";
825834

826835
#endregion
827836

@@ -915,6 +924,10 @@ internal SSHConnection[] ParseSSHConnectionHashTable()
915924
{
916925
connectionInfo.Port = GetSSHConnectionIntParameter(item[paramName]);
917926
}
927+
else if (paramName.Equals(SubsystemParameter, StringComparison.OrdinalIgnoreCase))
928+
{
929+
connectionInfo.Subsystem = GetSSHConnectionStringParameter(item[paramName]);
930+
}
918931
else
919932
{
920933
throw new PSArgumentException(
@@ -1385,7 +1398,7 @@ protected void CreateHelpersForSpecifiedSSHComputerNames()
13851398
{
13861399
ParseSshHostName(computerName, out string host, out string userName, out int port);
13871400

1388-
var sshConnectionInfo = new SSHConnectionInfo(userName, host, this.KeyFilePath, port);
1401+
var sshConnectionInfo = new SSHConnectionInfo(userName, host, this.KeyFilePath, port, this.Subsystem);
13891402
var typeTable = TypeTable.LoadDefaultTypeFiles();
13901403
var remoteRunspace = RunspaceFactory.CreateRunspace(sshConnectionInfo, this.Host, typeTable) as RemoteRunspace;
13911404
var pipeline = CreatePipeline(remoteRunspace);
@@ -1407,7 +1420,8 @@ protected void CreateHelpersForSpecifiedSSHHashComputerNames()
14071420
sshConnection.UserName,
14081421
sshConnection.ComputerName,
14091422
sshConnection.KeyFilePath,
1410-
sshConnection.Port);
1423+
sshConnection.Port,
1424+
sshConnection.Subsystem);
14111425
var typeTable = TypeTable.LoadDefaultTypeFiles();
14121426
var remoteRunspace = RunspaceFactory.CreateRunspace(sshConnectionInfo, this.Host, typeTable) as RemoteRunspace;
14131427
var pipeline = CreatePipeline(remoteRunspace);

src/System.Management.Automation/engine/remoting/commands/PushRunspaceCommand.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1282,7 +1282,7 @@ private RemoteRunspace GetRunspaceForContainerSession()
12821282
private RemoteRunspace GetRunspaceForSSHSession()
12831283
{
12841284
ParseSshHostName(HostName, out string host, out string userName, out int port);
1285-
var sshConnectionInfo = new SSHConnectionInfo(userName, host, this.KeyFilePath, port);
1285+
var sshConnectionInfo = new SSHConnectionInfo(userName, host, this.KeyFilePath, port, this.Subsystem);
12861286
var typeTable = TypeTable.LoadDefaultTypeFiles();
12871287

12881288
// Use the class _tempRunspace field while the runspace is being opened so that StopProcessing can be handled at that time.

src/System.Management.Automation/engine/remoting/commands/newrunspacecommand.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1080,7 +1080,8 @@ private List<RemoteRunspace> CreateRunspacesForSSHHostParameterSet()
10801080
userName,
10811081
host,
10821082
this.KeyFilePath,
1083-
port);
1083+
port,
1084+
Subsystem);
10841085
var typeTable = TypeTable.LoadDefaultTypeFiles();
10851086
string rsName = GetRunspaceName(index, out int rsIdUnused);
10861087
index++;
@@ -1105,7 +1106,8 @@ private List<RemoteRunspace> CreateRunspacesForSSHHostHashParameterSet()
11051106
sshConnection.UserName,
11061107
sshConnection.ComputerName,
11071108
sshConnection.KeyFilePath,
1108-
sshConnection.Port);
1109+
sshConnection.Port,
1110+
sshConnection.Subsystem);
11091111
var typeTable = TypeTable.LoadDefaultTypeFiles();
11101112
string rsName = GetRunspaceName(index, out int rsIdUnused);
11111113
index++;

src/System.Management.Automation/engine/remoting/common/RunspaceConnectionInfo.cs

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1867,6 +1867,15 @@ private int Port
18671867
set;
18681868
}
18691869

1870+
/// <summary>
1871+
/// Subsystem to use
1872+
/// </summary>
1873+
private string Subsystem
1874+
{
1875+
get;
1876+
set;
1877+
}
1878+
18701879
#endregion
18711880

18721881
#region Constructors
@@ -1894,6 +1903,7 @@ public SSHConnectionInfo(
18941903
this.ComputerName = computerName;
18951904
this.KeyFilePath = keyFilePath;
18961905
this.Port = DefaultPort;
1906+
this.Subsystem = DefaultSubsystem;
18971907
}
18981908

18991909
/// <summary>
@@ -1903,15 +1913,18 @@ public SSHConnectionInfo(
19031913
/// <param name="computerName">Computer Name</param>
19041914
/// <param name="keyFilePath">Key File Path</param>
19051915
/// <param name="port">Port number for connection (default 22)</param>
1916+
/// <param name="subsystem">Subsystem to use (default 'powershell')</param>
19061917
public SSHConnectionInfo(
19071918
string userName,
19081919
string computerName,
19091920
string keyFilePath,
1910-
int port) : this(userName, computerName, keyFilePath)
1921+
int port,
1922+
string subsystem) : this(userName, computerName, keyFilePath)
19111923
{
19121924
ValidatePortInRange(port);
19131925

19141926
this.Port = (port != 0) ? port : DefaultPort;
1927+
this.Subsystem = (String.IsNullOrEmpty(subsystem)) ? DefaultSubsystem : subsystem;
19151928
}
19161929

19171930
#endregion
@@ -1965,6 +1978,7 @@ internal override RunspaceConnectionInfo InternalCopy()
19651978
newCopy.UserName = this.UserName;
19661979
newCopy.KeyFilePath = this.KeyFilePath;
19671980
newCopy.Port = this.Port;
1981+
newCopy.Subsystem = this.Subsystem;
19681982

19691983
return newCopy;
19701984
}
@@ -2040,14 +2054,14 @@ internal int StartSSHProcess(
20402054
}
20412055

20422056
arguments = (string.IsNullOrEmpty(domainName)) ?
2043-
string.Format(CultureInfo.InvariantCulture, @"-i ""{0}"" {1}@{2} -p {3} -s powershell", this.KeyFilePath, userName, this.ComputerName, this.Port) :
2044-
string.Format(CultureInfo.InvariantCulture, @"-i ""{0}"" -l {1}@{2} {3} -p {4} -s powershell", this.KeyFilePath, userName, domainName, this.ComputerName, this.Port);
2057+
string.Format(CultureInfo.InvariantCulture, @"-i ""{0}"" {1}@{2} -p {3} -s {4}", this.KeyFilePath, userName, this.ComputerName, this.Port, this.Subsystem) :
2058+
string.Format(CultureInfo.InvariantCulture, @"-i ""{0}"" -l {1}@{2} {3} -p {4} -s {5}", this.KeyFilePath, userName, domainName, this.ComputerName, this.Port, this.Subsystem);
20452059
}
20462060
else
20472061
{
20482062
arguments = (string.IsNullOrEmpty(domainName)) ?
2049-
string.Format(CultureInfo.InvariantCulture, @"{0}@{1} -p {2} -s powershell", userName, this.ComputerName, this.Port) :
2050-
string.Format(CultureInfo.InvariantCulture, @"-l {0}@{1} {2} -p {3} -s powershell", userName, domainName, this.ComputerName, this.Port);
2063+
string.Format(CultureInfo.InvariantCulture, @"{0}@{1} -p {2} -s {3}", userName, this.ComputerName, this.Port, this.Subsystem) :
2064+
string.Format(CultureInfo.InvariantCulture, @"-l {0}@{1} {2} -p {3} -s {4}", userName, domainName, this.ComputerName, this.Port, this.Subsystem);
20512065
}
20522066

20532067
System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo(
@@ -2082,6 +2096,11 @@ private string GetCurrentUserName()
20822096
/// </summary>
20832097
private const int DefaultPort = 22;
20842098

2099+
/// <summary>
2100+
/// Default value for subsystem
2101+
/// </summary>
2102+
private const string DefaultSubsystem = "powershell";
2103+
20852104
#endregion
20862105

20872106
#region SSH Process Creation

0 commit comments

Comments
 (0)