Hacker News new | ask | show | jobs
by julianz 3947 days ago
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.
4 comments

A cmdlet is a PowerShell native command. It reads and writes objects, where as Unix commands read and write plain text. Try this in PowerShell:

get-command

get-command | where CommandType -eq "alias"

Notice the lack of parsing. In Unix you'd typically do this kind of thing with grep, but then you'd have to watch out that you don't accidently include the wrong rows because some other column happened to contain the string "alias"

Try this:

Get-Command | Out-GridView

There's this thing called PowerGUI. It has a text editor for writing PS and a computer management GUI tool. It's written in PS itself. At first I wasn't too impressed, but then I noticed in the computer management thing there's an option to "view code". And then I saw how simple it is, how these nice interfaces were implemented with a trivial amount of PowerShell. Now I think PowerShell is great.

PowerGUI is a godsend. Sure PowerShell ISE ships for free, but PowerGUI is a much more capable editor/debugger. It's free as well.
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.

What about service apache2 restart
Or /etc/rc.d/apache2 restart, as one would find in the BSD world (and Slackware, with a bit of modification).

This isn't to mention that it should be relatively trivial to map "restart-service $foo" to "/etc/rc.d/$foo restart" or "systemctl $foo.service restart" or whatever if one so chooses.

FreeBSD uses the service command these days too.
Good to know. In that case, "BSD Land minus FreeBSD and possibly its descendants".
Sure you could write functions or aliases to everything to give them more predictable names. But you shouldn't have to.
It's not like 'systemctl' is the only game in town, though.
You say that as if that makes remembering things easier.
Regarding your edit: service works just fine on ubuntu as well
As do stop, start, and restart (as long as you have /sbin on your path)
Restart-Service:Windows :: service:RHEL ?
Powershell cmdlets are different(ly named) than executables/commands because they don't preferentially emit text: they emit .NET object streams. I suspect this is for compatibility/interrop reasons.

(They are implemented as .NET classes loaded from within libraries, as I recall. Eg, `import-module activedirectory` will load the entire library of AD cmdlets.)

Here's what you can do with object streams:

Get-ADUser | select FirstName,LastName,EmailAddress,Department | where {$_.FirstName -contains "Jeffery"} | format-table

In a traditional Unix pipeline, you'd have to make sure that none of the other fields contained "Jeffery", or you could get false positive results. For example, you might have to use multiple named pipes or temporary files for each of the table columns, and reinterpolate them into a table/CSV/whatever after doing the grep. You could always use Python/Perl/Ruby/Tcl instead of course, but those aren't really shells.

You can also do math, method calls, etc. The example above was just a trivial one.

I find Powershell extremely weird. We have a fair number of Powershell scripts for admin tasks and frankly I think they'd all be easier to understand if they were just written in C#.
Mhmm. I wrote a set of PowerShell scripts to do some basic deployment stuff a while back and I discovered...

- Timing issues with something as simple as "remove file," where the agreed upon Stack Overflow solution was to call it "a few more times until you didn't get an error."

- Broken implementations of recursive folder copy.

- Okay, we'll call upon "rm" and "rmdir" -- oh, PowerShell intercepts those and invokes the previously described buggy routines. (Eventually figured out that I needed to shell out completely.)

In the end I regretted writing these crummy house-of-cards PowerShell scripts.