Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PowerShell remoting in PowerShell 7 should use PowerShell.7 endpoint by default #11616

Closed
alexandair opened this issue Jan 17, 2020 · 32 comments
Closed
Labels
Committee-Reviewed PS-Committee has reviewed this and made a decision Issue-Question ideally support can be provided via other mechanisms, but sometimes folks do open an issue to get a Resolution-Answered The question is answered. WG-Remoting PSRP issues with any transport layer
Milestone

Comments

@alexandair
Copy link
Contributor

At the moment, PowerShell remoting in PowerShell 7 is using Windows PowerShell's microsoft.powershell endpoint as the default one. That endpoint is not even visible/discoverable when you run Get-PSSessionConfiguration.

By default, targets should be PS7 endpoints and you could specify -ConfigurationName microsoft.powershell, if you really want to execute in the context of Windows PowerShell.

@alexandair alexandair added the Issue-Question ideally support can be provided via other mechanisms, but sometimes folks do open an issue to get a label Jan 17, 2020
@iSazonov iSazonov added the WG-Remoting PSRP issues with any transport layer label Jan 17, 2020
@SteveL-MSFT
Copy link
Member

This makes sense particularly as compatibility with WinPS in PS7 has improved significantly compared to PSCore6

@SteveL-MSFT SteveL-MSFT added this to the 7.1-Consider milestone Jan 17, 2020
@iSazonov
Copy link
Collaborator

In future (after we will have many PS7 installations) we could have PS7 endpoint first and fallback to WinPS one.

@alexandair
Copy link
Contributor Author

I would like to hear a reason why should PS7 fallback to WinPS endpoint.

@iSazonov
Copy link
Collaborator

We keep backward compatibility and modern management tools may work with old endpoints.

@ThomasNieto
Copy link
Contributor

This might need to go into its own issue report but Install-PowerShellRemoting.ps1 and Enable-PSRemoting create different endpoint names and might not work correctly with this feature if implemented.

@Jaykul
Copy link
Contributor

Jaykul commented Jan 19, 2020

There are many reason why WinRM should always default to "microsoft.powershell" regardless of the version of the PowerShell client:

  • This endpoint is installed and enabled by default on Windows Server -- including in Azure.
  • The default endpoint should always be the unversioned endpoint. Otherwise you'd have to know what was available on each each remote!
  • The version of PowerShell a client is running should not affect which endpoint you connect to,

You know, the other problem is that there's no other endpoint you can connect to:

  • New versions of PowerShell do not register endpoints by default. There's no point defaulting to connect to an endpoint that won't exist by default.
  • Organizations that do switch to new versions of PowerShell are required to install it during initialization, and must configure the endpoints themselves, so they can configure whatever endpoints they want to use by default.

Frankly, at this point, that doesn't seem that likely, based on the conversations I've had. It's more likely that devs and admins are installing new client versions on their personal development and administration machines, but to do their jobs, they still connect to whatever comes pre-configured on their servers.

Because of that, I think that if we are ready to say a new version of PowerShell should be the default, we should update the default endpoint to point to it. Register the versioned endpoints for use by software that requires a particular version (and add a PowerShell.5) but update the default to point at the latest version of PowerShell, and turn on remoting by default (on servers). Or rather, check the remoting box it by default if remoting is already enabled on the OS, and add another checkbox (also checked) to take over the default endpoint.

@doctordns
Copy link
Contributor

Should PowerShell 7 always create a remoting endpoint during installation?
Or should that be the task of a specific command (Install-PowerShell7Remoting)?

@Jaykul
Copy link
Contributor

Jaykul commented Jan 21, 2020

@doctordns I would say it could depend on whether WinRM is already enabled or not.

That is, if you're installing where WinRM remoting is already enabled ...

  • I would argue for adding "powershell.7"
  • I would argue if "microsoft.powershell" points at PowerShell 5, add a "powershell.5" if it's not there already
  • I would not argue against updating "microsoft.powershell" to point at 7 ...

Otherwise... regardless of whether it's Windows, Mac, or Linux ... I think that if WinRM is not already enabled, you shouldn't enable it by default, and there's no point setting up endpoints if it's not, right?

