2017-10-27

Why pwsh Was Chosen For PowerShell Core

2017102701

Intro

With the release of PowerShell Core 6.0.0-beta.9 the binary for PowerShell Core was renamed from powershell.exe and powershell on Windows and Linux/Unix/macOS respectively to pwsh.exe and pwsh. This major change has drained the pitchfork and torch emporiums of their stock as PowerShell users from all over the globe have taken to internet forums, twitter, slack, and the PowerShell repo to voice their opposition and disbelief in this change. The responses range from minor annoyance to expletive heavy diatribes.

It's clear that many PowerShell users are not happy with this change.

So why did the PowerShell Team decided to make such and unpopular change? There are several reasons the change was necessary and for why pwsh was chosen. I will attempt my best here to explain them all.

As you read, please keep in mind that I'm not a Microsoft employee nor am I a member of the PowerShell Team. I'm just a community contributor with collaborator access to the GitHub repo. I don't have any special insider knowledge, but I do follow the repo and PowerShell Core very closely. I am speaking to you as a fellow member of the community as someone with a decent insight into the project, not as an outright authority on all things PowerShell.


PowerShell Core vs Windows PowerShell

Before we can go into the reasons of this change, some background understanding is needed. The PowerShell you know and love on Windows (versions 1.0 through 5.1) is referred to as Windows PowerShell. The next evolution of the PowerShell language, shell, and platform is called PowerShell Core. PowerShell Core will start at version 6.0. It is not an entirely different product but is a major change and a break away from Windows PowerShell.

PowerShell Core runs on .NET Core while Windows PowerShell runs on .NET Framework. You don't need to know all of the differences and similarities, but the major one to consider is that .NET Core is cross-platform (runs on Windows, Linux, macOS and others) while .NET Framework is Windows specific. This is a very oversimplified explanation for the sake of brevity. .NET Core has many of the features of .NET Framework, but not everything. Some features are lost for the sake of cross platform portability. PowerShell Core being built on .NET Core means it too becomes portable and cross-platform. But it also means means some features from Windows PowerShell are sacrificed for that gain.

PowerShell has a history of near complete backwards compatibility with previous major version releases. This is somewhat rare for a programming language. Usually a new major version means massive breaking changes from the previous major version sometimes to the point of requiring complete refactoring of code. For a history lesson, look up the history of PHP especially the very early versions.

PowerShell Core, unfortunately, will not have the level of backwards compatibility PowerShell users may be used to. What is lost is also made up for with a ton of new features, cross-platform compatibility, and the fact that PowerShell Core is now Open Source and Open Development. Community members such as you and myself can make suggestions, file bugs, fix bugs, and add & test new features. Some features lost in PowerShell core wont be missed, others may be missed sorely. But many new changes coming out of the community have been sorely wanted and needed for a long time. This is good for the future of PowerShell even if it is troublesome transition.

This PowerShell Team blog post outlines the future of PowerShell.


Side-By-Side

Now that you have some background info we can get into the "why".

