-
Notifications
You must be signed in to change notification settings - Fork 135
Add side-by-side support to pwsh.exe #202
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
Changes from 6 commits
6f2460e
52833ba
4dee90a
b749970
dc01087
cc040c9
908ace9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,253 @@ | ||
| --- | ||
| RFC: RFCNNNN | ||
| Author: Kirk Munro | ||
| Status: Draft | ||
| SupercededBy: none | ||
| Version: 0.1 | ||
| Area: CLI, SDK | ||
| Comments Due: July 21, 2019 | ||
| Plan to implement: Maybe | ||
| --- | ||
|
|
||
| # Side-by-side support in PowerShell 7 and later | ||
|
|
||
| Historically, upgrading Windows PowerShell meant replacing your existing | ||
| version with a newer version. The were only two notions of side-by-side support | ||
| with Windows PowerShell: | ||
|
|
||
| 1. Support for running `powershell.exe -version 2` in Windows PowerShell | ||
| versions 3.x-5.x. That wasn't quite the same as running PowerShell version 2 | ||
| though, because your modules that were installed by default and not available | ||
| in the PowerShell Gallery may not be compatible with version 2 and therefore | ||
| couldn't load. | ||
| 1. Support for installing multiple versions of modules side-by-side and | ||
| importing the version that you needed in Windows PowerShell version 3.x-5.x. | ||
|
|
||
| Unfortunately, there are many scenarios where upgrading Windows PowerShell | ||
| isn't an option for users, such as: | ||
|
|
||
| 1. When you are using a product that has a dependency on a specific version | ||
| of PowerShell. | ||
| 1. When you have automation scripts or other management solutions that have a | ||
| dependency on a specific version of PowerShell. | ||
|
|
||
| In order to keep systems and management processes running the way they must in | ||
| an enterprise, many users have no choice but to stick with a downlevel version | ||
| of Windows PowerShell for a very long time. There are even some organizations | ||
| still using PowerShell version 2 today! | ||
|
|
||
| All of this has lead to much of the community pushing hard for downlevel | ||
| support for updates via modules as much as possible so that they can use the | ||
| new features and functionality in older versions of PowerShell. The serious | ||
| downside to that approach is that modules that offer downlevel support have to | ||
| be designed for downlevel versions, perhaps opting in to additional | ||
| functionality with logic that checks for specific versions of PowerShell. The | ||
| end result is that this holds us back as a community, and we need to find a way | ||
| to enable us to move forward more quickly. | ||
|
|
||
| Fortunately, the upcoming release of PowerShell 7 provides a rare opportunity | ||
| for the PowerShell Community: its release marks the first time that a successor | ||
| to a Windows PowerShell release can be installed side-by-side with Windows | ||
| PowerShell (note: PowerShell Core 6.x was not a true successor to Windows | ||
| PowerShell, but PowerShell 7 is the successor to both Windows PowerShell 5.x | ||
| and PowerShell Core 6.x). It will even have a separate executable (`pwsh.exe`), | ||
| and can be installed to specific locations. That means users will be able to | ||
| install and use PowerShell 7 side-by-side with other versions of PowerShell, | ||
| which is a great help for users looking for opportunities to move forward. | ||
| There are still some products and/or scenarios that aren't supported in | ||
| PowerShell 7, but this release brings us much, much closer to parity and gives | ||
| us an opportunity to spend more time looking forward than backward. | ||
|
|
||
| Unfortunately, according to the [Microsoft blog post about the forthcoming | ||
| PowerShell 7 release](https://devblogs.microsoft.com/powershell/the-next-release-of-powershell-powershell-7/), | ||
| PowerShell 7 will align more closely with the .NET Core support lifecycle, | ||
| which brings in support for LTS (Long Term Servicing) and non-LTS releases. | ||
| Non-LTS (aka Current) releases are supported for three months after a | ||
| subsequent Current release or an LTS release. This means you'll have to update | ||
| those releases regularly, which helps move the community forward. On the other | ||
| hand, LTS releases will be supported either for three years after general | ||
| availability or for a 12 month maintenance period after the next LTS release | ||
| ships, whichever is longer (i.e. if it takes them longer than expected to get | ||
| an LTS release out the door for some reason, the previous LTS release could be | ||
| supported for even longer). This means you'll be able to stick your heels in | ||
| the ground and use an LTS release for a very long time, which risks holding us | ||
| back. | ||
|
|
||
| In order to keep the focus on moving forward, the purpose of this proposal is | ||
| to support side-by-side installations of PowerShell such that...: | ||
|
|
||
| * ...it is easy to see what versions of PowerShell are installed. | ||
| * ...it is easy to launch a specific installed version of PowerShell from a | ||
| command line. | ||
| * ...having multiple installed versions of PowerShell doesn't cause problems | ||
| for automation, products, or services built for a specific version of PowerShell. | ||
|
|
||
| ## Motivation | ||
|
|
||
| As a user, | ||
| I can easily install newer versions of PowerShell side-by-side with old versions, | ||
| so that I can continue to use products/solutions for specific versions of PowerShell while using newer versions when needed. | ||
|
|
||
| As a user, | ||
| I can use the command line to see which versions of PowerShell are installed, | ||
| so that I can know what versions are available to me to use. | ||
|
|
||
| As a user, | ||
| I can launch the version of PowerShell I need from the command line, | ||
| so that I can use automation built and tested against specific versions of PowerShell while still being able to use the latest version on the same system. | ||
|
|
||
| ## User Experience | ||
|
|
||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does this RFC include Windows? Or is it MacOS/Linux only? Where does WSL fit? The examples are using a lot of third-party (by which I mean "non-Windows" and "non-PowerShell") commands. I find myself quite confused by this. I know what "apt get" is, but no clue what "brew" or "choco" or etc. do.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| ### Installing a specific version of PowerShell | ||
|
|
||
| The end goal is for users to be easily able to do any of the following with a | ||
| PowerShell installer: | ||
|
|
||
| * install the latest version of PowerShell side-by-side with an existing | ||
| version from a UI (e.g. `.msi`, `.pkg`, `.deb`) | ||
| * install the latest version of PowerShell side-by-side with an existing | ||
| version from the command line (e.g. `sudo apt-get install ...`, `brew cask | ||
| install ...`, `choco install ...`) | ||
|
|
||
| _Note: I'm a little uncertain of these details here, so please correct me where | ||
| appropriate._ | ||
|
|
||
| The current release process seems to include updated published versions of | ||
| packages in the various package repositories (for `apt-get`, homebrew, and | ||
| Chocolatey). The problem with this approach is that it does not support | ||
| side-by-side installations at the command line. For example, if I have | ||
| PowerShell Core 6.2.0 installed on macOS and I want to install PowerShell Core | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there a real need to have patch versions side-by-side? I would think the common scenario is 6.2, 7.0, 7.1. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Indeed. And if PowerShell releases truly follow semver rules for versioning, I would expect 7.1 to be completely back compat with 7.0. So I'd only expect side-by-side support for major versions e.g. 5, 6, 7, 8, etc. Oh, looking ahead, you still need side-by-side support for previews as well but that is already handled today for major versions.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We're explicitly not using semver for the version of PowerShell itself. Modules should use semver, but PS versions are just intended to signal relative size of feature sets, among other things. |
||
| 6.2.1 side-by-side, I cannot. I can upgrade my installed version, reinstall | ||
| the current version, or install a preview version (since that comes from a | ||
| different package name), but I cannot install a different version side-by-side. | ||
|
|
||
| Instead, if the release process not only updated the latest package but also | ||
| created a version-specific package in the various repositories, then users | ||
| could specify a specific version that they want to install (e.g. `brew cask | ||
| install [email protected]`) to install different versions of PowerShell | ||
| side-by-side with one another, with the versions automatically being installed | ||
| in an appropriate version folder (which they are already anyway). Chocolatey | ||
| already has support for installing a specific version, but it does not seem to | ||
| work at the moment (I tried installing PowerShell Core 6.2.0 and ended up with | ||
| 6.2.1, with an error indicating that 6.2.0 was not installed). | ||
|
|
||
| The UI installers should provide options to upgrade the latest installed | ||
| version of PowerShell or install a new version side-by-side. | ||
|
|
||
| ### Listing installed versions of PowerShell | ||
|
|
||
| ```bash | ||
| # This launches the latest version of PowerShell, returns a list of installed | ||
| # versions and their installation location, and then exits | ||
| pwsh -ListVersions | ||
| # This does the same thing | ||
| pwsh -lv | ||
| ``` | ||
|
|
||
| ```output | ||
| 6.2.1 [/usr/local/microsoft/powershell/6.2.1/] | ||
| 7.0.100-preview1 [/usr/local/microsoft/powershell/7.0.100-preview1] | ||
| ``` | ||
|
|
||
| ```powershell | ||
|
|
||
| # This returns a list of installed versions and their installation location as | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it should be explicitly stated that this will only look in the expected installed locations and not search the entire filesystem. This means that custom deployments of the .zip/.tgz won't be found unless they are expanded in the same locations. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe use a file inventory that each version of PowerShell updates during install/uninstall. This method could read the file and list the versions there. Maybe with some validation that the source truly exists. Or detect Choco and list versions that way. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if Windows is included here, the registry should be examined, IMO. |
||
| # objects | ||
| Get-InstalledPSVersion | ||
| ``` | ||
|
|
||
| ```output | ||
| Version InstallLocation | ||
| ------- --------------- | ||
| 6.2.1 C:\ProgramFiles\PowerShell\6.2.1 | ||
| 7.0.100-preview1 C:\ProgramFiles\PowerShell\7.0.100-preview1 | ||
| ``` | ||
|
|
||
| ### Launching a specific version of PowerShell | ||
|
|
||
| ```bash | ||
| # This launches the latest version of PowerShell, gets the installation | ||
| # location of the specified version, launches pwsh for that version, and exits | ||
| # when the launched version exits | ||
| pwsh -Version 6.2.1 | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There are some implications we need to think about here. On Unix systems, we can leverage There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Within PowerShell at least, couldn't it intercept this request to start the native app called
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It could be special cased in PowerShell itself, but not sure if it's worth it. Also, it seems that this is most useful for scripts using There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The “PowerShell.exe -Version x.x -File “C:\Path\To\script.ps1” could work here as well. It would be nice if a warning could be displayed, if that version isn’t installed and include what version was used instead. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also, I think it would be good to spawn a new child process, if calling a different “pwsh” from the console. This is expected behavior in Windows and *nix world when requesting a different shell. Unless a very good cleanup job was done of the current process, using some .dll swapping could get messy. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think there should be an error if the specified version isn't available, not using something else.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What if the version is not installed? Will we fail or run upper version?
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It seems that if a specific version is requested and not found, it should not run and would return an error. If |
||
| # This does the same thing | ||
| pwsh -v 6.2.1 | ||
| ``` | ||
|
|
||
| ```output | ||
| # A new window with the desired version of PowerShell open. | ||
| # If it is possible to do have this window on a new tab in the new Terminal, | ||
| # that would be great. | ||
| ``` | ||
|
|
||
| ## Specification | ||
|
|
||
| * create a `Get-InstalledPSVersion [<CommonParameters>]` cmdlet that returns | ||
| the installed versions of PowerShell along with their locations | ||
| * update the `-version` argument of `pwsh.exe` to attempt to launch a specific | ||
| version of PowerShell | ||
| * add a `-ListVersions` argument to `pwsh.exe` that internally invokes | ||
| `Get-InstalledPSVersion`, formats and outputs the results, and exits | ||
| * update the release packaging process to produce versioned packages | ||
|
|
||
| ## Alternate Proposals and Considerations | ||
|
|
||
| ### Include Windows PowerShell version support | ||
|
|
||
| It would be worth considering having `Get-InstalledPSVersion` return the | ||
| installed version of Windows PowerShell along with its location, and having | ||
| `pwsh -version` support launching Windows PowerShell. That would allow users to | ||
| launch any installed PowerShell version from `pwsh.exe`, making it easy to set | ||
| up automation with one command to invoke. Arguments from `pwsh.exe` could be | ||
| mapped to arguments on `powershell.exe`. | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think that |
||
|
|
||
| ### Are containers and Docker enough to solve this need? | ||
|
|
||
| While discussing this with a colleague of mine, they asked if this is really | ||
| needed, or if containers and Docker solve this problem already. While I believe | ||
| containers can allow users to use different versions of PowerShell, I also | ||
| suspect that most users don't know how to set that up, if they even use Docker | ||
| at all. I think it would be easier for everyone if we could just launch the | ||
| proper version of PowerShell via `pwsh.exe`. | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Who is your audience? I'm an admin scripter. And while I know what Docker/containers are, I certainly don't use them, nor do I know how (I have done a Windows container lab, but not using Docker). Lots of desktops/laptops don't have virtualization turned on, nor have a virtualizer installed nor will your average user know how to do so. But their admins may have very good reasons to need multiple versions of PS. |
||
|
|
||
| ### Maintain backwards compatibility with pwsh.exe -version | ||
|
|
||
| In PowerShell Core 6.2, if you invoke `pwsh -version` you get the current | ||
| PowerShell version. That support could remain in place if this RFC is approved, | ||
| returning the current (latest) version when invoked without a version, or | ||
| launching the requested version when invoked with a version. | ||
|
|
||
| ### Windows Update | ||
|
|
||
| If PowerShell is added back as a component of Windows, some consideration needs | ||
| to be given to Windows Update. With side-by-side installations, it would not | ||
| make much sense to update older versions, so the most recently installed stable | ||
| version should be treated as the default version to check for updates. | ||
|
|
||
| Unfortunately I do not have much insight into what Windows Update requires. | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Windows Update requires that the path to the binaries don't change. This means that we don't have even a complete version as the folder name hence it's just |
||
| @iSazonov mentioned he remembers it requiring the _same_ installation folder, | ||
| and if that is the case, how would that work with a SxS updateable PowerShell. | ||
| If someone who knows what is actually required to make Windows Update work | ||
| could share what could/should be done here, that would be appreciated. Ideally | ||
| PowerShell would work like dotnet works, supporting side-by-side installations | ||
| while being updateable via Windows Update as well. | ||
|
|
||
| ### Version discovery and registration | ||
|
|
||
| Currently the PowerShell installer allows you to install PowerShell into any | ||
| folder you want. This flexibility comes at a cost, because it means registering | ||
| installations of PowerShell on a system to make sure they are discoverable. | ||
|
|
||
| Since PowerShell is a runtime that other products need to be able to depend on, | ||
| some thought needs to be given towards how best to install it. I believe it | ||
| would be better to only install to known locations for all users/system or for | ||
| the current user so that we could check the filesystem to discover versions of | ||
| PowerShell that are installed, regardless of what platform we are on. It is | ||
| likely that this would also make building solutions on top of side-by-side | ||
| installations of PowerShell easier, so that they can check for the required | ||
| version easily. | ||
|
|
||
| It is worth mentioning that the dotnet sdk installer does not ask you where | ||
| you want to install it. Instead it installs to one of two locations, depending | ||
| on whether or not you are an admin (i.e. it installs to an all users/system | ||
| location if you are admin, or to a user location if you are not). | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/some/many/