PowerShell is less like bash and more like a
.net based DrRacket.
You can instantiate
.net objects, query their state, manipulate them interactively, and pass them around. You can also trivially write new shell commands in C#.
If you go through the tutorials and write a cmdlet in C#, and see how it interacts with powershell, you'll understand why it's cool. Might not be useful for everything, but it's well designed and extremely powerful.
Having a command-line interface that allows me to instantiate and interactively mess around with any .NET object was the killer functionality that first got me to really start playing with PowerShell, but the object-oriented pipeline really soured me on text-based pipelines in general. It's a very powerful, I would say underrated, way of doing stuff.
Basic man-page style documentation for your own scripts comes practically free with powershell. Powershell uses named parameters (though technically you're not forced to do so) with command-line tab-completion. Powershell uses a standardized verb+noun syntax design which makes it slightly easier to figure out what commands are what. Powershell uses an object pipeline instead of plain text.
This is the spirit of unix taken to the next generation. It's an incredibly useful CLI environment and pipeline which makes it easy to combine small tools to achieve powerful functionality while also facilitating making scripts by making them easier to use and easier to write.
For example, let's say I wanted to find every process using more than 100m of ram. With powershell that's just:
get-process | where WorkingSet -gt 100e6
Because powershell is object based you gain a lot more potency in the command pipeline. For example, let's say I wanted to kill all processes that matched a certain filter. That's as easy as piping the output of get-process through some filters then into stop-process. Let's say instead I wanted to wait until all instances of firefox are closed, that's just this:
get-process | where path -like '*\firefox.exe' | %{ $_.WaitForExit() }
Powershell is far from perfect and it has a few very annoying gotchas here and there, but so does bash, python, and any other language for that matter. Powershell is a very powerful language that has benefited from a lot of rethinking of some of the traditions in command line interfaces that exist solely because that's how it used to work back in the day despite the reasons for those choices no longer pertaining in the here and now (teletype terminals, slow connections, slow everything, etc.).
A common complaint from people used to bash is that it's verbose. But since everything is autocompleted and there is support support for short aliases it's very hard to claim it has to be more verbose than bash. Using long description funcion names by default, and shorter alias as an option is clearly the sane design choice.
Fundamentally? Passing objects around instead of text means that I spend a tonne less time futzing around with cut, awk and sed transforming the output of one tool into appropriate input for the next one over.
Off the top of my head: native hashmaps. Native JSON marshalling/unmarshalling. Native HTTP calls. Control structures that don't suck (ie, bash doesn't even support variable comparison natively). Probably lots more I'm forgetting.
`test` (aka [) is a bash builtin, FWIW; integer comparison works perfectly well inside (( )).
I generally prefer bash for job control and pipe parallelism. For more complex tasks that would require a hash, internet access complex parsing etc., I tend to write a script in a different language, and plug it into a pipeline with bash.
The lack of parallelism in PS is the second biggest reason I don't use it.
The single biggest reason is bash is my common interface across Linux, Windows (cygwin), OS X and Solaris (when I used to run it).
> The lack of parallelism in PS is the second biggest reason I don't use it.
I've done parallelism in PS, it's not difficult[1][2]. IIRC there were some gotchas, but it's certainly possible.
> For more complex tasks that would require a hash, internet access complex parsing etc., I tend to write a script in a different language, and plug it into a pipeline with bash
Right, you have no other choice in bash. Powershell lets you do all that within the language itself trivially.