Windows PowerShell has never truly had side-by-side support. What this means is that when you upgrade from 4.0 to 5.0, you cannot still run 4.0. The upgrade replaces the previous version. Yes, you can (but shouldn't) use 2.0 with the right settings and switches, but that's more of a compatibility mode than true side-by-side.

PowerShell Core is being developed with the understanding that it will run side-by-side with Windows PowerShell as well as future and development versions of PowerShell Core. The feature loss in PowerShell Core I spoke of includes many Official Microsoft modules for Windows management and RSAT. Many of those rely on parts from .NET Framework that are just not available in Core. But Windows PowerShell isn't going away anytime soon. As modules are moved to support PowerShell Core more and more of that functionality will be available. Until then, there is a very real expectation that you will need Windows PowerShell (5.1) to manage some aspects of Windows. PowerShell Core is not outright replacing Window PowerShell (at least in the immediate future). You can and will run both.

The problem becomes distinguishing between PowerShell Core and Windows PowerShell. In PowerShell Core 6.0.0-beta.8 and older, the binary was called powershell.exe on Windows. This is troublesome because Windows PowerShell is also powershell.exe. This means that you can't have both in your PATH environment variable because "there can be only one".

To solve this problem, PowerShell Core needed a new binary name. This allows you to have both in your PATH and call both easily. This is going to help you greatly in the future when you need to call back and forth between PowerShell Core and Windows PowerShell. For reference, check out the image above the intro.

This is the primary driving decision for the new name: to support side-by-side operations between PowerShell Core and Windows PowerShell.

Here is the decision by the PowerShell Committee when they approved the new name:

@PowerShell/powershell-committee discussed this and where we landed is to have PSCore6 binary called just pwsh without an additional shortcut/alias for powershell. The benefit is making it explicit without ambiguity on Windows whether you are using Windows PowerShell or PowerShell Core. On non-Windows, it's shorter to type and more consistent with other shell naming. Based on customer feedback, we can always add a powershell link/shortcut/alias in the future.

Here is a YouTube recording of the October 19, 2017 Community Call where Joey Aiello and Steve Lee discuss the name change (relevant part starts at 33:38):


OK, But Why pwsh and not posh or psh??

Unfortunately, posh and psh are both taken in the Linux world. They already belong to other binaries. If the point of changing the binary name was to avoid ambiguity in Windows, what good would it serve to then create ambiguity in Linux? You may be wondering why they care at all about Linux as this is a Microsoft product. Welcome to the new world! PowerShell and Microsoft are citizens of Linux and macOS now. When decisions are made, more than Windows can, will, and must be considered. Many possible new names were considered and eventually pwsh was chosen from the options available, like it or not.

Linux shell binaries are historically only a few characters long and end in sh.with posh and psh out of the running, some of the contenders were prsh and pwrsh.Ultimately, pwsh was chosen. If I had to guess, I would say it was done by committee vote. Also, if I had to guess, I would say that no matter what was chosen people would be asking "why not this or that?" It was a decision that was bound to make some people unhappy no matter how it landed.


Wasn't This About a Shorter Name and Blending in with Linux??

Nope, well, not really.

This confusion on the shorter name comes about from the repo issue where the decision was made. The issue was originally titled "Create Posh as a shorter name for calling powershell.exe". That title was not chosen by the PowerShell Team, but by someone in the community making a suggestion. There were a few other issues opened about using a different binary name, but this one was chosen as the master issue for tracking.

But, having a shorter name is nice. I think a 4 letter command is much better than powershell even if it isn't easy to pronounce an somewhat awkward to type like pwsh. It also fits in with the way things are done on the Linux side of the world.

2017102702

It wasn't about that either. Well, not primarily.

Remember, PowerShell Core is now a *nix citizen too. It's not just visiting, it's there to stay. So in some ways it does need to blend in with the *nix ecosystem. Up until 6.0.0-beta.9 the Linux binary was powershell. If it weren't for the side-by-side issue in Windows it likely would have stayed that way. But, when in Rome, do as romans do. The PowerShell Core binary needed a new name, one that doesn't clash in Windows or Linux, and one that blends in with the *nix ecosystem. pwsh is very Linux-y, but it also fulfils the requirement of being unique in Windows and Linux.


This. Breaks. Everything!!!

No it doesn't. Not really.

First, yes, this is a breaking change. It is one of (probably) 100's between 5.1 and 6.0 and one of a handful between 6.0.0-beta.8 nd 6.0.0-beta.9. That's the nature of major version differences and beta releases.

But, nothing is broken right now. This doesn't break any of your Windows PowerShell scripts. If anything, it ensures they will continue to function by not accidently calling the wrong powershell.exe.

But what about Linux? Surely things are broken there and in all the CI/CD pipelines built to use powershell/powershell.exe for PowerShell Core?

Sure, maybe they are broken for the moment. But, PowerShell Core is still in beta. There is no illusion that it is not in beta. They bake the fact that it's in beta right into the version name: 6.0.0-beta.9. Beta tech should never be used in production. The nature of alpha and beta releases (and to a degree RC releases) is that things will break. If you are using this in production, consider using something else until 6.0.0 is RTM if your systems cannot tolerate the breaking changes between beta iterations. There are bound to be more breaking changes between now and RTM. Don't blame a beta for being what it is.


pwsh is a Stupid Name!!!

2017102703


Conclusion

It is what it is. pwsh is the new name for the PowerShell Core binary, like it or not. The name was changed primarily to support side-by-side operations in Windows between Windows PowerShell and PowerShell Core (and future versions of PowerShell Core). The name was chosen because it is unique in both Windows and Linux where possibly more desirable names were already taken. It's Linux-y in nature because PowerShell is now also a Linux citizen. This change is a breaking change, but nothing of importance should be broken yet as PowerShell Core is still in beta and this change does not affect Windows PowerShell.


Join the conversation on Reddit!