Prof. Powershell
This Match Has No Equal: Comparison Operators
Working with the -eq, -match, and -like comparison operators in PowerShell.
- By Jeffery Hicks
- 04/24/2012
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.