@doctordns
Copy link
Contributor

I believe installing PowerShell 7 should create meaningful endpoints. That way, everything works if WINRM is enabled and can work if you do enable WInRM. If you are arguing NOT to create the endpoint I'd agree but only if enabling WInRM then creates the required endpoint.

IIRC, you have the PowerShell 5 endpoint whether or not you have WinRM enabled. I'd like that same behaviour when I install PowerShell 7.

Also, I would like a PowerShell.5 and a PowerShell.7 endpoints created explicitly. For backwards compatibility reasons the Microsoft.PowerShell should remain as is.

@SteveL-MSFT SteveL-MSFT added the Review - Committee The PR/Issue needs a review from the PowerShell Committee label Feb 6, 2020
@SteveL-MSFT
Copy link
Member

A less breaking change would be for PS7 client to use PowerShell.7 remoting endpoint by default instead of Microsoft.PowerShell which (currently) always points to the inbox Windows PowerShell

@iSazonov
Copy link
Collaborator

iSazonov commented Feb 6, 2020

A less breaking change would be for PS7 client to use PowerShell.7 remoting endpoint by default instead of Microsoft.PowerShell

And fallback to Microsoft.PowerShell endpoint.

@doctordns
Copy link
Contributor

doctordns commented Feb 6, 2020

A less breaking change would be for PS7 client to use PowerShell.7 remoting endpoint by default instead of Microsoft.PowerShell which (currently) always points to the inbox Windows PowerShell

I was kind of surprised that Pwsh 7 had no native endpoints defined by default. And that even when you did create them, remoting into localhost fails.

@doctordns
Copy link
Contributor

I would have expected, by default, PS 7 to have a PS 7 endpoint defined, by default. And if I did 'Enter-PSSession' I'd have expected a compatible endpoint. So this failing is not expected:

invoke-command -computer foo {Get-ADComputer -Filter * | Foreach-Object - Parallel...}

Seems to me that the default endpoint should be the version of PowerShell you are running. If you run PWSH 7 then endpoint chosen by default should be a PWSH 7 endpoint. Not a PowerShell 5.x.

@iSazonov
Copy link
Collaborator

iSazonov commented Feb 7, 2020

I would have expected, by default, PS 7 to have a PS 7 endpoint defined, by default. And if I did 'Enter-PSSession' I'd have expected a compatible endpoint.

Current all infrastructures have Windows PowerShell preinstalled. All scripts works with Windows PowerShell endpoint. Until customers get a possibility to roll automatically out PowerShell Core in their environments it makes sense to change the defaults. First, users should get a possibility to change the default in config file and by GPO.

@doctordns
Copy link
Contributor

@iSazonov I am not sure I agree.

If I am a WIndows PowerShell user, I remote, by default, into a remoting session of the same version.

With PowerShell 7 I get it differently and by default, I get NO PowerShell 7 endpoints. So by default, remoting is to a downlevel version. And, again by default, I can't remote to a PowerShell 7 endpoint at all (none are created). Finally, I also can't seem to remote to localhost in any case.

There may be good reasons, but this is not a great user experience.

  1. When remoting using unnamed endpoints, if the version of PowerShell we are remoting into is Less than the current version, we should get a warning "entering downlevel/older version of Powershell - V X.X". That warning can be ignored or handled with -WarningAction parameter
  2. Pwsh7 endpoints should be created by default.
  3. Enter-PSSession should remote into an endpoint of the same version by default.
  4. The obvious excepting to 3 is for wincompat sessions.

I would like to see a very user-friendly resolution with actionable error messages and sane warnings/.

@joeyaiello
Copy link
Contributor

@PowerShell/powershell-committee just had a good long conversation about this that raised a number of concerns and open questions. We agree that we need to think more about it, and a few of us will swing by to continue the discussion independently.

Also leaving the label so we make sure to come back to it after we think more

@doctordns
Copy link
Contributor

doctordns commented Feb 20, 2020

Works here. On a Server 2019 with RC2 loaded:

