Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

> And you can’t do both. You can’t be explicit and implicit, you can’t be terse and readable, you can’t be flexible and robust.

PowerShell does quite well in this case.



PowerShell fully disregards the POSIX paradigm (good), and has forged its own path in the world of shells.

- one shell does almost everything, rather than having a million different utilities with their own input/output formats

- everything is not a bag of bytes, or a bunch of text to be parsed; outputs are objects with queryable structure

- comes with a massive standard library, even without .NET

- straightforward, (mostly) sane syntax, thoroughly different from `sh` and descendants

I must say, for all the criticism levelled against it, Microsoft has a penchant for creating really useful and unique programming languages and tools, or at least building on existing tools and improving them. C#, F#, .NET, PowerShell, TypeScript, VS Code, VS. And six out of these seven are now cross-platform and open-source.


I agree with your points.

> PowerShell fully disregards the POSIX paradigm

I agree that it's good.

Why do you think people are still entrenched into mode of thinking these days? Better tooling has switched over to node (NPM) and Python (pip) for anything more complicated than 50 lines.


> Why do you think people are still entrenched into mode of thinking these days?

I dunno. Familiarity? I mainly use Windows because it's what I've used for 23 years, even though I have a dedicated SSD to Linux. Maybe for many people, it's not worth unlearning decades of muscle memory and re-learning PS just so they can get object-oriented shell scripting.


>outputs are objects with queryable structure

I've often wondered how far you could get with a table based text structure in POSIX land.

Things like awk can deal with that already. Its backwards compatible if you ignore the first line.


PS natively deals with JSON, which is nice. Something awk would melt down trying to parse.

it comes in handy when querying REST APIs

https://learn.microsoft.com/en-us/powershell/module/microsof...


I get the feeling Powershell is exactly what the author has in mind when they say

>Historically, operating systems that have fanciful structured interfaces between programs have been left in the dust by Unix, because Unix maximizes flexibility by favoring the lowest-common-denominator interface, which is the string.

at the end, there.

I adore what Posh gives me over bash. I've also seen many people over the years try to use it as Windows's "shittier Bash" without noticing that doing complicated things with strings here is so painful because _you're not supposed to do complicated things with strings._

The readability of Posh is a direct consequence of people learning to work with its stricter, but more composable interfaces.


> Windows's "shittier Bash"

That's how I tried to use it in the first year of using Windows (after switching back). Once I let go of my entrenched habits after years of Linux, I was able to do much more with PowerShell.


I mean, there's some beauty to having all output as string. It's more predictable. But soon you're jumping through so many hoops to get what you want, it's terrible.

I've been learning PowerShell ever since it was launched, but it took me many years to realize it's actually better than bash. Sometimes you have two learn tô stop fighting the tool and embrace it instead.

I still hate the naming schema, though.


> there's some beauty to having all output as string

Yeah, I suppose. :) In a way, it's also antiquated.


I refused to learn PowerShell for way to long. Now that I have, I've started to like it quite a lot. It has some weird stuff, but hey. So did Perl ;-)


Looking at your name...

kichererbsen in german means chick peas, but if you separate the two parts.. and maybe fudge the spelling to kichern, it would literally translates to giggle peas.

in dutch it's kikkererwten which literally translates to frog peas. I always found that funny... makes me want to kichern.


Yep, totally agree. Never thought PowerShell would become my go-to utility knife, but here we go.


Same.

Story time: I've been a diehard bash/zsh fan for the better part of the last two decades (I was a regular user of it since 1999 so that's 24 years now). I daily-drove some form of Linux since 1999 up until ~2010 when I switched to MacOS (zsh). I only switched to using Windows as my daily driver for ~2 1/2 years ago.

Around 2 years ago, I had a script in python that I wrote to process my directory of media files based on the directory name and looked for a subtitle file and pulled that down. For fun, it was a simple enough script that I re-wrote it in bash (WSL2). Six months later, I needed to make a change and was surprised at how much I couldn't read it. I just forgot.

That was OK, I had a boring weekend and rewrote the whole thing in PowerShell. A few things I noticed:

- It was more LOC owing mostly to brackets, etc, but I'm over the whole "less LOC is better" mentality.

- It was faster - but this is probably the result of WSL2, but also, I didn't have to call out to other CLI utilities as much. You can do just about everything in PowerShell and call out to .NET for anything more complex.

- It was far more readable. Having to parse while [ ]; do ... done; is harder than ForEach-Object ( ) { }

- Passing things around as an object is a very pleasant way of scripting (Python could do the same, but it feels more "Programming Language" than "Scripting" at this point)

