Let me let you in on a little secret: if you learn and understand Powershell you will be indispensable to your employer. Employers are looking for technically adept new hires who know how to script, pipe and flip text without a sweat. And the suits in Redmond are actively making Powershell the de-facto way of doing things in Windows.
Windows Server 2012 R2 defaults to the command line and Windows Server 2016 continues to put the emphases on using this awesome command line utility.
I could rhapsodize about Powershell for hours but today I just want to focus on easily listing all processes from the command line. Let me show you how awesome this is:
It is my conviction that you can do anything faster at the command line than in a GUI. Once you get comfortable with commands you’ll be freaking unstoppable.
Hit the Windows Logo key, type “power”, press and hold Ctrl + Shift while clicking Powershell and you’ll run as Administrator.
Now it’s time to have some freaking fun man.
Okay, now to get a list of all processes just type:
But let’s say you didn’t know you could use the kickass “ps” alias to view your processes – how could you figure out that PS is the way to go?
Say high to Get-Command
Get-Command, Help and Get-Member are my all time favorite Powershell commands because you can use these three to basically figure out anything you need to do in Powershell. Screw Google.
By typing Get-Command -Name *process* I’m telling Powershell to get all the commands that have the word “process” somewhere in the name. The splat on both ends of the noun are wildcard characters that basically say, “Yeah, I don’t give a crap what’s behind process or after process just give me all the crap that has the word process in it”
Get-Command -Name *process*
This is awesome because you’re basically saying:
Hey, Powershell, the command line is daunting I don’t know where to start. All I know is that I want to view a list of all processes on the machine. Do you have any commands that deal with processes?
Now we see there’s a Get-Process hiding out in that list so we could use that to view a list of all processes.
But wait, I typed ps not Get-Process. How did I know ps would do the same thing?
Well, let’s think about that… perhaps ps is an alias for get-process? How would you find out?
If you said Get-Command -Name *alias* then you are already two steps ahead of 80% of the Powershell guys out there.
Get-Command -Name *alias*
So what can we do with Get-Alias?
By the way, notice all the commands start wit ha verb such as “Export”, “Get”, “Set” and have a dash followed by a noun “Alias”, “Process”, “PSHostProcess”, etc… this is standard. This makes guessing commands really intuitive and it’s one of my top five reasons for falling in love with Powershell.
So let’s see what we can do with Get-Alias
I know this looks confusing but stay with me. We’re just trying to figure out how we can view all the aliases for a given command. In other words, ps must be an alias for the definition Get-Process so there must be a way to see all the definitions for a given alias right?
If you browse through the help you’ll see a few things but one pops out immediately.
Let’s type that.
Ctrl + c to return to the prompt and test our theory…
Get-Alias -Definition Get-Process
Well, what do ya know!
Look at the output. The first column shows the command type: so these are all aliases. And the next column shows the alias, gps and the command it maps to: Get-Process. There are actually two:
- gps -> Get-Process
- ps -> Get-Process
This means we can type Get-Process, gps or ps to view a list of all processes on your computer.
Pretty nice right?
You can do a lot of jujitsu with Powershell but let me leave you with one little thing to blow your mind.
Let’s say you do a ps and only want to see the top 3 processes using the most CPU cycles on your box. How would you do that? There’s a really easy way to pull this off.
ps | gm *cpu*
I know that look crazy but stay with me for a second. gm is an alias for Get-Member and it shows you all the properties (columns) for a given command (technically called a Cmdlet). So this little command sends the output of the Get-Process command to Get-Member so we can view all the possible fields we can sort on. We’re looking to see if there are any fields with the name CPU in it.
Okay there is! Notice the first column called “Name” shows “CPU” as a value. So now we know we can sort out process output by CPU.
But what’s the sort command?
Let’s use Get-Command to see all commands that have sort in the name.
Note: I typed gcm but that’s no problem: gcm is just an alias for Get-Command. Since we’re typing it a lot you might as well know that 🙂
So we see one Alias, one Cmdlet and one Application.
An Alias is just another name for a command it looks like we can use a command named sort or Sort-Object. An Application is a standard Windows built-in program like ping.exe or ipconfig.exe.
So let’s try this out with Sort. Maybe we can sort on the CPU field we discovered with Get-Member? (remember ps | gm *cpu*)
Let’s send the results of the ps command into the sort command and see what happens if we give it the CPU property…
ps | sort cpu
Okay, we’re getting closer but we’re getting too many results and the CPU column is sort in the wrong direction. In other words, it’s showing ascending values. The CPU values are climbing as you go down the collection.. is there a way to change that?
Watch this – I’m about to blow your mind again.
Press the up arrow to retrieve your most recent command, type a space and a dash (between the 0 and plus keys) and then hit tab.
Every time you hit tab Powershell shows you a valid parameter belonging to the sort command (technically a Cmdlet but I’m calling it a command to prevent confusion for now) And look at what showed up -Descending! Oh yeah!
ps | sort cpu -Descending
Incidentally that tab-complete thing works on all Powershell stuff so use it often.
Okay, that looks a lot better but we still have more than 3 results. How can we chop out all the extra crap?
Let me ask you: how would you figure that out?
Well, just think about what you’re trying to do. You’re trying to select a specific set of rows. (called Objects in Powershell) In other words, you don’t want to see all the objects returned in the output you just want to select the top three objects from the collection that have the highest CPU values.
I wonder… is there a way?
Is there a way to select a specific set of objects?
Great it exists, but how do we use it?
If you hit up the help file you’ll discover there’s a -First parameter. So let’s connect everything:
ps | sort cpu -Descending | select -first 3
But what if you only care about the Process Name and the CPU?
ps | sort cpu -Descending | select ProcessName, CPU -First 3
Do you see what I did? I simply added the column names (called Properties) that I wanted directly after the select Cmdlet.
So I typed select ProcessName, CPU -First 3 which is saying:
Hey Powershell? Pipe all the output from PS into Sort-Object, also known as sort for short and order the CPU values from highest to lowest. Then take all that crap and pipe it into Select-Object (select for short) but only display the ProcessName and CPU properties and the first 3 rows (objects, remember rows are called objects)
That’s how that works!
The Bottom Line
Powershell is awesome. If you agree show out in the comments below. Also, let me know if you want me to do a series on this and I’ll be glad to do that.