PowerShell 7.0.0-rc.2
Copyright (c) Microsoft Corporation. All rights reserved.

https://aka.ms/powershell
Type 'help' to get help.

In TFL Customisations for [ConsoleHost]

PS C:\Foo> Import-Module -Name ServerManager -UseWindowsPowerShell
WARNING: Module ServerManager is loaded in Windows PowerShell using WinPSCompatSession remoting session; please note that all input and output of commands from this module will be deserialized objects. If you want to load this module into PowerShell Core please use 'Import-Module -SkipEditionCheck' syntax.
PS C:\Foo> gmo

ModuleType Version    PreRelease Name                                ExportedCommands
---------- -------    ---------- ----                                ----------------
Manifest   7.0.0.0               Microsoft.PowerShell.Management     {Add-Content, Clear-Content, Clear-Item, Clear-It…
Manifest   7.0.0.0               Microsoft.PowerShell.Security       {ConvertFrom-SecureString, ConvertTo-SecureString…
Manifest   7.0.0.0               Microsoft.PowerShell.Utility        {Add-Member, Add-Type, Clear-Variable, Compare-Ob…
Manifest   7.0.0.0               Microsoft.WSMan.Management          {Connect-WSMan, Disable-WSManCredSSP, Disconnect-…
Script     2.0.0      rc2        PSReadLine                          {Get-PSReadLineKeyHandler, Get-PSReadLineOption, …
Script     1.0                   ServerManager                       {Disable-ServerManagerStandardUserRemoting, Enabl…

PS C:\Foo> Get-PSSession

 Id Name            Transport ComputerName    ComputerType    State         ConfigurationName     Availability
 -- ----            --------- ------------    ------------    -----         -----------------     ------------
  2 WinPSCompatSes… Process   localhost       RemoteMachine   Opened                                 Available

@PaulHigin
Copy link
Contributor

Although I am sympathetic to this issue (this behavior has annoyed me many times), I feel the default endpoint should remain 'Microsoft.PowerShell'. We want people to move from 5.1 to 7, and if we change the default endpoint for 7 then many existing scripts will break.

But I also feel that 'Get-PSSessionConfiguration' running in PS7 should show the default 'Microsoft.PowerShell' endpoint, if it exists.

@daxian-dbw
Copy link
Member

But I also feel that 'Get-PSSessionConfiguration' running in PS7 should show the default 'Microsoft.PowerShell' endpoint, if it exists.

I agree!

@vexx32
Copy link
Collaborator

vexx32 commented Feb 20, 2020

I think it makes more sense for the default endpoint to be a PS7 endpoint, really.

We have the Windows Compatibility module loading that uses its own endpoint for those things already. Seems to me the simplest option would be to make it easier and more discoverable for folks to find both the PS7 endpoint and the Windows PowerShell endpoint, and maybe add easy shortcuts to remote to those, perhaps a general name for WinPS remoting that's available from Invoke-Command and picks the first Windows PowerShell endpoint it can find.

@essentialexch
Copy link

i agree with @PaulHigin - if you change the default endpoint on Windows, you'll break a lot of scripts.

Your typical admin scripter doesn't know (and shouldn't need to know) about endpoints.

@doctordns
Copy link
Contributor

doctordns commented Feb 21, 2020

I disagree with @PaulHigin and @essentialexch on this.

The behaviour of PowerShell 7 is not consistent with how Windows PowerShell works. IIRC, in each version (well since V2) of PowerShell, if you Enter-PSSession to localhost, you'd get an endpoint consistent with the current version of PowerShell. In Windows PowerShell 5.1, if I enter a session it is a session with the same version. I don't suddenly and without warning get a different version. With PowerShell 7. by default I get a downlevel version. Why add inconsistency when consistency CAN be maintained easily.

And as to @essentialexch's comment. I slightly disagree with both points. Anyone who is going to move to PowerShell 7, has to know that there are just some things that are not going to work without some changes and take the appropriate action. Have you tried running a script that uses Best Pactics, or WSUS? This is a no-go with PowerShell 7. Fortunately, that issue is now gone with the block list for import-module.

To say 'a lot of scripts' are going to be affected - this possibly a gross overstatement. I've been working on a book, and it is not the case that "a lot" of scripts break. I have only found three modules to be actually problematic. And the existing 5.1 scripts that do remoting actually work better than I expected - that is to say pretty much flawlessly.

If you are writing scripts using remoting, would you really NOT know about what an endpoint is and how it works? If you are writing production scripts that depend on remoting, then yes you really should understand remoting and what an endpoint is. All the more so if you are going to use JEA. One of the first things I teach students in the Remoting module is what an endpoint is. I draw it out and my students do understand it quite easily.

Here's what I feel should happen:

  1. PowerShell 7 should be installed with some default end-points, just like versions of Windows PowerShell did. One should not need to use Enable-PSRemoting to get these to exist.

  2. The output of Get-PSSessionConfiguration should be identical for both PowerShell 7 and 5.1. It currently is not. And it would be nice to have Get-PSSessonConfiguration did not need an elevated console to run.

  3. The help text needs to be improved - the help for enter-PSSession makes NO mention of suddenly being a different version. The text has to make clear what is happening. Currently, it's not clear that a downlevel endpoint is being chosen and why that matters (and how to fix it).

  4. Ensure that if a downlevel endpoint IS to be used, then it should be visible with Get-PSSessionConfiguration. Try to do the following in PowerShell 7

$hostname = hostname
Get-PSSessionConfiguration
Enter-PSSession -ComputerName $hostname
$Psversiontable

IF you have not run Enable-PSRemoting, you see ZERO endpoints, but you do enter the session. If you have enabled remoting, you see THREE (PS7) endpoints, but when you enter the 'default' it's a different endpoint. That is both inconsistent and illogical.

Interestingly, if I do the same thing in PowerShell 5.1 I get different results. First, in 5.1 I see ALL the endpoints (Not just current version ones), secondly, by default, if I enter-PSSession I see an endpoint of the same version, not some other version.

In summary, I do not believe the current implementation presents a consistent and logical default installation for remoting. And given the added importance of remoting in PWSH, this needs to be resolved prior to RTM.

@SteveL-MSFT
Copy link
Member

I had a discussion with @JamesWTruher on this topic. Some thoughts:

  • Get-PSSessionConfiguration should be enhanced to be able to run remotely so you can discover configurations for remote endpoints. This means that Get-PSSessionConfiguration should show everything so when used remotely, it doesn't matter if you connect to 5.1 or 7.
  • I think that for most customers, they expect to establish a connection to the same major version of the PowerShell they are using by default.
  • We should have some policy and/or setting to define the default endpoint a client connects to if not specified.
  • I'm of the opinion that for most customers, what they care about is establishing A connection and not a SPECIFIC connection, so a fallback strategy makes sense to me and output a Warning message if connecting to something other than a version that matches the client
  • @JamesWTruher proposed adding a note property that indicates the PSVersion for remote objects similar to how we add PSComputerName

@doctordns
Copy link
Contributor

@SteveL-MSFT - I agree

  • Regarding Get-PSSessionConfiguration - I'd like to also ensure that if this command is run inside PowerShell 7, it discovers the down-level endpoints too.
  • Regarding Policy - where is this defined? I assume in powershell.config.json. Is a group policy needed to set this for wider deployment?
  • Regarding the warning - well in a way that would be consistent with importing a module via PSCompat - you get a warning there too.
  • Note property - yes, please!

I do have a small concern over what will go into 7.0. I believe this needs to be in 7.0. My concern is that that means it won't get quite as wide testing as an RC (and I am the last person to want yet another RC!). I think these changes are fairly simple - but then what do I know about that!

@PaulHigin
Copy link
Contributor

A remote option for Get-PSSessionConfiguration is good, but what endpoint does it connect to? It would have to be 5.1. But most users won't bother to use it, they just expect a PowerShell remote connection to work.

I agree that most users expect to connect to the same PS version for loopback connections. But for connections to arbitrary machines, not so much. They probably don't know what version of PowerShell is installed and just want it to work, and 5.1 is guaranteed to be installed on all Windows machines. First running Get-PSSessionConfiguration on 100+ remote machines doesn't seem feasible.

@alexandair
Copy link
Contributor Author

@SteveL-MSFT
"We should have some policy and/or setting to define the default endpoint a client connects to if not specified."

That already exists. $PSSessionConfigurationName variable has the value http://schemas.microsoft.com/powershell/Microsoft.PowerShell by default.

@doctordns
Copy link
Contributor

As to WHICH endpoint - seems to mew that by default an endpoint of the same version. Automagically going downlevel, as I pointed out earlier, is inconsistent with how Windows PowerShell works.

I'd expect that this should be the case for loopback and across the net. If I am in PWSH 7 and remote into another PowerShell 7 box, I should get a PowerShell 7 console if that is possible. If not, connect to the highest downlevel endpoint and do so with a warning (similar to that generated when Import-MOdule uses implicit remoting to import a module into a PowerShell 7 session.

@iSazonov
Copy link
Collaborator

I think that for most customers, they expect to establish a connection to the same major version of the PowerShell they are using by default.

Only if the customers install the new major version on all systems. Currently Windows PowerShell dominates (statistics show this) and will do until MSFT make a total update to PS Core. Today there is no such update even as an option. Really customer's scripts in Enterprises are still not PS Core compatible and are not tested.

I'm of the opinion that for most customers, what they care about is establishing A connection and not a SPECIFIC connection, so a fallback strategy makes sense to me and output a Warning message if connecting to something other than a version that matches the client

This seems to violate the basic security principle. Any fallback should be enabled explicitly especially for remoting.

@essentialexch
Copy link

If I Enter-PsSession today, or ICM I get PS 5.1. If I enter Enter-PsSession tomorrow, after PS 7 is installed, I better still get PS 5.1, by default. Otherwise stuff will break (as well as violating the principle of "least surprise").

Do I know what John Q. User has done to his computer? No, and I shouldn't need to. And I sure shouldn't need to check first.

And no, I don't need to know ANYTHING about endpoints to use Enter-PsSession or ICM.

@joeyaiello
Copy link
Contributor

joeyaiello commented Mar 3, 2020

Wanted to post some of my thoughts from last week, as we had a very long discussion regarding this one in the @PowerShell/powershell-committee, and we wanted to let this one churn a little.

I should note that at this point there's no way this making 7.0, and would have to be something that's changed for 7.1.

Leaving aside Windows PS 2.x for a second, in a pre-Core world, Windows PowerShell would always remote into the "latest version" on a box because there could only be one version on the box. This was one of the historical problems with Windows PowerShell and WMF: upgrading your OS or version of PowerShell was an operation that moved your entire machine forward.

As such, we did our best to maintain backwards compatibility in new versions so that users could take advantage of new features and bug fixes without breaking their existing scripts. This was a lot easier given the strong backwards compatibility of .NET Framework, but even with Core, we've invested heavily over the last couple years to achieve a high level of backwards compatibility with Windows PowerShell so that users can migrate more easily.

But of course, in neither case were we perfect. Our guidance was always that admins who owned the servers should validate their workloads with new versions of Windows Server and/or Windows PowerShell in a test or staging environment, so that they could be sure that updating wouldn't break them.

The key point here is that the server admin was making the conscious decision to change the runtime for the server: both in the local server case, as well as the server remoting endpoint case (because at that point in time they were the same thing).

Today, the admin still has complete control over the server endpoint. They can:

  • turn on/off WinRM remoting completely for Windows PowerShell and/or PowerShell Core/7
  • set the default microsoft.powershell endpoint to any PowerShell they choose
  • create arbitrary WinRM endpoints that point to specific side-by-side versions
  • leverage SSH remoting for PowerShell 7

To that end, we're not talking about any kind of blocker. Given the proper configuration, all scenarios are possible (if this isn't accurate, my apologies, please call one out).

Are some of these a complete pain to do today? Absolutely, especially considering that Get-PSSessionConfiguration is explicitly filtering out Windows PowerShell endpoints (a decision that I believe can be traced to very naive decision-making on my and others' part in an earlier version of Core).

We should fix that. As noted above, we should also fix Get-PSSessionConfiguration so that it works remotely and you can discover available server endpoints.

However, I don't think changing the default is prudent for a couple reasons:

  • The fallback logic is "magic" that will require admins who are updating their WinRM endpoints to understand additional complexity (e.g. if I want to force clients to default to entering via Windows PS on my server, but still leave remoting on for PS 7, I have to rename the PS 7 endpoints to anything other than the default name).
  • Backwards compatibility is still a top, top concern, and there are some scripts that will continue to not work when moved to 7. Given the historical pain of updating Windows PowerShell, we made a pretty strong guarantee that deploying Core/7 is a side-by-side operation, and will not impact your Windows PowerShell workloads. (You can find some of this language in my 6.0 release blog, and something similar in the 6.0 release notes, but this is something I've spoken to in presentations and with customers for years now.)

I also propose that we add a switch to the MSI to enable admins to easily "set PowerShell 7 as the default endpoint. This would allow admins to force Windows PowerShell clients to use PowerShell 7 as the default endpoint on the Server, something much more akin to the way that SSH remoting works, where the default shell can be set by the admin, irrespective of the shell in which the client is executing ssh. (Though it was also raised in our meeting that you can override the default shell as an SSH client, of course requiring that said shell exists on the remote side. While not perfect, this is somewhat of a parallel to the WinRM clients passing an endpoint configuration name.) As a piece of implementation detail, this checkbox should also probably rename the existing microsoft.powershell endpoint (if it exists) to something like microsoft.powershell.5 or microsoft.windows.powershell.

I know this seems frustrating to some that are living on the cutting edge, where they're able to move to PowerShell 7 across their entire client- and server-side environments. But the "principle of least surprise", as @essentialexch referred to it, is something that's very important to us. PS Core and 7 were created to be side-by-side because we wanted to enable admins and users to make separate parts of the journey upwards as they are ready. We really want to get away from this idea that upgrading is an all-or-nothing approach. Even if an endpoint fallback partially solves that issue, it's still something that will surprise any users who may have deployed PS 7 to their servers under the banner that it wouldn't affect whatever was working yesterday.

And while we have absolutely no plans to do this (and as I know @SteveL-MSFT agrees, I would prefer to never do this), all of that leaves aside what the heck we would do if there ever future incompatible versions of PowerShell (like an 8.0). Introducing magic fallback logic just feels like we're painting ourselves into a corner.

I should note that this isn't a definitive answer on this issue, and the @PowerShell/powershell-committee still wants to talk more about the proper solution. But I wanted to lay out my thoughts to provide a framework for others to provide their feedback.

@Jaykul
Copy link
Contributor

Jaykul commented Mar 12, 2020

Thanks @joeyaiello that sounds reasonable 😉

Maybe with this settled (and if we can get Get-PSSessionConfiguration fixed so it doesn't filter out the Windows PowerShell endpoints), the community can write the scripts to configure some common conventions such as:

  • Ensure there's a "powershell.#" and "powershell.#.#.#" for every installed version
  • Set the "Microsoft.PowerShell" endpoint to point at the latest version
  • Set the "Microsoft.PowerShell" endpoint to point at the latest LTS version
  • Set the "Microsoft.PowerShell" endpoint to point (back) at Windows PowerShell 5.1

@SteveL-MSFT SteveL-MSFT added Committee-Reviewed PS-Committee has reviewed this and made a decision and removed Review - Committee The PR/Issue needs a review from the PowerShell Committee labels Mar 25, 2020
@SteveL-MSFT
Copy link
Member

@PowerShell/powershell-committee agreed to open some new issues to make it easier for users to discover and set the default endpoint as noted in Joey's write-up

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Committee-Reviewed PS-Committee has reviewed this and made a decision Issue-Question ideally support can be provided via other mechanisms, but sometimes folks do open an issue to get a Resolution-Answered The question is answered. WG-Remoting PSRP issues with any transport layer
Projects
None yet
Development

No branches or pull requests

12 participants