- Calling an CLI utility is just the same as in Bash (Unless it has spaces, then you just do & "Path to CLI.exe")

I had to make a change recently and was pleasantly surprised at how much I could remember the layout, functions, etc.

I also tried to adhere to the MS-isms like using a Verb-Noun for my functions where it makes sense, and breaking things up in modules.

I don't absolutely love PowerShell, but it is pleasant to use and pulling in .NET stuff is just a line of code away.

Now I use it directly as a daily driver, with Windows Terminal - which is also surprisingly pleasant to use.


I want to add: PowerShell has the amazing pipeline operator `|`. Examples abound in Microsoft’s documentation[1][2].

[1]: https://learn.microsoft.com/en-us/powershell/scripting/learn...

[2]: https://learn.microsoft.com/en-us/powershell/module/microsof...


PowerShell's pipe silently mangles binary data by default:

https://brianreiter.org/2010/01/29/powershells-object-pipeli...

Newer versions of Powershell have flags that must be explicitly passed to fix this, but it can bite you if you are not aware:

https://stackoverflow.com/questions/54086430/how-to-pipe-bin...


That is just a case of people trying to use PowerShell as a bash shell combined with the unfortunate decision by whomever at Microsoft to alias PowerShell cmdlets to well known UNIX tools.

It doesn't "silently mangle" binary data - it assumes you're piping PS objects or text streams through. If it is a text stream, then it will pipe through as Unicode by default.

Invoke-WebRequest (curl) pipes out an object, with the content in (object).Content. Using | uses Unicode by default which "mangles" binary output. So it tries to convert the object into a Unicode text stream then into the file.

The correct way to save an image would be to simply set -OutFile (-o) in Invoke-WebRequest.

If you MUST pipe it through, then you need to access the object's .Content, then use Set-Content -AsByteStream (for PS7+) or use Set-Content -Encoding byte (PS5)

PS5> $(Invoke-WebRequest -Uri https://www.w3schools.com/html/w3schools.jpg -ContentType 'image/jpg').Content | Set-Content -Encoding byte test.jpg

PS7> $(Invoke-WebRequest -Uri https://www.w3schools.com/html/w3schools.jpg -ContentType 'image/jpg').Content | Set-Content -AsByteStream test.jpg

This is useful if you wanted to put the image inside a variable (rather than create a temporary file for the image) and pass it around until you figure out what you want to do with it.


>> That is just a case of people trying to use PowerShell as a bash shell combined with the unfortunate decision by whomever at Microsoft to alias PowerShell cmdlets to well known UNIX tools.

>> It doesn't "silently mangle" binary data - it assumes you're piping PS objects or text streams through. If it is a text stream, then it will pipe through as Unicode by default.

The problem is that PowerShell uses aliases that match UNIX command line utility names and the same pipe syntax, but exhibits subtlely different behavior without any indication of the difference.

If someone is not aware of the difference and they use PowerShell to process production data, their data could be corrupted without them realizing it.


> The problem is that PowerShell uses aliases that match UNIX command line utility names

Agreed.

> If someone is not aware of the difference and they use PowerShell to process production data, their data could be corrupted without them realizing it.

Someone coming from UNIX-land shouldn't be making PowerShell scripts day1. They really should be diving into documentation. Microsoft's documentation on PS is _excellent_ and here is one about pipelining: https://learn.microsoft.com/en-us/powershell/module/microsof...

Notably:

> To support pipelining, the receiving cmdlet must have a parameter that accepts pipeline input. Use the Get-Help command with the Full or Parameter options to determine which parameters of a cmdlet accept pipeline input.

then further down:

---

Using native commands in the pipeline

PowerShell allows you to include native external commands in the pipeline. However, it is important to note that PowerShell's pipeline is object-oriented and does not support raw byte data.

Piping or redirecting output from a native program that outputs raw byte data converts the output to .NET strings. This conversion can cause corruption of the raw data output.

As a workaround, call the native commands using cmd.exe /c or sh -c and use of the | and > operators provided by the native shell.

---

To work with external commands and pipelining, you can refer to this SO (top answer explains it very well): https://stackoverflow.com/questions/8097354/how-do-i-capture...


> Piping or redirecting output from a native program that outputs raw byte data converts the output to .NET strings. This conversion can cause corruption of the raw data output.

And this behavior is terrible and one of many "gotchas" that PowerShell has. Fortunately, there is a chance it will be "fixed": https://github.com/PowerShell/PowerShell/issues/1908#issueco...




Consider applying for YC's Fall 2026 batch! Applications are open till July 27.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: