Powershell? More like PowerDSL
I really tried to like Powershell. Despite coming from Unix, I was open to powershell’s ideas like everything being an object. But after sometime with it I concluded powershell adds more friction than benefit.
Powershell’s main novelty is having objects in a shell. But is this trade-off worth it? Especially when it entails allocating .NET objects all the time. Many important programs have stable outputs so adding structure everywhere is rarely useful. Even programs that might change their output like git have a --porcelain flag for programmatic consumption. Any serious tool you rely on for your infrastructure has a --json flag or similar. If it does not, that’s a problem with the tool more than it is with the shell.
I understand that output inconsistency is a real issue and there’s value in having structured objects, but I believe attempting to solve it on the shell level rather than on the tool level is an invasive decision, and I personally think its not worth it. CLI programs often output text. They don’t allocate .NET objects and they don’t make assumptions about the underlying shell. In order to make them
play nicely with the powershell world you’ll have to output json then call ConvertFrom-Json. If the program doesn’t output json then you’re out of luck. You’re back to parsing text just like in Unix shells.
Powershell’s object-pipelines do not replace text-pipelines, but rather exist alongside it, making you hold two execution models in your head. In Unix, everything outputs text, whether it’s a shell builtin or an external command. There’s no “object” and “text” world that you have to think about. To get the most out of powershell and its rich objects, you’ll have to stick to builtin cmdlets or cmdlets made specifically for powershell. This make it feel like a Domain specific language (DSL) for Microsoft’s products. Perhaps a more appropriate name would’ve been PowerDSL instead of Powershell to reflect its common use case.
Performance is another significant issue: Powershell is slow. It starts up slow, runs cmdlets slow, and consumes a relatively large amount of resources for simple operations. Shells should be quick and snappy given how much time we spend using them. Even without using the rich object features of powershell, you’re still paying the performance cost.
Coming from Unix, I was pleasantly surprised to see that powershell has builtin readline support (bash-like keybindings), but I noticed that it sometimes crashes unexpectedly. A keyboard shortcut might crash in your shell… Powershell then shows an error message asking you to report issues for Microsoft’s broken readline implementation on GitHub. That’s a multibillion-dollar corporation by the way.
Extra things that bother me: I found its syntax ugly, its case insensitive-but-sometimes-case-sensitive naming conventions annoying. You have to restart the shell when PATH changes. I noticed they often taxonomize things that don’t need taxonomizing (Looking at you, $PWD.Path). Some things throw exceptions, but other things return null. Those things add friction.
That’s not to say Unix shells are perfect. However, despite being older, they somehow feel more pleasant than powershell. It’s tragic because Microsoft had the opportunity to make something much better.