Article might be more successful if it demonstrated some of the advantages of PowerShell, such as returning the output as objects instead of lines, and what you can do with them as a result.
I'll admit to being in the "Bash is what I know, I'll just install WSL/Cygwin/PuTTY on my Windows workstation and be done with it" crowd. PowerShell is on my bucket list of things I need to learn at some point, or at the very least just get a RosettaCode cheatsheet of common stuff I do in bash and how to do it in PowerShell for when I'm stuck on remote Windows servers.
> Article might be more successful if it demonstrated some of the advantages of PowerShell, such as returning the output as objects instead of lines, and what you can do with them as a result.
The costs of doing this don't get enough mention though. You're essentially locking yourself into an ecosystem.
It's typical in bash to have a pipeline where every program is written in a different language -- shell scripts, Python, C, C++, Rust etc. They can all operate on text, but what is a Python program supposed to do with a Rust object or vice versa?
It only works between two programs that support the same object format. But in that case you're effectively passing an object to a function in the same language. Languages already have that with lower overhead than pipes. Even if you're set on using pipes, nothing really stops you from piping a binary format object from one program to another, as long as they use the same object format.
So I think the people who say to compare PS to python and not bash are right, but it's not even that -- just compare it to any other language that has objects. It can pass the objects easily within the language but not outside of it. That's hardly a novelty. And then, despite the ostensible ports to other platforms, you have the usual drawbacks of vendor-specific languages -- many of the APIs only exist or do something useful on Windows and you're locking yourself into the platform.
Sure, but my understanding is that PowerShell by itself can do alot of the stuff I typically use four or five pipes to accomplish (e.g. `grep regex myFile | sort -u | cut -d ',' -f 3`). In which case, it might not be as much of a problem for most use-cases.
Sure it can, but so can one python script. For that matter, so can the four or five pipes. What's so wrong with `grep regex myFile | sort -u | cut -d ',' -f 3` etc.?
It would be nice if PowerShell had object serialization and deserialization functions built into the language or standard library, similar to the Common Lisp read and print functions.
This would make it possible for PowerShell to interoperate with other command line facilities.
Awesome. Thank you for letting me know about those. I have been using bash and Perl for many years, but have only dabbled in PowerShell since almost all of my work happens on Linux.
I am bookmarking those because I expect to have to use PowerShell for some automation tasks on Windows in the near future.
So you're locking yourself into an ecosystem. You have to replace everything with .NET.
Even existing things that are written in C++ or Python would have to be specifically rewritten to input and output .NET runtime objects. And why use that rather than any other object format that isn't tied to a specific vendor?
I made a Bash script for HN, and while I’m the furthest thing from an expert in Bash (I’m a newb), I was impressed by a contribution made with a port of the script to Powershell[1]. You can see the same script compared in Bash, Powershell and Python!
Prior to this I had never really explored PS, but it is definitely cool
Thanks rasengan. I've been using PowerShell for about 5 years now. I was trying to learn Bash, but I found too limiting -- it was like going backwards. So, I started learning Python.
You'll notice that the PowerShell and Python versions are very similar.
In fairness, when I ported the Bash version to PowerShell and then Python, the Bash version was much shorter. rasengan later added a lot of functionality to the Bash version.
And the point was to demonstrate some of the functionality in a short example, not to be a line-by-line port. I find it's easier to learn a new language by looking at a short example. The rest is left as an exercise to the reader.
This seems pretty unfair to bash - bash version is way longer than needed, both because it does more (more fields, difference tracking) and because it is written very vebosely (very long prefixes on each var, using multiple calls instead of single “read” command)
I really dislike those comparisons where one side wins not because the language is better, but because it does much less.
Thanks for posting this, it's interesting to see the same problem solved in 3 languages.
I use Bash for all my scripting needs, on both Windows and Linux - I just can't get over my dislike of Powershell's verbose syntax and Pascal-Snake-Case naming!
But some things are difficult or finicky in Bash; maybe I should stop putting off learning Python...
Commands use <Verb>-<Adjective><Noun> structure, for example Get-ADUser gets an AD user. Once you learn that, it's easy to know that the equivalent command for AzureAD is Get-AzureADUser.
It did take me a while to get used to it, but it does make sense, and it makes it easier to learn/remember commands.
I know about the lack of case sensitivity, but in idiomatic Powershell, it's Pascal-Kebab-Case. If I use a language, almost everyone else's code is going to be idiomatic, so I would write idiomatic code too.
Well... yes, I suppose it is a bit silly! I've really tried to like it, but I just can't get past it.
It's just my personal preference, but I've come across quite a few others who dislike the naming of Powershell commands too - seems to be a real love/hate kind of thing.
A very basic example of that, from my own use, is storing the result of a frequently issued large recursive directory search that always returns much the same list of files in a variable, and then using foreach to iterate over the variable multiple times to do stuff. Being a list of objects rather than an array of strings means that object properties and methods are still available within the loop bodies, the objects not having been flattened into just filenames.
PowerShell occupies the same area on Windows that REXX did on OS/2, indeed the same area that Object REXX did. Its useful properties are not that it can be made to look somewhat like POSIX shell commands. In many ways asking "What are the advantages over a POSIX shell?" is not even asking the right question. Its useful properties are rather different.
One such is that it can be used as an interpreted environment for rapidly prototyping .NET programs. I've used it to interactively do quick and dirty mixed file and SQL handling that would have required several full edit+compile+debug cycles in C# (and not just edit-and-continue).
It can speak to anything that has a .NET API. This includes Windows Forms. https://github.com/jdebp/terminal-tests/blob/master/PowerShe... is a PowerShell program that uses ECMA-48 output to Windows Terminal to draw a wriggling worm, with a Windows Forms dialogue box alongside it that can control various test parameters as it goes.
It's employable in the same sort of "glue" areas that REXX was. It is very useful in Azure/TFS build pipelines, for example. Don't think of it as a "server" thing because of this, though. It's a "glue" thing, as useful on desktop machines as on servers. It's the same improvement over writing glue as CMD scripts on Windows as REXX was over writing glue as CMD scripts on OS/2.
I haven't explored its embeddability myself, but like TCL, REXX, and others it can be used as an embedded in-process scripting language within other programs. Again, this isn't something that one directly contrasts with a POSIX shell.
I absolutely abuse Bash for more usecases than I should on my mac, but you owe it to yourself to try out Powershell Core on PC. It is very, very productive. If it weren't for a couple nuances, I would consider switching to it on my Mac as well.
`ls` is an alias on windows systems. I dont remember what the command maps to, but it maps to something. Same thing with a lot of others (e.g. cat is an alias for Get-Content)
You could always make aliases. For example, ls would be 'wsl ls' to run the ls command from Linux instead of searching down the Windows exec path for it.
Also, I noticed at least my version of powershell actually has a built in 'ls'. It isn't quite the same as 'wsl ls' but it does show results more appropriate for Windows file systems.
I dev on a Mac and do a lot of 'quality of life' scripting with Bash. I recently had to do something on a PC and figured I'd try out Powershell. I have to say, it was a joy. Dealing with objects instead of text is so refreshing, it really is a game changer especially when you start integrating with COM (e.g. excel).
The only things I found worse:
1 - error handling doesnt bubble in the same way. e.g. I can't do an equivalent of `set -e`, or do `cmd && other_cmd`
2 - return values are very nuanced. If you don't understand how function statement contribute to the result, you will spend a lot of time debugging odd issues
As people mentioned there is `$ErrorActionPreference = "Stop"` but it's not equivalent to bash `set -e`. Looks like there is no consensus if we'll get something similar in the near future (https://github.com/PowerShell/PowerShell-RFC/pull/88)
I think PowerShell doesn’t really compete with Bash, it competes with Python, Perl or the like. And I haven’t found it to be superior in that aspect other than at integration with Windows system stuff.
PowerShell should raise the bar for lowest common denominator of scripting on Windows systems. I've dabbled a bit it, but I was disappointed it was so tightly coupled (possibly by necessity?) with the .NET runtime version. This makes it much more difficult to update on old systems. I had to write PowerShell in the oldest compatible version. It's almost like dealing with JavaScript implementations of all versions if IE. Other scripting langues like Python provides user-space virtual environments with forward/backward compatibility. Does PowerShell have a universally available package manager (ie. Windows Update)? I don't spend much time in the Windows world. But, the friction of using PowerShell was higher than my tolerance.
This is a pretty poor comparison of the two, especially once it gets into the syntax, of which most of the Bash examples are broken in some way.
There’s also a lot of just straight errors, such as mentioning “true” and “false” “values” in Bash, which don’t exist—the userland toolset includes “true” and “false” programs that can be used to inject desired exit code status into some logic flow, but there is no real concept of a Boolean type.
Overall, if you’re going to provide a rundown of how x and y compare, you should probably give real examples, not just a laundry list of “instead of grep, we use select-string; instead of sed we use -replace”. But how do you use them? I worked with Powershell some over a decade ago, but this article doesn’t give enough info for me to understand what to do with the information it’s providing. And given the errors in describing how Bash works, I’m skeptical that the Powershell examples are syntactically correct either.
Its designed for shell usage, python, ruby and friends don't feel "native" in that manner and are simply akward for many cases by missing most improtant thing - pipeline. People use them because bash suck and because they want to be full stack.
The biggest issue in PowerShell is very slow script execution startup time, 300-500ms seems to be typical. So forget about externally launching PowerShell scripts thousands of times.
The second biggest issue I've seen is generic lack of robustness and maturity. Default cmdlets do the common case nicely, but once you have something unusual in the mix things go wrong fast... By unusual, I mean things like filesystem junctions, volumes mounted into directories.
If you want colors, Write-Host is nice. Except that it goes only to console AND to (undocumented?) file id 6! (same way like stdout goes to 1, stderr to 2, etc.).
PowerShell seems to behave slightly differently in each Windows version. A script that's written for Win10 1803 might just break under 1809.
I don't have much issues with Bash etc., even sh. It performs well and is very robust. I do hate its many footguns, like how easy it is to get escaping wrong.
> Received wisdom about Write-Host, by the way, is that one rarely wants it.
Yeah, totally got that. But how else you can generate colorized easy-to-read output, where yellow warnings stand out?
There should be something like Write-Host that outputs colors to console stdout handle and silently drops color properties when writing to (anonymous) pipe stdout handle.
I use PowerShell for quite some time (mostly windows/.NET guy here) and it would be great tool except one thing: the amount of not obvious quirks is astounding and not really decreased over the years. Probably because of avoidance of breaking changes, which is understandable where there are tons on powershell scripts out there. But for for someone who uses it mostly as a shell to write one liners or occasionally write a script not longer than 30 lines of code, it's really discouraging when you encounter again some unexpected behavior (even though you thought you learned powershell "good enoguht" couple years ago).
Yes, this could be problematic. But any language has this kind of quirks (rust, ruby etc.). The problem is not like with C where you have quirks forever.
Having used both, in a personal and professional capacity, I don't think they occupy the same "real estate". If you have a bunch of Windows systems to admin, sure, PowerShell works great with all the Windows built-ins. In fact, it works with SCCM pretty well. If your systems are Linux-based, you can use shell scripts to interface with something like Chef or Rundeck. Use something that works natively and is designed for the platform you need to orchestrate.
That presumes, which is always my complaint about this subject, that this is an advantage. I'd say that's what sh, ksh, and bash have over powershell (tm).
The problem with pipelines of objects is that it is inherently a more strongly typed, defined, interface. And therefore special-case. Streams of characters is as loosely typed as it gets. And for processing text files and gluing disjointed tools together, it may seem crude, but is very effective. Especially for quick text processing jobs, or automating series of commands.
The UNIX shell concept has been honed and refined over 50 years to do exactly what it does, and it does it very well. It is also extremely generic. This choice was on purpose and has stood up well to the test of time.
Powershell is somewhat a perl-for-windows-admins. A write only pile of special tools and special cases for the peculiarly baroque system interfaces of that particular OS. Neither better or worse than VBA from what I can tell, just the passing style this decade.
>The problem with pipelines of objects is that it is inherently a more strongly typed, defined, interface. And therefore special-case.
Not true. While I am somewhat of a novice at powershell, I didn't find that to be the case at all.
> Streams of characters is as loosely typed as it gets. And for processing text files and gluing disjointed tools together, it may seem crude, but is very effective. Especially for quick text processing jobs, or automating series of commands.
Well done for the Pavlovian regurgitation of how piping text output is supposed to work.
I don't like working with it. It is okay for small scripts. However if it is mildly complicated I would use something like Python (not powershell).
Powershell is great for small scripts where you need to do sysadmin tasks e.g. I have a script where I setup my SQL Database aliases for development. Piping text about doesn't help me in these sorts of tasks. I need to go "I need to find where the real database is, and then map those properties to an alias". That works better with piping objects. It works kinda like functional concepts such as map(), reduce() etc.
You should use the right tool for the right job.
> The UNIX shell concept has been honed and refined over 50 years to do exactly what it does, and it does it very well. It is also extremely generic. This choice was on purpose and has stood up well to the test of time.
You know not everyone thinks that Unix was the pinnacle of human achievement.
I'm not saying UNIX and similar system are even the pinnacle of potential operating systems. But they're pretty darn good, and at least at par with, when compared to other existing mature ones.
> You should use the right tool for the right job.
Agree. UNIX however, has a fundamental file and character based structure. Windows, the opposite. So while powershell and its predecessors are useful in that environment, it's not equally suited to the tasks that bash is used for.
So what I'm poking at is that while bash isn't a great tool for interfacing with the service manager, or registry, or policy frameworks and the like (SQL, definitely), powershell is not a general purpose command processor and text manipulator. And on UNIX, whether you like that philosophy or not, that's all you need. I would never want to use a powershell script to move and rename file structures with some rules and variables.
> It is okay for small scripts.
That's what it's designed for and how it should be used.
If you are talking about libraries or even a lot of functions, or if it's thousands of lines long, other more formal programming languages like Python (and with good debuggers) would be better. But to just bang out an adduser script in 30 minutes, that's where shell is lightweight enough to really shine.
Look, typed OO pipelines sound like a good idea, but the negative side is this. For example, to deal with the registry, you have to have purpose built library like https://docs.microsoft.com/en-us/powershell/module/microsoft... that someone needs to write and then everyone has to know. This has to be done for every kind of interface in windows. This is just as complex as Pythons standard libraries or writing C or C++ Win32 code.
With the UNIX toolkit philosophy, I have about 20 utilities and builtins to know: shell + awk/grep/sed/cut/etc. And that's it. The cons are #1 efficiency is lower and #2 as pointed out by many folks, a lot of scripts spend a lot of code inline (in different ways) things like how to parse a config file.
But back to the article. It's not valid to just presumptively state like a fact that one is better than the other as the argument. And it's really not valid to compare such different tools head-to-head when it's the whole underlying philosophies of their associated ecosystems that are so different.
> So what I'm poking at is that while bash isn't a great tool for interfacing with the service manager, or registry, or policy frameworks and the like (SQL, definitely), powershell is not a general purpose command processor and text manipulator. And on UNIX, whether you like that philosophy or not, that's all you need. I would never want to use a powershell script to move and rename file structures with some rules and variables.
I can manipulate text fine with Powershell without having to use other small programs that may or may not exist on the system. I can also interface with parts of the operating system sensibly. I was reading and writing text files a lot easier with Powershell than I ever did with Bash.
> Look, typed OO pipelines sound like a good idea, but the negative side is this. For example, to deal with the registry, you have to have purpose built library like https://docs.microsoft.com/en-us/powershell/module/microsoft.... that someone needs to write and then everyone has to know. This has to be done for every kind of interface in windows. This is just as complex as Pythons standard libraries or writing C or C++ Win32 code.
You seem to think that this is somehow a negative. I think you should be able to rely on an abstractions. I would rather rely on a well defined and understood interface than writing my own script to manipulate a file. The former is obviously less error prone than the other. Any claim to the contrary is a nonsense.
> But back to the article. It's not valid to just presumptively state like a fact that one is better than the other as the argument. And it's really not valid to compare such different tools head-to-head when it's the whole underlying philosophies of their associated ecosystems that are so different.
Yes one is sane and the other one isn't. I've heard most of these (bogus) arguments before. I hate to sound rude, but I honestly fed up of hearing it.
Agreed! Clearly you mean UNIX/Linux is the sane one, right? Before you fly into a hissy fit and say the UNIX toolkit theory is insane please learn, read, and respect a little history. So all the famous papers, IEEE, ACM, written by folks like DMR and Thompson are "bogus" arguments, right???
These guys might have done things in ways you don't grok, ways you don't like, or ways you think you know how to do better. The UNIX approach, like all complex things, has pros and cons. But until anything you or microsoft has built has stood up for 50 years, been academically published and cited, maybe won a couple Turing awards and Presidential medals, don't try defend an argument with a simple "it's bogus" or "insane" or "nonsense".
> Agreed! Clearly you mean UNIX/Linux is the sane one, right? Before you fly into a hissy fit and say the UNIX toolkit theory is insane please learn, read, and respect a little history. So all the famous papers, IEEE, ACM, written by folks like DMR and Thompson are "bogus" arguments, right???
Seems you are going into the hissy fit. I also don't care about your arguments from authority. Programming against a well defined abstraction will be better than piping things around and easier for people to understand.
> These guys might have done things in ways you don't grok, ways you don't like, or ways you think you know how to do better. The UNIX approach, like all complex things, has pros and cons. But until anything you or microsoft has built has stood up for 50 years, been academically published and cited, maybe won a couple Turing awards and Presidential medals, don't try defend an argument with a simple "it's bogus" or "insane" or "non
This is the Pavlovian response to any criticism of the great unix way. Again all of this is an argument from authority and people used Unix because it was good enough and available. Lets not pretend it was successful because it was so great.
I'm not making an argument to authority. I'm saying you are dismissing, without any valid argument at all, years of reasoned academics and experienced and careful engineering.
So what's your argument? You're level abstract is "better" because it just clearly is. And you're tired of hearing another viewpoint?
I think you are very naive and I don't see you how will gain experience if you don't wish to listen to anything you don't already understand!
> So what's your argument? You're level abstract is "better" because it just clearly is. And you're tired of hearing another viewpoint?
Maybe you are dense. I have heard all these talking points before, many, many, many times. I do not find them convincing. If you regurgitate copy-pasta from 4chan's /g board I am not going to be interested.
> I think you are very naive and I don't see you how will gain experience if you don't wish to listen to anything you don't already understand!
I've been mucking about with computers since the BBC Micro-computer. I have been developing professionally for 15 years. Don't patronise me. I am actually very very cynical.
That's just insulting I'm writing from my own personal experience and trying to explain my arguments.
> professionally for 15 years
So a relative newbie, eh? I might have expected as much.
> I am actually very very cynical.
Understatement. You are not however good at learning or listening. Or debate.
Maybe the reason you keep hearing the same arguments is that there is merit to them. Maybe your viewpoint isn't universal and a large number of other people see things a different way. Maybe the reason you aren't convinced is because you don't take the time to listen and understand what others are saying. I understood your points, I accept some of them, for example bash isn't any good for managing SQL databases. You've offered nothing but insults false assumptions and general negativity and that "you don't like it".
> That's just insulting I'm writing from my own personal experience and trying to explain my arguments.
Your arguments are the same as the copy-pasta. It isn't anything new, it isn't anything convincing and it isn't even an argument really.
> So a relative newbie, eh? I might have expected as much.
Yeah yeah yeah yeah whatever. You conveniently missed out the fact I've been programming since the late 80s, just not as a Software Engineer.
> Understatement. You are not however good at learning or listening. Or debate.
Why should I listen to someone that does the same recycled arguments? I listen to a lot of people, just generally not people who recycle the same old nonsense. You haven't told me anything I haven't heard before.
> Maybe the reason you keep hearing the same arguments is that there is merit to them. Maybe your viewpoint isn't universal and a large number of other people see things a different way. Maybe the reason you aren't convinced is because you don't take the time to listen and understand what others are saying. I understood your points, I accept some of them, for example bash isn't any good for managing SQL databases. You've offered nothing but insults false assumptions and general negativity and that "you don't like it".
I don't think streaming text around between programs is in any way robust. I don't mind the whole "lego pieces" and single responsibility principle. But it is hardly unique to Unix. This tirade against me because I don't agree with your ideology and somehow I am a bad person is quite amusing though. The so called insults were extremely mild so don't pull that nonsense.
The real difference is: in any reasonable bash script there will be a significant amount of awk, cut, tr and other commands to munge the output of one command into the input expected by the next. In PowerShell that totally goes away.
Better stated like this: in Powershell you do business stuff 99% of the time, in bash you do it 1% of the time and arbitrary text parsing 99% of the time.
To be more evil, your text parsing wont work on all platforms, and you probably didn't od it right or you need to be Reg Exp master which is something I rarely find even in senior devs.
I'll admit to being in the "Bash is what I know, I'll just install WSL/Cygwin/PuTTY on my Windows workstation and be done with it" crowd. PowerShell is on my bucket list of things I need to learn at some point, or at the very least just get a RosettaCode cheatsheet of common stuff I do in bash and how to do it in PowerShell for when I'm stuck on remote Windows servers.