Terms of Use For FixedByVonnie

By proceeding to access fixedByVonnie.com, you expressly acknowledge, and agree to, all of the following:

fixedByVonnie.com is a personal website and blog owned by Security Plus Pro LLC, which is being presented for informational purposes only. The views on this website are solely those of the website owner (and not those of any employer or of any professional associations affiliated with the website owner).  Any views expressed in this website and any information presented on this website, or in any of its blog entries, should not be relied on for any purpose whatsoever other than as the personal opinions of the website owner.  The website owner expressly disclaims any and all liability for any information presented on this site.  The owner of this website and its blog posts shall not be held liable, and shall be held harmless, for any errors or omissions in any information or representations contained in this website, or in any of its blog entries.  The website owner also expressly disclaims any liability for the current or future availability of any such information. The website owner makes no representations as to the accuracy or completeness of any information on this website or which may be found by following any link on this website. The website owner shall not be held liable for any losses, injuries, damages, claims, or causes of action, from the display or use of any information on this website or in any of its blog entries. If you use the information on this website, or on any of its blog entries, you do so solely at your own risk.

Say what’s up to PowerShell 5 (Part 18/27) - fixedByVonnie

Say what’s up to PowerShell 5 (Part 18/27)

So in our previous posts, you learned all about PowerShell objects, how to use Select-Object to select specific properties of that object, how to use Sort-Object to order the output and even how to use hash tables to create computed columns on the fly (that’s that @{n=blah;e=1 -gt 2;} business)

In this post I want to show you the last command you need to gain complete control over what PowerShell shows you.  It’s called Where-Object and it’s awesome.

When I started learning PowerShell the thing that gave me the greatest trepidation were those blasted hash tables and also the comparison syntax.

In most progrmaming langauges the greater than symbol, >, is used to indicate that what’s on hte left is greater than what’s on the right.  And the equal symbol, =, is used to show equivalency.  Not so in PowerShell!

If you type:

get-help *operators"

Comparison operators in PowerShell

you can learn how PowerShell thinks about operators but I’ll spare you the trouble by breaking it down for you right here, right now.

Go ahead and type 1 < 10 in PowerShell.

PowerShell less than symbol

This fails because in the shell the less than symbol already serves a purpose: it’s the redirection operator.  In other words, it redirect output.

So we can’t use that.

Here’s how you do comparisons in PowerShell:

  • -lt is less than
  • -le is less than or equal
  • -gt is greater than
  • -ge is greater than or equal
  • -eq is equal
  • -ne is not equal

So if we type:

1 -lt 10

we get success!

1 is -lt 10

Having fun Where-Object

So let’s say you only want to see services that are running.

You could type:

gsv | where-object { $_.status -eq "stopped" }

or you could use the where-object alias of a question mark to achieve the same goal:

gsv | ? { $_.status -eq "stopped" }


But let’s say we only want the stopped services that have names that begin with an “m”.

We could use the -and parameter with a wildcard character like this…

gsv | ? { $_.status -eq "stopped" -and $_.name -like "m*"}

PowerShell -and operator

Cool, but here’s the thing:

Whenever you start filtering you always need to filter as far left as possible.

PowerShell doesn’t have the word Power in there by accident.  You can use PowerShell to pull data from thousands of computers and if you’re filtering isn’t setup right you’ll waste precious computer resources trying to display your data.

Let’s take a look at the command we just typed again without the cryptic partial parameters:

Get-Service | Where-Object { $_.status -eq "stopped" -and $_.name -like "m*"}

The far left contains no filters.  In other words, the Get-Service cmdlet isn’t doing anything to narrow down the results.  So all the results are getting sent to Where-Object and then and ONLY THEN are they being filtered.  This could be a huge problem if you’re pulling data from thousands of hosts across a network.  You could oversaturate the link.

So we need to see how we can do our filtering in Get-Service. We should filter as much as we can to the left as early as possible.

You can figure this out by looking in the help cmdlet for any parameters that can restrict your results.

I just happen to know that Get-Service let’s us do the name filtering like so:

Get-Service m*

Filtering Get-Service


So let’s rewrite our where-object clause so that name filtering is done to the left in Get-Service.

Get-Service -Name m* | Where-Object { $_.status -eq "stopped"}

Filtering to the left


gsv m* | ? { $_.status -eq "stopped" }

Filtering to the left 2

Same difference.

That way if we ever decide to use this to pull data from multiple  computers it won’t kill the network.

Get-Service -Name m* -ComputerName dc17alx1, ws11alx1 | Where-Object { $_.status -eq "stopped"}


Connect with Vonnie on Twitter

Posted in Windows, Windows 10 Tagged with: