
In defense of PowerShell - Raesan
http://www.benwilson.me/2015/08/24/hn-doesnt-seem-to-get-powershell/
======
JoshTriplett
> I’m willing to admit that PowerShell isn’t obviously better as a shell than
> something like bash, but it’s unquestionably a better language to use for
> scripting.

There's a missing "on Windows" here. Sure, PowerShell is clearly a tool
designed for the Windows environment. And if you're a Windows system
administrator, it has more tools and glue for that environment. You could use
PowerShell to replace things that you'd otherwise have to write in Python or
similar, not shell.

But that doesn't make it "unquestionably a better language to use for
scripting" overall; it makes it a better fit for its target platform, which is
certainly true.

And an earlier part of the document made exactly that point: PowerShell on
Linux would be as uncomfortable as Cygwin is on Windows. There's an impedance
mismatch there.

~~~
InclinedPlane
I've lived in both the windows and linux/unix worlds and I will say that
powershell is a better scripting language than bash. Bash is ok, but
powershell is nicer. Powershell is sort of like python in that it tends to
force down a path of doing things in a certain way.

Powershell isn't just "more tools and glue for windows stuff", it's a
different way of doing things. In powershell you get named command-line
parameters for free, that's a huge win. You get usage messages and simplified
man-page help baked into the way things work, that's also huge. In powershell
you don't just work with text, you work with objects, which pass along the
pipeline. That means that instead of using sed and awk to muck up the output
of some other script you can just use simple select, where, and format
commands. This is incredibly powerful and an area where linux has fallen
behind.

I like linux a lot, but this attitude of sneering down at windows and
powershell merely because it's not linux is amateurish and parochial. People
should be thinking about adapting the innovations that powershell has made and
building on them instead of looking at it as some bizarre alien beast that
will never be relevant to them.

~~~
JoshTriplett
I'm not sneering at PowerShell because it's not Linux. And I think it's an
impressive model. It's certainly a different way of doing things, and it's
worth looking at and learning from.

But Powershell people dismiss the bash and Linux model of "everything's a
file", too, the same way others dismiss the Powershell model. They're
different; neither is "unquestionably" better for all cases.

Personally, once I start wanting stateful objects I can pass around to
multiple methods, I switch from Bash to Python or Rust. I don't think Bash
fits that use case well either, but that's not the only use case around.

~~~
clinta
Personally I think an interactive shell that works well with objects is
incredibly valuable. I love working in PowerShell and I wish there was a good
Python based shell that I could use to replace zsh. I spend a lot of time in
iPython but it's not quite the same.

------
julianz
I work primarily in a Microsoft environment, although I have Linux shell
experience as well, and I totally don't get Powershell. What is a cmdlet? Why
does it need a stupid made-up name like that? Why are all the commands
incredibly verbose and hard to remember? I avoid using it at every
opportunity.

~~~
nailer
As a Unix person, 'Restart-Service' seems a lot easier to remember than
'systemctl'.

Edit: Restart-Service is also easier to remember than /etc/init.d was.

Edit 2 (rate limit): `service` on RHEL is great, but it's a Red Hat-ism. Which
is fine, I used to work at Red Hat, but still.

It's also pretty limited: you use service to start/stop/restart, but you still
use systemctl to list services, or list /etc/init.d (technically
/etc/rc.d/init.d on RHEL) on older boxes.

On Windows, to get services, it's `get-service`

Fun exercise for readers, given that you now know `restart-service` and `get-
service`:

\- Guess what the powershell command to get processes is.

\- Guess what the powershell command to stop a process is.

\- Guess what the Powershell command to install a package is.

There's some weird ones - dmidecode on Linux becomes get-wmiobject on
Powershell (see the rosetta stone link posted earlier) - but for the most part
it makes more sense than Linux and Unix.

~~~
vezzy-fnord
It's not like 'systemctl' is the only game in town, though.

~~~
itaibn
You say that as if that makes remembering things easier.

------
bashinator
The tab completion in powershell is frustrating to me. I _never_ want to cycle
through every available option (especially when many PSH commands have
literally hundreds of switches). I want the tab-completion to only show
options for which I've started typing the prefix. I want double-tab to print a
listing of said options so that I can see them all at once. Is this possible?
Right now it feels like there's a major lack of discoverability in PSH.

~~~
sithadmin
The usual PowerShell guru's response to your complaint is 'This is what
PowerShell ISE is for'.

Personally I don't think this is elegant, but that's what I usually encounter
in the wild.

~~~
WorldMaker
For what it's worth, Windows 10 enhances the basic command host to support
some more things such as nicer tab completion directly out of the box (for
both traditional cmd.exe and PowerShell) without having to switch to ISE.

------
rikkus
Powershell is a nice language.

Here's map/filter/reduce. Golf welcome.

    
    
      @(1, 2, 3) `
         | % { $_ + 1 } `
         | ? { $_ -gt 2 } `
         | Measure-Object -Sum
         | Select Sum
    

You can write a generic reduce like this:

    
    
      $reduce = {
        param   ([scriptblock]$reducer)
        begin   { $initialised = $false }
        process { 
          if (-not $initialised) {
            $agg = $_
            $initialised = $true
          } else {
            $agg = &$reducer $agg $_
          }
        }
        end     { $agg }
      }
    

And then use it like this:

    
    
      @(1, 2, 3) | &$reduce { param($agg, $i) $agg + $i }

------
yellowapple
As someone who used to use PowerShell rather extensively (back when my dayjob
regrettably involved thousands of Windows machines that needed managing and
support), I feel like trying to compare PowerShell to, say, bash is folly. To
me, PowerShell has more in common with a proper scripting language - somewhere
between Perl and Ruby, but with a nice-ish REPL - than a traditional shell
like bash. Both the Unix-style text-centric paradigm and the PowerShell-style
object-centric paradigm have their place.

That all said, the most recent PowerShell I've significantly touched was
version 2; I've since moved on to greener pastures.

------
parfe
I dislike windows (and by extension, powershell) because a solution such as
changing the port the webserver runs on looks something like:

    
    
        New-ItemProperty IIS:\sites\DemoSite -name bindings -value @{protocol="http";bindingInformation=":8081:"}
    

[http://www.iis.net/learn/manage/powershell/powershell-
snap-i...](http://www.iis.net/learn/manage/powershell/powershell-snap-in-
making-simple-configuration-changes-to-web-sites-and-application-pools)

What did I just modify? Is it persisted to the hard disk? How do i back that
up? How do I revert the change? How do I move this change (and 20 others) from
one server to another? It's three months later, and I want to do something
similar, where can I find the current state of DemoSite and mimic it for
DevSite?

I like plain text. Clearly companies succeed on microsoft products and people
make money administering them. Doesn't mean I have to like it.

~~~
_mgr
That example you gave is from 2008. You would use the current PowerShell
Cmdlets provided for managing IIS.

    
    
      IIS:\>New-WebBinding -Name "Default Web Site" -IPAddress "*" -Port 80 -HostHeader TestSite
    

[https://technet.microsoft.com/en-
us/library/ee790599.aspx](https://technet.microsoft.com/en-
us/library/ee790599.aspx)

~~~
nailer
Edit: updated per research.

Wouldn't it be, for his example of changing the port:

    
    
        Set-WebBinding -Name 'RadWebServer' -IPAddress "*" -Port 443 -PropertyName Port -Value 4430
    

I don't have a huge amount of PowerShell experience so maybe that's incorrect
or has extra bits.

~~~
_mgr
Yes it would be as the OP's question was about changing the binding. My bad.

------
slavik81
I started off as a PowerShell fan, but my introductory experience has been
pretty poor. A little while back, I tried testing the output of a sorting
algorithm with PowerShell. I wrote a line of bash to check my results:

    
    
      diff <(cat output.txt) <(cat output.txt | sort -n)
    

Then I wrote the PowerShell:

    
    
      get-content output.txt | foreach-object { [Int] $_ } | sort-object | out-file -encoding ascii sorted.txt
      compare-object (get-content output.txt) (get-content sorted.txt)
    

Yeah, it's a lot longer. It was the bug that really soured me, though. The
files compare as identical even if output.txt is not sorted.

You go read Microsoft tutorials [1] and they tell you to use Get-Content (cat)
and Compare-Object (diff) like this for comparing files, but what they don't
tell you is that order is ignored. Given how often I see the above code cited
online for comparing files [2][3], I'm not sure that many people actually
understand this.

I still haven't actually figured out how you properly compare files with
PowerShell. I call fc.exe now, but its output is pretty gnarly so all I use is
the return value.

[1] [https://technet.microsoft.com/en-
us/library/Ee156812.aspx](https://technet.microsoft.com/en-
us/library/Ee156812.aspx) [2]
[http://blogs.technet.com/b/heyscriptingguy/archive/2015/04/0...](http://blogs.technet.com/b/heyscriptingguy/archive/2015/04/01/use-
powershell-to-compare-two-files.aspx) [3]
[http://serverfault.com/questions/5598/how-do-i-diff-two-
text...](http://serverfault.com/questions/5598/how-do-i-diff-two-text-files-
in-windows-powershell)

~~~
bjourne
AFAICT, you are just trying to check if a file is sorted? Then wouldn't:

    
    
        diff (cat out.txt | sort | out-string) (cat out.txt -raw)
    

do it?

~~~
slavik81
Yeah, actually. Though, I'd still include the cast to int, because I need to
sort numerically, not lexicographically.

I suppose the lesson is that if you want to preserve line order, you need to
use -raw to prevent Get-Content (cat) from splitting the file into multiple
lines. That still ruins the output text from Compare-Object (diff), but it's
cleaner than fc.exe.

Thanks.

------
nailer
Equivalent Powershell commands to Linux / OS X / OpenBSD / SmartOS:

[https://certsimple.com/rosetta-stone](https://certsimple.com/rosetta-stone)

------
romualdr
I agree with most of the comment: it's weird.

I also agree with the author, you don't try enough or don't bother trying.

i LOVE _nix environnements, but i HAVE to work on Windows. And yeah, at first,
it 's a pain. Nothing works as expected and you get bunch of errors ... but
you have to remember that you're not on a _nix terminal !

You don't expect to master a environnement on a first try, do you ? Remember
this is not the term you know and love. And if you take some time to get used
to, here is your reward:

you will be able to rocks the term on Windows too, and that's pretty badass.

------
_mgr
"I think many of the misconceptions I see on HN about PowerShell (and much of
the Windows hate in general, actually) are because the typical use case on HN
is quite a bit different than that of an internal IT department of a non-tech
company, which is more Microsoft’s focus."

This, and vice versa that you see in other online communities. Debating your
religious position is almost becoming safer than stating your technology
choices, which like religion are quite often not your choices to start with.

------
jfb
Much of the time that PowerShell is mentioned here is in the context of a
discussion about how nun-punchingly awful the Unix shell is, and what could
possibly replace it. I have never used PowerShell, so I have nothing to add to
those discussions, but the fish-out-of-water nature of much of the commentary
about it, particularly the negative commentary, is because of this.

Sadly for those of us who detest the shell, nobody seems to have a good
replacement at hand.

EDIT: superfluous "I" removed

~~~
vezzy-fnord
_Much of the time that PowerShell is mentioned here is in the context of a
discussion about how nun-punchingly awful the Unix shell is, and what could
possibly replace it._

Precisely my impression as well. It's the PowerShell promoters who tend to be
the ones that bait first.

I'm personally not partial to PowerShell, but I hardly loathe it, either. I
think the likes of the Inferno shell and es show the right path to what a
modern shell should resemble.

------
nivla
I have not used powershell so I can't vouch for it. It is mainly because I
couldn't find simple tutorials regarding them. Unix shell on the other hand is
dead simple to use. However I get all icky if I have to use them on scripts.
The outputs are always raw and never structured so it feels like a hackjob
everytime. It also leads way to a different kind of vulnerabilities from
incorrect parsing of outputs. I think this is the part where powershell from
what I heard comes off as superior. The output is structured and you can work
straight with the results.

As far as verbosity, its a mixed bag for me. It makes it easy to read at a
glance with minimal mental parsing but at the same time seems such an
incorrect fit for a shell where it is optimal to have it under a screen line.
You can equate it to trying to write a rant on twitter.

------
stephengillie
The real "gotcha" for Powershell, for me, is the huge differences between
versions. As the author mentions, v3 is much better than v1. The original
version is pretty bad. A lot of parsing cmdlets don't work right. And a lot of
the really useful ones aren't included, which also blocks some of the cool
cmdlets you can download and install.

Having to port a script from Powershell v5 to Powershell v2 is dumb, but sadly
necessary. Usually I'll write a script on the oldest server in the farm to
ensure interoperability. But often the workarounds for v2 break v5's
implementation of select-string or other parsing tools.

And this doesn't get into remote execution or remote script enablement, which
are both separate. Powershell fragmentation is a serious problem that
complicates Windows adminstration and use of this powerful tool.

------
nlawalker
Powershell definitely has its quirks, and unfortunately one of its best
features - powerful remote administration - is also painful to configure and
troubleshoot and is often unreliable and slow.

I wish the team in charge of Powershell would take a page from the Python
community and adopt an opinionated, "one right way to do everything" stance.
For anyone using or looking in to Powershell, here are a few best practices
I've compiled:

\- Concurrency in Powershell is generally ugly and painful. Background jobs
are OK if you want to background something while you're working at the command
line (although you could just open another window) but they're a pain to use
in scripts, plus they're very heavyweight and slow if you need any semblance
of performance. There are other ways of doing concurrency but they are not
well documented and are fairly messy. Events/observer pattern is possible but
weird. If you need concurrency, head for C#.

\- Handling exceptions is way better than it used to be (trap), but still
annoying. For your sanity and everyone else's, set $ErrorActionPreference =
"Stop" at the top of every script, along with Set-StrictMode -Version Latest.

\- Keep track of what you're outputting to your pipeline - anything that
generates output that you're not capturing into a variable gets thrown in the
pipeline, which can wreak havoc, especially if you end up with different types
of objects being emitted. Sprinkle Out-Null around to avoid this. Combine
multiple data fields into a new psobject if necessary (this is also good for
scripts that output a bunch of information at the end).

\- Don't use Write-Host - it's not output and thus can't be redirected. Use
Write-Verbose frequently, and consider adding $VerbosePreference = 'Continue'
in your profile to see verbose output all the time.

\- If you need to access a SQL database, use ADO.NET. Invoke-SqlCmd and the
rest of the sqlps module are a mess, at least the last time I looked. You can
use sqlcmd.exe too but then you're back to text output.

\- Add this to your profile. With this, any time you run something at the
command line, it will be stored in $LastObject. I always forget to store stuff
in a variable.

    
    
      function Out-Default { $input | Tee-Object -var global:LastObject | Microsoft.PowreShell.Core\out-default }

------
dafrankenstein2
Powershall comes handy when I work with open source software technologies on
windows 7

------
tyho
I started reading this article not knowing anything about powershell, and
finished horrified by the issues he tried to dispel in it. No remoting, no
scripting? Are they serious?

~~~
WorldMaker
You didn't read deep enough. Remoting and Scripting are <em>off by
default</em> but available. Remoting is not great, but getting better soon (as
in now-ish) with SSH support getting baked into PowerShell. (Yeah, that SSH,
OpenSSH.) Scripting IS great, you just have to turn it on. (It's off by
default because Microsoft didn't want it to be a virus vector for your
Grandfather's machine who doesn't need shell scripting and likes to click on
every attachment he sees in his email.)

Get-Help about_Execution_Policies # Tells you everything you need to know
about

So the first thing I typically do in PowerShell in user accounts I control is:

Set-ExecutionPolicy RemoteSigned -Scope CurrentUser

After that I can run all the scripts I want to run. (From there it's a quick
jump over to Chocolatey for application installs and PsGet for useful
PowerShell scripts like PoshGit that adds your friendly Git branch info to the
PowerShell prompt.)

------
ossreality
It worse than that, the misunderstanding that is.

I live and breathe Linux. But Powershell is so far ahead of bash for text and
object manipulation, it's not really even a close call.

~~~
aldanor
That's an interesting claim, care to back it?

P.S. *nix shell != bash, there's zsh and fish that are light years ahead re:
tab completion and other general niceties.

~~~
InclinedPlane
Powershell data is not just plain-text, it's all objects. On *nix when you run
"ls -l" you get text. On powershell when you run "gci" you get objects. But
the objects are nicely formatted automatically for you when they hit stdout so
it ends up looking the same.

On powershell if I want to find a list of files that are more than 100k in
size I can just do "gci | where Length -gt 100000". If I want to see the top
10 processes that have the most handles open I just run "get-process | sort
handles -desc | select -first 10". That way of interacting with things extends
all the way through every aspect of powershell and it's incredibly potent. If
I want to query a bunch of build jobs from a service I can just create a
simple couple line script that talks to a web service and returns queries.
Then I can use the built in select, where, format, etc. commands to get at the
data I want. I can filter by jobs that have failed, I can filter by jobs of a
certain type, or that ran on one machine. All of that is basically free on
powershell, it's just baked into the way everything works. It saves you from
all the ridiculous overhead of using perl, sed, awk, etc. just to get at the
data you want.

Aside from that, with powershell you get things like man-page-style help and
usage messages, named parameters, parameter type checking, etc. at very low
cost, as just the natural way of doing things.

The Unix philosophy has always been about having small tools that you can use
together to get big stuff done, powershell very much embodies that philosophy.

------
twerkmonsta
Noone gets Powershell.

~~~
stephengillie
Some of us do, but we've given up trying to expose HN to the shell. The anti-
Microsoft culture that built up in the late 1990s and early 2000s has too much
inertia on HN to overcome by occasional articles.

~~~
jfb
Keep in mind that much of what seemingly makes Powershell so great on Windows
is inapplicable in a Unix shell environment. So there's still some juvenile
"M$ hyuck hycuk" nonsense, but there's also some pretty spot-on discussion of
the difficulty of trying to move tools between very different systems.

