Takes care of the parsing and makes pipelines less brittle for sure (just look at things like NO_COLOR [0] that are basically "please adopt this so we can stop having to add endless edge cases to strip ansi color codes") because it keeps data flowing between programs into a machine-friendly format. It's only when it reaches a human that it is formatted for a human to see.
Then when you peel off the surface you realize you can invoke C# directly from the shell. That's right, either you can import any C# .dll out there and call it from the shell or flat out write C# in your script and have Powershell execute it at runtime [2]. You can add syntaxic sugar to make your dll easier to work with but any C# dll can be called from powershell.
As a side effect, this means that if you have a front-end/back-end app with the back-end written in C#, you also have a (bad) scripting interface basically for free.
Until then, the footprint is too big, and the installed base is too small.
Microsoft itself is responsible for the POSIX shell - it was required to compile into a 64k text segment on Microsoft Xenix.
Without Bill's beloved Xenix, ksh88 would have been the POSIX standard.
It's all Microsoft's fault.
I simply cannot relate to this prioritization.
Exactly, that's why having to guess command/args and google the man-page is way less productive by a lot. For minimal productivity gains in the time it takes you to type a few characters you've wasted minutes.
Another big benefit mentioned elsewhere is that you can bring in C# directly into the shell.
The other thing is that idiomatic PowerShell takes a "Python perspective" that scripts are often read way more often than they are written and the best, idiomatic examples often use the most verbose forms of names to make things clearer to read.
PowerShell has a very rich aliases system with many, much shorter names for almost everything (and the ability to define your own to your heart's desire; and the ability to list which aliases are active on a current system), and you absolutely can code golf PS1 commands down into very bash-like lines. Most PowerShell veterans tend to write extremely terse stuff at the REPL even when in scripts and online documentation they try to stick to the idiomatic verbosity for others that need to read the scripts and understand what they do (even sometimes themselves months or years later).
Not only use of cmdlet aliases make shorter syntax but also:
- Shortening parameter names to unique prefix
- Use of parameter aliases
- Use of automatic pipeline property binder
In my experience achieving the same or shorter one-liners for the same task as with bash is typical.
But an example that springs to mind for me is "Get-ChildItem".
Two default aliases for this PowerShell command are `ls` and `dir`.
PowerShell seems to build upon data structures, can pass these around much in the same way that is done in the REPL of an interpreter.
Unix shells lean on the file system for that: if you want to "really" pass around data structures, you pass the name of associated file handles, as defined in the namespace of the virtual file system (VFS).
It turn out that the unix way is usually quite sufficient for interactive sessions. Remarkably so.
But I can write PowerShell functions that do type checking. I can sign PowerShell files with a certificate that implements a security policy...
Stuff like that can be done by a Unix shell and VFS in 2021, but the complexity trade-offs start to favor programming environments with a typed call stack.
PowerShell cmdlets (which is all built-in commands, most first party commands, some second and third party modules and wrappers and anything you can easily do in writing your own functions inside scripts) all share a single argument parser, rather than the usual command line application status quo in other shells where it is every app for itself in argument parsing and some programming languages are better than others at it and some libraries in languages are better than others.
One thing the cmdlet argument parser is good at is that it does make it really easy for the cmdlet author to add aliases (alternate names) for arguments (which PowerShell calls Parameters to the cmdlet) right next to where you define your Parameters. As a comparison, this is equally easy in say Python's argparse where you can provide a list of possible argument names in addition to just a single name. (If you are rolling your own in, say, C it may feel a bit harder.)
The other thing that PowerShell's shared argument parser supports is it always allows you to use the shortest non-ambiguous prefix to name an argument. (This is also something that Python's argparse does by default. Other languages/libraries it varies.) Which is basically that it always supports the "tab completion" automatically without actually having to type tab or "complete" the argument. For instance, the Remove-Item cmdlet often used by the alias `rm` doesn't seem to have any obvious aliases for its parameters, but `-r` works just fine like you would just about expect from other things named `rm` because there is no other parameter that starts R other than "-Recurse". It almost works equally well for Remove-Item's "-Force" parameter with the small hiccup that there is also a "-Filter" so you need `-fo`.
Another thing these last couple things demonstrate is that PowerShell's shared argument parser is case-insensitive. (Python's argparse is not, which is where the shared similarities stop.) PowerShell parameters in documentation are almost always shown in PascalCase for readability but most day-to-day use I see tends to be all lower case just like you just have to do in bash (`rm -r -fo`), only in PowerShell it is an option if you are into brevity rather than the only language that these cmdlets understand/parse.
Having a shared parser for all of this across so much of the shell (and easily used when writing your own functions which are treated as cmdlets just the same) means that you can count on it pretty much everywhere and you don't have to know anything about what language your command line tool was written nor worse what library in that language was used for argument parsing. (Python's argparse was only added to the standard library in Python 3.2! There's still tons of Python command line tools in the wild that don't use argparse at all and manually parse their args or use older libraries with fewer features from before the Python team declared a "winner" and added it to the standard library.)
https://devblogs.microsoft.com/scripting/learn-about-using-p...
If you pipe objects around between cmdlets, PowerShell will auto-bind object properties to cmdlet parameters. Which feels like the magic of the Unix pipe text streams everywhere but lets you skip several text parsers (no grep/awk/sed intermediates perhaps) and feels like even more magic when it just works: `Get-Process -Filter something | Stop-Process`. The blog post gets into some of the details of how it works and that it isn't just magic and that in PowerShell you can even inspect with tools like Get-Help to discover how it is doing it and use that to your advantage to automate complex tasks with very simple command lines.
So, you want them to use it a lot when they don't like it?