Filtering Results

Often when you run a cmdlet you will get far more results than you can view. You will need to tell the cmdlet which particular ones you want and you can do this by filtering the returned values.

I think it is important here to recognise that you aren’t filtering what the cmdlet finds you are flittering results from what it found. This is the process:

Run cmdlet > pass output to filter > filter for just the bits we want

This means that it can take a long time to run some commands even though you only want a small subset of results.

Filtering is done by the Where-Object cmdlet or its Alias Where

get-service will return every service installed regardless of it’s status. In my lab this returned 254 services, but what if we only want to see what has started

get-service | where-object -property status -eq running

This reduced the number to 102

What else can we filter on. Remember get-member? We can use this to see all the properties and we can choose to filter on any of them

get-service | get-member

I can see a StartType property, let’s see if we can look at services that aren’t set to autostart

get-service | where-object -property starttype -ne automatic

well that worked but I got 194 services returned in various states and some are started, so how can we find those that are started but not automatically? The answer to this is to replace the -Property parameter with -FilterScript and then put our query into a script block like this:

get-service | where-object -FilterScript {($_.Starttype -ne automatic) -and ($_.status -eq running)}

what we have done here is to tell the script that we want to check each record for its start type and its current status

and finally if we want to see the start type we would need to tell it to include that in the output

get-service | where-object -FilterScript {($_.Starttype -ne automatic) -and ($_.status -eq running)} | select Status, Name, Displayname, StartType

Filtering Left

Remember when I said we should do as much as we can in the cmdlet and pipe the smallest number of result to the pipeline, what did I mean by that? Consider this simple example:

 get-service | where name -like "*bits*"

this returns exactly what you would expect, but to do that its has found all services and then piped that list in where-object which has then re-processed the list to find the one named BITS. It doesn’t take long in this example but we can ask the cdmlet to do that for us without the pipe

get-service -servicename 'BITS'

it returns the same results but faster … let me demonstrate this by measuring the time it takes to complete

Using the Measure-Command I can demonstrate that the filter took longer. In this case it is only milliseconds, but a larger query with more records can be significantly impacted as can the computer it runs on.

Summary

Try to find exactly what you want using cmdlet parameters first.

If that fails you can pipe results in where-object and use either the -Property or -FilterScript parameters to reduce the returned values to a manageable number.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.