|
| 1 | +--- |
| 2 | +RFC: RFC0038 |
| 3 | +Author: Kirk Munro |
| 4 | +Status: Rejected |
| 5 | +SupercededBy: none |
| 6 | +Version: 0.1 |
| 7 | +Area: CLI, SDK |
| 8 | +Comments Due: July 21, 2019 |
| 9 | +Plan to implement: Maybe |
| 10 | +--- |
| 11 | + |
| 12 | +# Side-by-side support in PowerShell 7 and later |
| 13 | + |
| 14 | +Historically, upgrading Windows PowerShell meant replacing your existing |
| 15 | +version with a newer version. The were only two notions of side-by-side support |
| 16 | +with Windows PowerShell: |
| 17 | + |
| 18 | +1. Support for running `powershell.exe -version 2` in Windows PowerShell |
| 19 | +versions 3.x-5.x. That wasn't quite the same as running PowerShell version 2 |
| 20 | +though, because your modules that were installed by default and not available |
| 21 | +in the PowerShell Gallery may not be compatible with version 2 and therefore |
| 22 | +couldn't load. |
| 23 | +1. Support for installing multiple versions of modules side-by-side and |
| 24 | +importing the version that you needed in Windows PowerShell version 3.x-5.x. |
| 25 | + |
| 26 | +Unfortunately, there are many scenarios where upgrading Windows PowerShell |
| 27 | +isn't an option for users, such as: |
| 28 | + |
| 29 | +1. When you are using a product that has a dependency on a specific version |
| 30 | +of PowerShell. |
| 31 | +1. When you have automation scripts or other management solutions that have a |
| 32 | +dependency on a specific version of PowerShell. |
| 33 | + |
| 34 | +In order to keep systems and management processes running the way they must in |
| 35 | +an enterprise, many users have no choice but to stick with a downlevel version |
| 36 | +of Windows PowerShell for a very long time. There are even some organizations |
| 37 | +still using PowerShell version 2 today! |
| 38 | + |
| 39 | +All of this has lead to much of the community pushing hard for downlevel |
| 40 | +support for updates via modules as much as possible so that they can use the |
| 41 | +new features and functionality in older versions of PowerShell. The serious |
| 42 | +downside to that approach is that modules that offer downlevel support have to |
| 43 | +be designed for downlevel versions, perhaps opting in to additional |
| 44 | +functionality with logic that checks for specific versions of PowerShell. The |
| 45 | +end result is that this holds us back as a community, and we need to find a way |
| 46 | +to enable us to move forward more quickly. |
| 47 | + |
| 48 | +Fortunately, the upcoming release of PowerShell 7 provides a rare opportunity |
| 49 | +for the PowerShell Community: its release marks the first time that a successor |
| 50 | +to a Windows PowerShell release can be installed side-by-side with Windows |
| 51 | +PowerShell (note: PowerShell Core 6.x was not a true successor to Windows |
| 52 | +PowerShell, but PowerShell 7 is the successor to both Windows PowerShell 5.x |
| 53 | +and PowerShell Core 6.x). It will even have a separate executable (`pwsh.exe`), |
| 54 | +and can be installed to specific locations. That means users will be able to |
| 55 | +install and use PowerShell 7 side-by-side with other versions of PowerShell, |
| 56 | +which is a great help for users looking for opportunities to move forward. |
| 57 | +There are still some products and/or scenarios that aren't supported in |
| 58 | +PowerShell 7, but this release brings us much, much closer to parity and gives |
| 59 | +us an opportunity to spend more time looking forward than backward. |
| 60 | + |
| 61 | +Unfortunately, according to the [Microsoft blog post about the forthcoming |
| 62 | +PowerShell 7 release](https://devblogs.microsoft.com/powershell/the-next-release-of-powershell-powershell-7/), |
| 63 | +PowerShell 7 will align more closely with the .NET Core support lifecycle, |
| 64 | +which brings in support for LTS (Long Term Servicing) and non-LTS releases. |
| 65 | +Non-LTS (aka Current) releases are supported for three months after a |
| 66 | +subsequent Current release or an LTS release. This means you'll have to update |
| 67 | +those releases regularly, which helps move the community forward. On the other |
| 68 | +hand, LTS releases will be supported either for three years after general |
| 69 | +availability or for a 12 month maintenance period after the next LTS release |
| 70 | +ships, whichever is longer (i.e. if it takes them longer than expected to get |
| 71 | +an LTS release out the door for some reason, the previous LTS release could be |
| 72 | +supported for even longer). This means you'll be able to stick your heels in |
| 73 | +the ground and use an LTS release for a very long time, which risks holding us |
| 74 | +back. |
| 75 | + |
| 76 | +In order to keep the focus on moving forward, the purpose of this proposal is |
| 77 | +to support side-by-side installations of PowerShell such that...: |
| 78 | + |
| 79 | +* ...it is easy to see what versions of PowerShell are installed. |
| 80 | +* ...it is easy to launch a specific installed version of PowerShell from a |
| 81 | +command line. |
| 82 | +* ...having multiple installed versions of PowerShell doesn't cause problems |
| 83 | +for automation, products, or services built for a specific version of PowerShell. |
| 84 | + |
| 85 | +## Motivation |
| 86 | + |
| 87 | + As a user, |
| 88 | + I can easily install newer versions of PowerShell side-by-side with old versions, |
| 89 | + so that I can continue to use products/solutions for specific versions of PowerShell while using newer versions when needed. |
| 90 | + |
| 91 | + As a user, |
| 92 | + I can use the command line to see which versions of PowerShell are installed, |
| 93 | + so that I can know what versions are available to me to use. |
| 94 | + |
| 95 | + As a user, |
| 96 | + I can launch the version of PowerShell I need from the command line, |
| 97 | + 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. |
| 98 | + |
| 99 | +## User Experience |
| 100 | + |
| 101 | +### Installing a specific version of PowerShell |
| 102 | + |
| 103 | +The end goal is for users to be easily able to do any of the following with a |
| 104 | +PowerShell installer: |
| 105 | + |
| 106 | +* install the latest version of PowerShell side-by-side with an existing |
| 107 | +version from a UI (e.g. `.msi`, `.pkg`, `.deb`) |
| 108 | +* install the latest version of PowerShell side-by-side with an existing |
| 109 | +version from the command line (e.g. `sudo apt-get install ...`, `brew cask |
| 110 | +install ...`, `choco install ...`) |
| 111 | + |
| 112 | +_Note: I'm a little uncertain of these details here, so please correct me where |
| 113 | +appropriate._ |
| 114 | + |
| 115 | +The current release process seems to include updated published versions of |
| 116 | +packages in the various package repositories (for `apt-get`, homebrew, and |
| 117 | +Chocolatey). The problem with this approach is that it does not support |
| 118 | +side-by-side installations at the command line. For example, if I have |
| 119 | +PowerShell Core 6.2.0 installed on macOS and I want to install PowerShell Core |
| 120 | +6.2.1 side-by-side, I cannot. I can upgrade my installed version, reinstall |
| 121 | +the current version, or install a preview version (since that comes from a |
| 122 | +different package name), but I cannot install a different version side-by-side. |
| 123 | + |
| 124 | +Instead, if the release process not only updated the latest package but also |
| 125 | +created a version-specific package in the various repositories, then users |
| 126 | +could specify a specific version that they want to install (e.g. `brew cask |
| 127 | +install [email protected]`) to install different versions of PowerShell |
| 128 | +side-by-side with one another, with the versions automatically being installed |
| 129 | +in an appropriate version folder (which they are already anyway). Chocolatey |
| 130 | +already has support for installing a specific version, but it does not seem to |
| 131 | +work at the moment (I tried installing PowerShell Core 6.2.0 and ended up with |
| 132 | +6.2.1, with an error indicating that 6.2.0 was not installed). |
| 133 | + |
| 134 | +The UI installers should provide options to upgrade the latest installed |
| 135 | +version of PowerShell or install a new version side-by-side. |
| 136 | + |
| 137 | +### Listing installed versions of PowerShell |
| 138 | + |
| 139 | +```bash |
| 140 | +# This launches the latest version of PowerShell, returns a list of installed |
| 141 | +# versions and their installation location, and then exits |
| 142 | +pwsh -ListVersions |
| 143 | +# This does the same thing |
| 144 | +pwsh -lv |
| 145 | +``` |
| 146 | + |
| 147 | +```output |
| 148 | +6.2.1 [/usr/local/microsoft/powershell/6.2.1/] |
| 149 | +7.0.100-preview1 [/usr/local/microsoft/powershell/7.0.100-preview1] |
| 150 | +``` |
| 151 | + |
| 152 | +```powershell |
| 153 | + |
| 154 | +# This returns a list of installed versions and their installation location as |
| 155 | +# objects |
| 156 | +Get-InstalledPSVersion |
| 157 | +``` |
| 158 | + |
| 159 | +```output |
| 160 | +Version InstallLocation |
| 161 | +------- --------------- |
| 162 | +6.2.1 C:\ProgramFiles\PowerShell\6.2.1 |
| 163 | +7.0.100-preview1 C:\ProgramFiles\PowerShell\7.0.100-preview1 |
| 164 | +``` |
| 165 | + |
| 166 | +### Launching a specific version of PowerShell |
| 167 | + |
| 168 | +```bash |
| 169 | +# This launches the latest version of PowerShell, gets the installation |
| 170 | +# location of the specified version, launches pwsh for that version, and exits |
| 171 | +# when the launched version exits |
| 172 | +pwsh -Version 6.2.1 |
| 173 | +# This does the same thing |
| 174 | +pwsh -v 6.2.1 |
| 175 | +``` |
| 176 | + |
| 177 | +```output |
| 178 | +# A new window with the desired version of PowerShell open. |
| 179 | +# If it is possible to do have this window on a new tab in the new Terminal, |
| 180 | +# that would be great. |
| 181 | +``` |
| 182 | + |
| 183 | +## Specification |
| 184 | + |
| 185 | +* create a `Get-InstalledPSVersion [<CommonParameters>]` cmdlet that returns |
| 186 | +the installed versions of PowerShell along with their locations |
| 187 | +* update the `-version` argument of `pwsh.exe` to attempt to launch a specific |
| 188 | +version of PowerShell |
| 189 | +* add a `-ListVersions` argument to `pwsh.exe` that internally invokes |
| 190 | +`Get-InstalledPSVersion`, formats and outputs the results, and exits |
| 191 | +* update the release packaging process to produce versioned packages |
| 192 | + |
| 193 | +## Alternate Proposals and Considerations |
| 194 | + |
| 195 | +### Include Windows PowerShell version support |
| 196 | + |
| 197 | +It would be worth considering having `Get-InstalledPSVersion` return the |
| 198 | +installed version of Windows PowerShell along with its location, and having |
| 199 | +`pwsh -version` support launching Windows PowerShell. That would allow users to |
| 200 | +launch any installed PowerShell version from `pwsh.exe`, making it easy to set |
| 201 | +up automation with one command to invoke. Arguments from `pwsh.exe` could be |
| 202 | +mapped to arguments on `powershell.exe`. |
| 203 | + |
| 204 | +### Are containers and Docker enough to solve this need? |
| 205 | + |
| 206 | +While discussing this with a colleague of mine, they asked if this is really |
| 207 | +needed, or if containers and Docker solve this problem already. While I believe |
| 208 | +containers can allow users to use different versions of PowerShell, I also |
| 209 | +suspect that most users don't know how to set that up, if they even use Docker |
| 210 | +at all. I think it would be easier for everyone if we could just launch the |
| 211 | +proper version of PowerShell via `pwsh.exe`. |
| 212 | + |
| 213 | +### Maintain backwards compatibility with pwsh.exe -version |
| 214 | + |
| 215 | +In PowerShell Core 6.2, if you invoke `pwsh -version` you get the current |
| 216 | +PowerShell version. That support could remain in place if this RFC is approved, |
| 217 | +returning the current (latest) version when invoked without a version, or |
| 218 | +launching the requested version when invoked with a version. |
| 219 | + |
| 220 | +### Windows Update |
| 221 | + |
| 222 | +If PowerShell is added back as a component of Windows, some consideration needs |
| 223 | +to be given to Windows Update. With side-by-side installations, it would not |
| 224 | +make much sense to update older versions, so the most recently installed stable |
| 225 | +version should be treated as the default version to check for updates. |
| 226 | + |
| 227 | +Unfortunately I do not have much insight into what Windows Update requires. |
| 228 | +@iSazonov mentioned he remembers it requiring the _same_ installation folder, |
| 229 | +and if that is the case, how would that work with a SxS updateable PowerShell. |
| 230 | +If someone who knows what is actually required to make Windows Update work |
| 231 | +could share what could/should be done here, that would be appreciated. Ideally |
| 232 | +PowerShell would work like dotnet works, supporting side-by-side installations |
| 233 | +while being updateable via Windows Update as well. |
| 234 | + |
| 235 | +### Version discovery and registration |
| 236 | + |
| 237 | +Currently the PowerShell installer allows you to install PowerShell into any |
| 238 | +folder you want. This flexibility comes at a cost, because it means registering |
| 239 | +installations of PowerShell on a system to make sure they are discoverable. |
| 240 | + |
| 241 | +Since PowerShell is a runtime that other products need to be able to depend on, |
| 242 | +some thought needs to be given towards how best to install it. I believe it |
| 243 | +would be better to only install to known locations for all users/system or for |
| 244 | +the current user so that we could check the filesystem to discover versions of |
| 245 | +PowerShell that are installed, regardless of what platform we are on. It is |
| 246 | +likely that this would also make building solutions on top of side-by-side |
| 247 | +installations of PowerShell easier, so that they can check for the required |
| 248 | +version easily. |
| 249 | + |
| 250 | +It is worth mentioning that the dotnet sdk installer does not ask you where |
| 251 | +you want to install it. Instead it installs to one of two locations, depending |
| 252 | +on whether or not you are an admin (i.e. it installs to an all users/system |
| 253 | +location if you are admin, or to a user location if you are not). |
0 commit comments