This is how we've used Where‑Objects from the earliest days of PowerShell,
you run some command and then pipe the results to Where‑Object.
Remember, Where‑Object has an alias of where,
which is what you'll typically see in examples. Where‑Object uses
a script block to test if the incoming objects meet some
requirement. The script block can be as complicated or as long as
you need it to be, although, as you might imagine,
simple is usually better.
The $_ character, or set of characters, means the
current object in the pipeline.
Now this script block that you see on the screen is looking at
the status property of each incoming service object and it's
then performing a simple comparison.
Where filters usually use some type of comparison operator.
In this example,
I'm using the ‑eq, or equals, operator. If you need to,
there is a help topic that you should look at to learn
more about comparison operators.
In this example,
if the status property of the service object is equal to running,
Where‑Object will pass that object to the next command in the pipeline.
If it doesn't, it just ignores that object.
Now as I said, the script block can be as complex as you need it to be,
but in the end it has to give you a true or false result.
Only objects that give you a true result are passed on.
Starting a few versions ago,
PowerShell introduced a simplified syntax for Where‑Object. The concept's
unchanged, you're applying some type of filtering test,
but the syntax is relaxed.
You don't use $_ and you don't need to create an explicit
script block with the curly braces.
This type of syntax works fine with simple comparisons.
What you see here is an equivalent version of my previous example.
All you need is the property name.
The $_ is implied.
But Where‑Object is still comparing, in this case,
the status property of each service object, and only passing on those
where the value of status is equal to running. And just to keep you on
your toes, there's yet another way to use Where‑Object. Instead of
using $_ in the script block, you can use $psitem.
The concept is still the same,
but instead of using $_ to represent the object, you can use that $psitem.
However, as I'd like to say in PowerShell,
just because you can do something doesn't mean you should.
Personally, I'm not a big fan of $psitem.
I suggest that you stick with the traditional
syntax using a script block and $_.
When you find examples online and in the PowerShell help, this is most
likely what you're going to find anyway. It works everywhere,
and when you get to scripting,
this is definitely the form that I would recommend.
Plus, if your filtering expression is going to be complex,
such as the one I have here on the screen, then you
have no choice but to use this syntax, so why not just use it all the time?
Still, as you gain experience,
if you want to use the simple syntax of the prompt for a
simple comparison to save some typing, go right ahead.
Finally,
don't be surprised if you find yourself combining early and
late filtering ideas in the same command.
The first part of the command with Get‑Service is using the
‑name parameter to limit or filter initial results to services
with the name that starts with w.
This small number of service objects is then passed to
Where‑Object to filter again to only show services that are
running and have a manual start type.
Now, this is an admittedly artificial example, but the point I'm trying
to make is that you need to get in the habit of filtering early and using
Where‑Object when you have no other choices. Get‑Service doesn't have an
option to filter on the status,
so I really have no choice but to use Where‑Object. What I
don't want to see are examples like this.
These are things that I've seen from beginner
PowerShell students over the years.
Yeah, these commands will work,
but that doesn't mean it's the right way. For something like
getting services on the local machine, it really won't make
any difference performance‑wise.
But I want you to get in the habit of filtering the
right way, the PowerShell way, because eventually it will matter.
Building good PowerShell practices that you use all the time will go a
long way in helping you get the most out of PowerShell, and I think you'll find it easier to use.