Unfortunately, it also has some real sore points for use as an interactive shell, and even some outright broken behavior. Some that I lament most frequently:
- Powershell has native tab-completion support, but the word-of-god dictated "Verb-Noun" command naming scheme means almost every command shares a common prefix with a slew of entirely unrelated commands, making tab-completion painful.
- Power shell has sparse built-in support for funtional style list manipulation or data structures beyond lists. There's a "map" command (%), but no reduce, zip, tail, etc. These feel like they'd fit in perfectly to the design of the language, but they're just missing. Also, pipes are lazy, but lists are always strict, which can cause friction.
- most operators are strangely named, such as "-eq" for ==, which hurts legibility.
- There're lots of unvoidable brackets, meaning you often need to jump around the line while writing out a command incrementally. For example, to get filenames, you either need to write `(Get-Item).Name` or `Get-Item | %{$_.Name}`. It'd be nice to have something like `Get-Item |. Name` as an option.
- It's impossible to pipe raw bytes between commands/executables; raw bytes are interpreted as strings. This means, for example, it's impossible to pipe a file to `patch`, because the contents will be decoded into strings, piped as strings, then re-encoded with line endings changed, which `patch` rightfully refuses to apply.
- Running Powershell scripts is disabled by default (WTF?)
By comparison, *sh's heavily favor interactive use. For example, you can put io redirections at the start or end of a line, tab-completion is often very good, it's often possible to avoid brackets (ex. with xargs), background/foreground job management, etc.
Overall, I often find Powershell more pleasant to use than *sh, especially when writing scripts. But for interactive use, I often wish Powershell was a little smarter and a little dumber at the same time.