mirror of
https://github.com/PowerShell/PowerShell
synced 2026-06-08 12:12:50 +00:00
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.
This commit is contained in:
@@ -275,6 +275,7 @@ namespace Microsoft.PowerShell.Commands
|
||||
public string UserName;
|
||||
public string KeyFilePath;
|
||||
public int Port;
|
||||
public string Subsystem;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -763,6 +764,13 @@ namespace Microsoft.PowerShell.Commands
|
||||
set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This parameter specifies the SSH subsystem to use for the remote connection.
|
||||
/// </summary>
|
||||
[Parameter(ValueFromPipelineByPropertyName = true,
|
||||
ParameterSetName = InvokeCommandCommand.SSHHostParameterSet)]
|
||||
public String Subsystem { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion Properties
|
||||
@@ -822,6 +830,7 @@ namespace Microsoft.PowerShell.Commands
|
||||
private const string KeyFilePathParameter = "KeyFilePath";
|
||||
private const string IdentityFilePathAlias = "IdentityFilePath";
|
||||
private const string PortParameter = "Port";
|
||||
private const string SubsystemParameter = "Subsystem";
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -915,6 +924,10 @@ namespace Microsoft.PowerShell.Commands
|
||||
{
|
||||
connectionInfo.Port = GetSSHConnectionIntParameter(item[paramName]);
|
||||
}
|
||||
else if (paramName.Equals(SubsystemParameter, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
connectionInfo.Subsystem = GetSSHConnectionStringParameter(item[paramName]);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new PSArgumentException(
|
||||
@@ -1385,7 +1398,7 @@ namespace Microsoft.PowerShell.Commands
|
||||
{
|
||||
ParseSshHostName(computerName, out string host, out string userName, out int port);
|
||||
|
||||
var sshConnectionInfo = new SSHConnectionInfo(userName, host, this.KeyFilePath, port);
|
||||
var sshConnectionInfo = new SSHConnectionInfo(userName, host, this.KeyFilePath, port, this.Subsystem);
|
||||
var typeTable = TypeTable.LoadDefaultTypeFiles();
|
||||
var remoteRunspace = RunspaceFactory.CreateRunspace(sshConnectionInfo, this.Host, typeTable) as RemoteRunspace;
|
||||
var pipeline = CreatePipeline(remoteRunspace);
|
||||
@@ -1407,7 +1420,8 @@ namespace Microsoft.PowerShell.Commands
|
||||
sshConnection.UserName,
|
||||
sshConnection.ComputerName,
|
||||
sshConnection.KeyFilePath,
|
||||
sshConnection.Port);
|
||||
sshConnection.Port,
|
||||
sshConnection.Subsystem);
|
||||
var typeTable = TypeTable.LoadDefaultTypeFiles();
|
||||
var remoteRunspace = RunspaceFactory.CreateRunspace(sshConnectionInfo, this.Host, typeTable) as RemoteRunspace;
|
||||
var pipeline = CreatePipeline(remoteRunspace);
|
||||
|
||||
@@ -1282,7 +1282,7 @@ namespace Microsoft.PowerShell.Commands
|
||||
private RemoteRunspace GetRunspaceForSSHSession()
|
||||
{
|
||||
ParseSshHostName(HostName, out string host, out string userName, out int port);
|
||||
var sshConnectionInfo = new SSHConnectionInfo(userName, host, this.KeyFilePath, port);
|
||||
var sshConnectionInfo = new SSHConnectionInfo(userName, host, this.KeyFilePath, port, this.Subsystem);
|
||||
var typeTable = TypeTable.LoadDefaultTypeFiles();
|
||||
|
||||
// Use the class _tempRunspace field while the runspace is being opened so that StopProcessing can be handled at that time.
|
||||
|
||||
@@ -1080,7 +1080,8 @@ namespace Microsoft.PowerShell.Commands
|
||||
userName,
|
||||
host,
|
||||
this.KeyFilePath,
|
||||
port);
|
||||
port,
|
||||
Subsystem);
|
||||
var typeTable = TypeTable.LoadDefaultTypeFiles();
|
||||
string rsName = GetRunspaceName(index, out int rsIdUnused);
|
||||
index++;
|
||||
@@ -1105,7 +1106,8 @@ namespace Microsoft.PowerShell.Commands
|
||||
sshConnection.UserName,
|
||||
sshConnection.ComputerName,
|
||||
sshConnection.KeyFilePath,
|
||||
sshConnection.Port);
|
||||
sshConnection.Port,
|
||||
sshConnection.Subsystem);
|
||||
var typeTable = TypeTable.LoadDefaultTypeFiles();
|
||||
string rsName = GetRunspaceName(index, out int rsIdUnused);
|
||||
index++;
|
||||
|
||||
@@ -1867,6 +1867,15 @@ namespace System.Management.Automation.Runspaces
|
||||
set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Subsystem to use
|
||||
/// </summary>
|
||||
private string Subsystem
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
@@ -1894,6 +1903,7 @@ namespace System.Management.Automation.Runspaces
|
||||
this.ComputerName = computerName;
|
||||
this.KeyFilePath = keyFilePath;
|
||||
this.Port = DefaultPort;
|
||||
this.Subsystem = DefaultSubsystem;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1903,15 +1913,18 @@ namespace System.Management.Automation.Runspaces
|
||||
/// <param name="computerName">Computer Name</param>
|
||||
/// <param name="keyFilePath">Key File Path</param>
|
||||
/// <param name="port">Port number for connection (default 22)</param>
|
||||
/// <param name="subsystem">Subsystem to use (default 'powershell')</param>
|
||||
public SSHConnectionInfo(
|
||||
string userName,
|
||||
string computerName,
|
||||
string keyFilePath,
|
||||
int port) : this(userName, computerName, keyFilePath)
|
||||
int port,
|
||||
string subsystem) : this(userName, computerName, keyFilePath)
|
||||
{
|
||||
ValidatePortInRange(port);
|
||||
|
||||
this.Port = (port != 0) ? port : DefaultPort;
|
||||
this.Subsystem = (String.IsNullOrEmpty(subsystem)) ? DefaultSubsystem : subsystem;
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -1965,6 +1978,7 @@ namespace System.Management.Automation.Runspaces
|
||||
newCopy.UserName = this.UserName;
|
||||
newCopy.KeyFilePath = this.KeyFilePath;
|
||||
newCopy.Port = this.Port;
|
||||
newCopy.Subsystem = this.Subsystem;
|
||||
|
||||
return newCopy;
|
||||
}
|
||||
@@ -2040,14 +2054,14 @@ namespace System.Management.Automation.Runspaces
|
||||
}
|
||||
|
||||
arguments = (string.IsNullOrEmpty(domainName)) ?
|
||||
string.Format(CultureInfo.InvariantCulture, @"-i ""{0}"" {1}@{2} -p {3} -s powershell", this.KeyFilePath, userName, this.ComputerName, this.Port) :
|
||||
string.Format(CultureInfo.InvariantCulture, @"-i ""{0}"" -l {1}@{2} {3} -p {4} -s powershell", this.KeyFilePath, userName, domainName, this.ComputerName, this.Port);
|
||||
string.Format(CultureInfo.InvariantCulture, @"-i ""{0}"" {1}@{2} -p {3} -s {4}", this.KeyFilePath, userName, this.ComputerName, this.Port, this.Subsystem) :
|
||||
string.Format(CultureInfo.InvariantCulture, @"-i ""{0}"" -l {1}@{2} {3} -p {4} -s {5}", this.KeyFilePath, userName, domainName, this.ComputerName, this.Port, this.Subsystem);
|
||||
}
|
||||
else
|
||||
{
|
||||
arguments = (string.IsNullOrEmpty(domainName)) ?
|
||||
string.Format(CultureInfo.InvariantCulture, @"{0}@{1} -p {2} -s powershell", userName, this.ComputerName, this.Port) :
|
||||
string.Format(CultureInfo.InvariantCulture, @"-l {0}@{1} {2} -p {3} -s powershell", userName, domainName, this.ComputerName, this.Port);
|
||||
string.Format(CultureInfo.InvariantCulture, @"{0}@{1} -p {2} -s {3}", userName, this.ComputerName, this.Port, this.Subsystem) :
|
||||
string.Format(CultureInfo.InvariantCulture, @"-l {0}@{1} {2} -p {3} -s {4}", userName, domainName, this.ComputerName, this.Port, this.Subsystem);
|
||||
}
|
||||
|
||||
System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo(
|
||||
@@ -2082,6 +2096,11 @@ namespace System.Management.Automation.Runspaces
|
||||
/// </summary>
|
||||
private const int DefaultPort = 22;
|
||||
|
||||
/// <summary>
|
||||
/// Default value for subsystem
|
||||
/// </summary>
|
||||
private const string DefaultSubsystem = "powershell";
|
||||
|
||||
#endregion
|
||||
|
||||
#region SSH Process Creation
|
||||
|
||||
Reference in New Issue
Block a user