Powershell *could have been* the best shell scripting language ever. But Microsoft destroyed it.
The core problem with scripting languages is that they rely on lexical parsing of the text output from a command. You run a command to get a list of the employees, and you know that the 3rd column of the output contains a string with the date they were hired, so you used sed and awk to skip 2 commas, then any spaces, then grab the first four digits, and now you have the year of their hire. Great! But this is difficult and likely to break if the output format changes.
Powershell commands returned objects, so you run the cmdlet and grab the "Hiredate.year" property. That won't break, and if it is removed the code *should* throw an exception. And the brilliant part is that it still worked like a textual command-prompt when used interactively, because Powershell displays the objects as text when you typed a command! Amazing! It is the best of both worlds.
And it can call .NET so it has all the power of a real language like C#!
Yet Powershell is the least reliable, most likely to break in unexpected ways, scripting language that I have ever used. My teams have forbidden it from anything more than a few lines because we have been so burned. So where did Powershell go wrong?
First problem: Powershell's CD command doesn't work. The current directory is always c:\windows\system32 unless you do some wacky stuff. There is a reason for this, but it is dumb and not worth it. Just never use Set-Location in Powershell.
Next, even though Powershell has exception handling, it ignores errors and just plows on. So that example I gave about Hiredate.year doesn't actually work. If they change the output, the code silently breaks, completely defeating the entire purpose of the language. Plus you have the old problem of: 1) CD/Set-Location $myDirectory, 2) delete *.*, and if the CD command failed you just deleted c:\windows\system32. Genius!
Next, Powershell has lots of DWIM (Do what I mean) commands. So suppose you call .Count on something, Powershell could decide to return 0 of that thing has no count property. Or it could decide to return the count of properties on it. Or it could decide to return the Count property of the first object in the collection, if the collection has only one element. It depends.
Powershell makes extensive use of "implicit" variables like $_ and global settings. So you can call a command that changes those and your script behavior changes mid-run.
Return values are broken - there is a return command, but it doesn't do what you think it does.
Overall, Microsoft didn't learn any of the lessons from PERL, PHP, or Python about what makes a language unpredictable or inconsistent. They took the best idea to come into scripting in 20 years, then combined it with the worst mistakes of those languages.