I ended up doing a lot of testing to see what my returned results were.
Auto-vectorization is one of them; usually it "just works", but can be a PITA when dealing with, e.g., pipelines returning sequences you'd prefer to keep separate.
Another is that PowerShell error handling, while robust and powerful, can be difficult to implement properly, especially when "the right thing" isn't what PowerShell expects. Case in point: originally, PowerShell handled standard error output from external commands specially, wrapping lines of stderr output in error objects. While convenient in some cases, this made it unnecessarily difficult to work with external commands that output to stderr in non-failure cases, and was therefore changed in newer versions of PowerShell.
A final, non-language example is cmdlet availability on non-Server Windows versions. While PowerShell mostly has feature parity between desktop and server SKUs, there are at least a few non-Server-specific cmdlets that only work with Windows Server. The only example that comes immediately to mind is the ...-WindowsFeature set of cmdlets to manage installed Windows features; while present on client Windows systems, they fail with an error message unless the target system is running Windows Server. This is a particularly mystifying omission because dism.exe provides an equivalent command-line interface that works everywhere.
However it’s just unintuitive enough, with enough sharp corners, to be a real pain. I find if I haven’t used it for more than a couple weeks, then even doing trivial things require significant time and about a dozen browser tabs of docs.
That said, trying to remember how to use the various *nix tools like curl, find, tar, etc. and wrap them in a bash script isn’t easy either. No free lunch I guess.
* objects are streamed, not text. I look upon sed and awk and their ilk as stone knives and bear skins. why not just dot into fields?
* first-class interaction with libraries. I can import managed DLLs and call their methods. I don't have to build weird little one-off tools or expose porcelain. I can get at everything, it's profoundly hackable in an un-Windows way.
* the language is vectorized - basically like broadcast operators in something like NumPy. $x.foo gives you x's foo if x is an object, or an array of foos if x is an array of objects. it's really really nice.
* separate commands in one binary and argument (sets) are first-class. there's consistent rules about what "-i" will be short for. personally, I can pull all the valid commands and arguments automatically into my accessibility software for voice typing. the whole standard "verb-noun" thing also makes commands be what you expect and discoverable.
things I don't like include the language itself, its weird bindings to .NET (it predated the C# dynamic support and modern collection types), the restriction to .NET, bad support for streams (not sequences), the slowness, and the syntax looks a bit goofy. but it's worth the warts.