PowerShell Ezine, Logon Scripts

Ezine 178 - Filter Data with PowerShell's -Match and -Like

How to Filter Data with PowerShell's -Match and -Like

As with life, scripts often give us too much information.  In both settings the answer is a suitable filter.  PowerShell provides a rich variety of tools to help us select just the data we need.  My favourite method, as we will see, is the 'Where' statement with the '-match' comparitor.

Topics for the Comparators -Match and -Like

 ♣

This Week's Secret

In the case of spreadsheet formulae I admit a fixation with the 'If' statement.  Often times it would have been more efficient to use 'Lookup'.  With PowerShell scripts, although again I could use the 'If' construction, my preference now is for the 'where' clause.  My point is that whether you are designing a spreadsheet or a script, there are numerous ways of achieving the same result.  And while some methods are more efficient than others, it's often just a matter of taste which method you choose.

This Week's Mission

This Week's Mission is relatively straightforward; I want to show you PowerShell techniques which filter data.  The scenario is that we want research WmiObjects in general and 'system' classes in particular.  The problem is we are swamped with names of hundreds of classes.  Our solution will be to use the parent construction of a 'Where-Object' clause, with a comparitor of -Match or -Like.

-Match and -Like

We can distinguish between these two parameter in several ways.  In terms of remembering the difference I think of '-Match' as meaning a pure pattern match.  Whereas to me, '-Like' is a more fuzzy concept that is going to need the wildcard* symbol.  A more technical definition is as follows: -Like is just a wildcard comparison, while -Match is a regular expression, and a superset of -Like.

Example 1: The Where Statement with the -Match Comparitor

WmiObject is our vehicle for this example.  The where-Object statement employs a comparitor to find the pattern "system".  Because we use -Match, "system" can be anywhere in the WMI object's name.  Incidentally, this combination of 'Where' with '-Match' is my favourite method of filtering data.

# PowerShell example to list demonstrate -Match
# Author: Guy Thomas
# May 2010 tested on PowerShell v 1.0 and 2.0

clear-Host
$WMI = get-WmiObject -list | where-Object {$_.name -match "system"}
$WMI
Write-Host $WMI.count "WMI objects contain the word system"

Learning Points

Note 1:  Take special note of the important construction $_.   This means 'in this data stream'.

Note 2:  See how I have employed PowerShell's signature tune the (|) pipe.  The purpose of the pipe is to make the output of the list, the input into the where clause.

Challenge 1:  (Easy) remove the -Object from the where clause.  The script should run just the same.

Challenge 2:  Substitute the question mark (?) for where-Object.  Guy does not like this particular short-cut but many script writers prefer the tighter code which results from using this alias.

Guy Recommends: The Free IP Address Tracker (IPAT) IP Tracker

Calculating IP Address ranges is a black art, which many network managers solve by creating custom Excel spreadsheets.  IPAT cracks this problem of allocating IP addresses in networks in two ways:

For Mr Organized there is a nifty subnet calculator, you enter the network address and the subnet mask, then IPAT works out the usable addresses and their ranges. 

For Mr Lazy IPAT discovers and then displays the IP addresses of existing computers.  Download the Free IP Address Tracker

Example 2: The Where Statement with the -Like Comparitor

The only two changes compared with Example 1 are substituting -Like for -Match and adding a wildcard* in front of system.  -Like says to me 'sort of', 'fuzzy', or 'around about'.

# PowerShell example to demonstrate the comparitor -Like
# Author: Guy Thomas
# Version 1.3 December 2008 tested on PowerShell v 1.0

clear-Host
$WMI = get-WmiObject -list | where-Object {$_.name -like "*system"}
$WMI
Write-Host $WMI.count "WMI objects contain the word system"

Learning Points

Note 1: Introducing $WMI.count helps us to compare these results with example 1; you should see that -Like produces fewer wmiObjects then -Match.  To make -Like show all the "system" object you need to add another wildcard: "*system*".

Example 3: The If Statement with the -Match Comparitor

To give you perspective, I have introduced variations, for example employing an 'If' construction instead of the 'Where' in example 1 and 2.

clear-Host
$i=0
get-WmiObject -list | foreach {
    if($_.name -match "TCP") {
    write-Host $($_.name) ; $i++
    }
}
"There are $i objects containing TCP"

Learning Points

Note 1:  Unlike 'Where', the 'If' statement needs the additional command 'foreach' to kick off the loop through the $_.name.

Note 2:  The syntax of the 'If' construction is (test) then {script block for matching items}

Note 3:  In the line: "There are $i objects containing TCP"
admire how PowerShell interprets the counting variable ($i) in the middle of that text string.  This is called expanding a variable, and only works with "Double quotes".

Example 4: Introducing -NotMatch also -And

The most obvious comparitor is 'equals'.  You code this in PowerShell with -eq  (not =).  However in the present examples, to use -eq effectively we would need to know the name of the specific class.  Whereas in this context we want broader research into possible names containing 'Win32'.

Thus let us look at alternatives to -eq.  It is surprising how often the negative -NotMatch produces a neat solution to a scripting problem.  For instance there are many WmiObjects beginning with CIM, thus one way of excluding them would be to use -NotMatch "CIM".

Just one more point, using multiple criteria for your filter is easy once you master the deceptively simple '-And' syntax.

# PowerShell example to list demonstrate -NotMatch and -and
# Author: Guy Thomas
# Version 1.2 December 2008 tested on PowerShell v 1.0

clear-PSAhost
$WMI = get-WmiObject -list `
| where-Object {$_.name -NotMatch "CIM" -And $_.name -NotMatch "__"}
$WMI
Write-Host $WMI.count "WMI objects not contain CIM or __"

Learning Points

Note 1: It would make my day if you experimented with different filters.  Substitute your ideas for "CIM", and "__".  Perhaps best of all would be to combine -NotMatch and -Match.

Follow-up

As usual with my scripts, the mission is to get you started.  If you want to know more about -Match, -Like and their relatives, then start with PowerShell's own help thus:
get-help about_comparison_operators.  (Or try get-help about*)

These help files introduce a whole world of specific terms, for example, 'regular expression comparisons' and 'wildcard comparison'.  Once you need and understand such extra information, then I have succeeded in my mission of introducing you to -Match and -Like.


If you are looking for handy network utilities, try some of the free downloads at Tools4Ever


If you like this page then please share it with your friends

 


See more Microsoft PowerShell tutorials

PowerShell Tutorials  • Methods  • Cmdlets  • PS Snapin  • Profile.ps1  • Exchange 2007

Command & Expression Mode  • PowerShell pipeline (|)  • PowerShell 'where'  • PowerShell 'Sort'

If you see an error of any kind, do let me know.  Please report any factual mistakes, grammatical errors or broken links, I will be happy to not only to correct the fault, but also to give you credit.


Custom Search

Guy Recommends: WMI Monitor and It's Free!Solarwinds WMI Monitor

Windows Management Instrumentation (WMI) is one of the hidden treasures of Microsoft operating systems.

Fortunately, Solarwinds have created the Free WMI Monitor so that you can actually see and understand these gems of operating system information.  Take the guess work out of which WMI counters to use for scripts.

Download your free copy of WMI Monitor

 

Home Copyright © 1999-2012 Computer Performance LTD All rights reserved

Please report a broken link, or an error.