Prof. Powershell

This Match Has No Equal: Comparison Operators

Working with the -eq, -match, and -like comparison operators in PowerShell.

In this week's lesson I want to cover something I see frequently in forums and blogs, especially from people just getting started with PowerShell or coming from a VBScript background: comparison operators. Specifically, I want to look at when to use -EQ and when to use -Match or -Like.

First, the most important thing to realize about comparison operators is that they will return True or False:

PS C:\> 5 -eq 5
True

The -eq operator used to test if something equals something. In this case 5=5 so PowerShell returned True. The inverse is the -ne operator:

PS C:\> 5 -ne 5
False

You can also use -eq with strings. By default it is not case sensitive:

PS C:\> "jeff" -eq "JEFF"
True

This works just fine for simple comparisons:

PS C:\> get-process | where {$_.company -eq "microsoft corp."}

Handles NPM(K) PM(K) WS(K) VM(M) CPU(s)   Id ProcessName
------- ------ ----- ----- ----- ------   -- -----------
    575     26 11336 18864    88   0.25 2148 MSOIDSVC
     74      7  2952  5288    35   0.03 2312 MSOIDSVCM

Which leads me to another thing I see often. Using Process objects as an example, suppose I want to find all process objects that do not have a company name property. I often see people write something like this:

PS C:\> get-process | where {$_.company -eq $Null} | select name

Name
----
audiodg
Idle
MotoConnectService
NMSAccessU
System

Technically there is nothing wrong and as you can see it works. But in this situation, if $_.Company doesn't exist the Where clause will return False, so the -eq is implied. Usually you want to only grab objects with a defined value so this:

PS C:\> get-process | where {$_.company } | sort Company | group Company

is a better PowerShell approach in my opinion. We're not trying to compare strings, we are working with objects. Which leads to the final part of today's lesson, comparing with simple regular expressions.

If you look at the process objects, you'll notice some vendors have a number of variations on their name, especially Microsoft. If I want to find all Microsoft-related processes, I can' use a simple -eq. Instead I have to rely on using the -match operator:

PS C:\> get-process | where {$_.company -match "Microsoft"} | select Company -unique

Company
-------
Microsoft Corporation
Microsoft (R) Corporation
Microsoft Corp.

Now I retrieved all process objects where the company property include Microsoft anywhere in the name. The -match operator can use full regular expression syntax, but I'll cover that in a future lesson. If I wanted to find the opposite, I can use -notmatch:

PS C:\> get-process | where {$_.company -notmatch "Microsoft" -and $_.company} | measure

Count : 73
...

Notice my compound comparison. The other approach you can take is to use the -like operator which permits the use of wildcards. Here are all the processes on my computer with a company that starts with M:

PS C:\> get-process | where {$_.company -like "M*"} | select company -unique

Company
-------
Microsoft Corporation
Microsoft (R) Corporation
Motorola
Microsoft Corp.
Mozilla Messaging

Deciding which operator to use ultimately depends on the context of your command and what you are trying to achieve. Just remember that you are working with objects and strive for economy and efficiency.

To learn more about these operators, take a look at the help topic About__Comparison_Operators or my book, Windows PowerShell 2.0: TFM.

About the Author

Jeffery Hicks is an IT veteran with over 25 years of experience, much of it spent as an IT infrastructure consultant specializing in Microsoft server technologies with an emphasis in automation and efficiency. He is a multi-year recipient of the Microsoft MVP Award in Windows PowerShell. He works today as an independent author, trainer and consultant. Jeff has written for numerous online sites and print publications, is a contributing editor at Petri.com, and a frequent speaker at technology conferences and user groups.

comments powered by Disqus
Most   Popular