Cross Version PowerShell Remoting
In this issue:
- Overview
- Introduction
- Watch Your Version
- SessionConfigurations
- PowerShell 7 Configuration Cleanup
- PowerShell Remoting with ssh
- Mixed Sessions
- Summary
Overview
This article explains how PowerShell remoting connects to a remote host through WSMan session configurations, and the default endpoint usually runs Windows PowerShell 5.1. If you start a remoting session from PowerShell 7, you may unexpectedly land in a Windows PowerShell session unless you explicitly connect to a PowerShell 7 endpoint. PowerShell remoting sessions are version-specific, with profiles not loaded, and that PowerShell 7 creates its own remoting endpoints only when enabled in that version. The key takeaway is to check the configured endpoint and version before assuming remote commands will work as expected across systems and hosts.
Introduction
One of PowerShell's best features is remoting. This is the ability to execute commands on a remote machine just as if you were sitting at the console. It also doesn't matter how many remote machines you want to manage. It is just as easy to run a command or script remotely on one or 100 servers.
Traditional PowerShell remoting relies on the WSMan protocol and uses the WinRM service among other things to manage the remote connection and command execution. You've likely been using PowerShell remoting with Windows PowerShell for quite a while.
However, now that we have PowerShell 7 in the mix, you might need to pay closer attention to your remoting commands. I'm not going to cover setting up and configuring PowerShell remoting, but I want to point out some potential issues. This lesson assumes that your organization hasn't customized or configured PowerShell remoting much beyond the basics. I can't guarantee that you will be able to run all of my examples, but hopefully you will still recognize the points I am trying to make.
For the sake of simplicity, I am going to test PowerShell remoting connections to the localhost. You can test remoting commands by connecting to your own computer.
Watch Your Version
Let's start with a remoting scenario we've used for years. You are in a Windows PowerShell 5.1 session connecting to another computer.
PS C:\> Enter-PSSession $env:COMPUTERNAME
[CADENZA]: PS C:\Users\jeff\Documents>
The prompt indicates the remote connection. In the remote connection I can verify that I am in a Windows PowerShell session.
[CADENZA]: PS C:\Users\jeff\Documents> $PSEdition
Desktop
[CADENZA]: PS C:\Users\jeff\Documents> $PSVersionTable
Name Value
---- -----
PSVersion 5.1.26100.9549
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
BuildVersion 10.0.26100.9549
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
I can also test the hosting application:
[CADENZA]: PS C:\Users\jeff\Documents> Get-Host
Name : ServerRemoteHost
Version : 1.0.0.0
InstanceId : 4f2734d2-60ce-4a17-97d2-2552702ee670
UI : System.Management.Automation.Internal.Host.InternalHostUserInterface
CurrentCulture : en-US
CurrentUICulture : en-US
PrivateData :
DebuggerEnabled : True
IsRunspacePushed : False
Runspace : System.Management.Automation.Runspaces.LocalRunspace
As a reminder, in PowerShell remoting, profile scripts do not apply. The $profile variable isn't even defined.
[CADENZA]: PS C:\Users\jeff\Documents> Get-Variable profile
Get-Variable : Cannot find a variable with the name 'profile'.
+ CategoryInfo : ObjectNotFound: (profile:String) [Get-Variable], ItemNotFoundException
+ FullyQualifiedErrorId : VariableNotFound,Microsoft.PowerShell.Commands.GetVariableCommand
Regardless, I know that I can run Windows PowerShell commands in the remoting session. When finished, I'll type exit.
However, like many of you I am also running PowerShell 7 which also support remoting. I'm going to repeat the process, but from a PowerShell 7 session.
PS C:\> $PSEdition
Core
PS C:\> Enter-PSSession $env:COMPUTERNAME
[CADENZA]: PS C:\Users\jeff\Documents>
The prompt changes as expected, but everything else may not be what you expect.
[CADENZA]: PS C:\Users\jeff\Documents> $PSEdition
Desktop
[CADENZA]: PS C:\Users\jeff\Documents> $PSVersionTable
Name Value
---- -----
PSVersion 5.1.26100.9549
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
BuildVersion 10.0.26100.9549
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
[CADENZA]: PS C:\Users\jeff\Documents> Get-Host
Name : ServerRemoteHost
Version : 1.0.0.0
InstanceId : c8557524-423e-4bdd-be94-31ac1b55c0b6
UI : System.Management.Automation.Internal.Host.InternalHostUserInterface
CurrentCulture : en-US
CurrentUICulture : en-US
PrivateData :
DebuggerEnabled : True
IsRunspacePushed : False
Runspace : System.Management.Automation.Runspaces.LocalRunspace
My remote connection is to a Windows PowerShell 5.1 session which means I can't run any PowerShell 7 commands or use PowerShell 7 features like the ternary operator.
Here's what's happening.
SessionConfigurations
With traditional PowerShell remoting over WSMan, you are connection to remoting endpoint defined as a SessionConfiguration. These endpoints are configured automatically when you enable PowerShell remoting.
> It is possible to create additional and customized endpoints, which is the entire point behind Just Enough Administration, or JEA, but this is outside the scope of today's content.
The Get-PSSessionConfiguration command will display all registered endpoints.
PS C:\> Get-PSSessionConfiguration | Select-Object -first 1
Name : microsoft.powershell
PSVersion : 5.1
StartupScript :
RunAsUser :
Permission : NT AUTHORITY\INTERACTIVE AccessAllowed, BUILTIN\Administrators AccessAllowed, BUI...