about Comparison Operators - PowerShell | Microsoft Docs
source link: https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_comparison_operators?view=powershell-7
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
about_Comparison_Operators
- 03/15/2021
- 12 minutes to read
In this article
Short description
The comparison operators in PowerShell can either compare two values or filter elements of a collection against an input value.
Long description
Comparison operators let you compare values or finding values that match specified patterns. PowerShell includes the following comparison operators:
Long description Type Operator Comparison test Equality -eq equals
-ne not equals
-gt greater than
-ge greater than or equal
-lt less than
-le less than or equal Matching -like string matches wildcard pattern
-notlike string does not match wildcard pattern
-match string matches regex pattern
-notmatch string does not match regex pattern Replacement -replace replaces strings matching a regex pattern Containment -contains collection contains a value
-notcontains collection does not contain a value
-in value is in a collection
-notin value is not in a collection Type -is both objects are the same type
-isnot the objects are not the same type
Common features
By default, all comparison operators are case-insensitive. To make a comparison
operator case-sensitive, add a c
after the -
. For example, -ceq
is the
case-sensitive version of -eq
. To make the case-insensitivity explicit,
add an i
before -
. For example, -ieq
is the explicitly case-insensitive
version of -eq
.
When the input of an operator is a scalar value, the operator returns a Boolean value. When the input is a collection, the operator returns the elements of the collection that match the right-hand value of the expression. If there are no matches in the collection, comparison operators return an empty array. For example:
$a = (1, 2 -eq 3)
$a.GetType().Name
$a.Count
Object[]
0
There are a few exceptions:
- The containment and type operators always return a Boolean value
- The
-replace
operator returns the replacement result - The
-match
and-notmatch
operators also populate the$Matches
automatic variable unless the left-hand side of the expression is a collection.
Equality operators
-eq and -ne
When the left-hand side is scalar, -eq
returns True if the right-hand
side is an exact match, otherwise, -eq
returns False. -ne
does the
opposite; it returns False when both sides match; otherwise, -ne
returns
True.
Example:
2 -eq 2 # Output: True
2 -eq 3 # Output: False
"abc" -eq "abc" # Output: True
"abc" -eq "abc", "def" # Output: False
"abc" -ne "def" # Output: True
"abc" -ne "abc" # Output: False
"abc" -ne "abc", "def" # Output: True
When the left-hand side is a collection, -eq
returns those members that match
the right-hand side, while -ne
filters them out.
Example:
1,2,3 -eq 2 # Output: 2
"abc", "def" -eq "abc" # Output: abc
"abc", "def" -ne "abc" # Output: def
These operators process all elements of the collection. Example:
"zzz", "def", "zzz" -eq "zzz"
zzz
zzz
The equality operators accept any two objects, not just a scalar or collection. But the comparison result is not guaranteed to be meaningful for the end-user. The following example demonstrates the issue.
class MyFileInfoSet {
[String]$File
[Int64]$Size
}
$a = [MyFileInfoSet]@{File = "C:\Windows\explorer.exe"; Size = 4651032}
$b = [MyFileInfoSet]@{File = "C:\Windows\explorer.exe"; Size = 4651032}
$a -eq $b
False
In this example, we created two objects with identical properties. Yet, the
equality test result is False because they are different objects. To create
comparable classes, you need to implement System.IEquatable<T> in your
class. The following example demonstrates the partial implementation of a
MyFileInfoSet class that implements System.IEquatable<T> and has two
properties, File and Size. The Equals()
method returns True if the
File and Size properties of two MyFileInfoSet objects are the same.
class MyFileInfoSet : System.IEquatable[Object] {
[String]$File
[Int64]$Size
[bool] Equals([Object] $obj) {
return ($this.File -eq $obj.File) -and ($this.Size -eq $obj.Size)
}
}
$a = [MyFileInfoSet]@{File = "C:\Windows\explorer.exe"; Size = 4651032}
$b = [MyFileInfoSet]@{File = "C:\Windows\explorer.exe"; Size = 4651032}
$a -eq $b
True
A prominent example of comparing arbitrary objects is to find out if they are
null. But if you need to determine whether a variable is $null
, you must put
$null
on the left-hand side of the equality operator. Putting it on the
right-hand side does not do what you expect.
For example, let $a
be an array containing null elements:
$a = 1, 2, $null, 4, $null, 6
The following tests that $a
is not null.
$null -ne $a
True
The following, however, filers out all null elements from $a
:
$a -ne $null # Output: 1, 2, 4, 6
-gt, -ge, -lt, and -le
-gt
, -ge
, -lt
, and -le
behave very similarly. When both sides are scalar
they return True or False depending on how the two sides compare:
In the following examples, all statements return True.
8 -gt 6 # Output: True
8 -ge 8 # Output: True
6 -lt 8 # Output: True
8 -le 8 # Output: True
In most programming languages the greater-than operator is >
. In
PowerShell, this character is used for redirection. For details, see
about_Redirection.
When the left-hand side is a collection, these operators compare each member of the collection with the right-hand side. Depending on their logic, they either keep or discard the member.
Example:
$a=5, 6, 7, 8, 9
Write-Output "Test collection:"
$a
Write-Output "`nMembers greater than 7"
$a -gt 7
Write-Output "`nMembers greater than or equal to 7"
$a -ge 7
Write-Output "`nMembers smaller than 7"
$a -lt 7
Write-Output "`nMembers smaller than or equal to 7"
$a -le 7
Test collection:
5
6
7
8
9
Members greater than 7
8
9
Members greater than or equal to 7
7
8
9
Members smaller than 7
5
6
Members smaller than or equal to 7
5
6
7
These operators work with any class that implements System.IComparable.
Examples:
# Date comparison
[DateTime]'2001-11-12' -lt [DateTime]'2020-08-01' # True
# Sorting order comparison
'a' -lt 'z' # True; 'a' comes before 'z'
'macOS' -ilt 'MacOS' # False
'MacOS' -ilt 'macOS' # False
'macOS' -clt 'MacOS' # True; 'm' comes before 'M'
The following example demonstrates that there is no symbol on an American QWERTY
keyboard that gets sorted after 'a'. It feeds a set containing all such symbols
to the -gt
operator to compare them against 'a'. The output is an empty array.
$a=' ','`','~','!','@','#','$','%','^','&','*','(',')','_','+','-','=',
'{','}','[',']',':',';','"','''','\','|','/','?','.','>',',','<'
$a -gt 'a'
# Output: Nothing
If the two sides of the operators are not reasonably comparable, these operators raise a non-terminating error.
Matching operators
The matching operators (-like
, -notlike
, -match
, and -notmatch
) find
elements that match or do not match a specified pattern. The pattern for -like
and -notlike
is a wildcard expression (containing *
, ?
, and [ ]
), while
-match
and -notmatch
accept a regular expression (Regex).
The syntax is:
<string[]> -like <wildcard-expression>
<string[]> -notlike <wildcard-expression>
<string[]> -match <regular-expression>
<string[]> -notmatch <regular-expression>
When the input of these operators is a scalar value, they return a Boolean value. When the input is a collection of values, the operators return any matching members. If there are no matches in a collection, the operators return an empty array.
-like and -notlike
-like
and -notlike
behave similarly to -eq
and -ne
, but the right-hand
side could be a string containing wildcards.
Example:
"PowerShell" -like "*shell" # Output: True
"PowerShell" -notlike "*shell" # Output: False
"PowerShell" -like "Power?hell" # Output: True
"PowerShell" -notlike "Power?hell" # Output: False
"PowerShell" -like "Power[p-w]hell" # Output: True
"PowerShell" -notlike "Power[p-w]hell" # Output: False
"PowerShell", "Server" -like "*shell" # Output: PowerShell
"PowerShell", "Server" -notlike "*shell" # Output: Server
-match and -notmatch
-match
and -notmatch
use regular expressions to search for pattern in the
left-hand side values. Regular expressions can match complex patterns like
email addresses, UNC paths, or formatted phone numbers. The right-hand side
string must adhere to the regular expressions
rules.
Scalar examples:
# Partial match test, showing how differently -match and -like behave
"PowerShell" -match 'shell' # Output: True
"PowerShell" -like 'shell' # Output: False
# Regex syntax test
"PowerShell" -match '^Power\w+' # Output: True
'bag' -notmatch 'b[iou]g' # Output: True
If the input is a collection, the operators return the matching members of that
collection and the $Matches
automatic variable is $null
.
Collection examples:
"PowerShell", "Super PowerShell", "Power's hell" -match '^Power\w+'
# Output: PowerShell
"Rhell", "Chell", "Mel", "Smell", "Shell" -match "hell"
# Output: Rhell, Chell, Shell
"Bag", "Beg", "Big", "Bog", "Bug" -match 'b[iou]g'
#Output: Big, Bog, Bug
"Bag", "Beg", "Big", "Bog", "Bug" -notmatch 'b[iou]g'
#Output: Bag, Beg
-match
and -notmatch
support regex capture groups. Each time they run, they
overwrite the $Matches
automatic variable. When <input>
is a collection the
$Matches
variable is $null
. $Matches
is a Hashtable that always has a
key named '0', which stores the entire match. If the regular expression
contains capture groups, the $Matches
contains additional keys for each
group.
Example:
$string = 'The last logged on user was CONTOSO\jsmith'
$string -match 'was (?<domain>.+)\\(?<user>.+)'
$Matches
Write-Output "`nDomain name:"
$Matches.domain
Write-Output "`nUser name:"
$Matches.user
True
Name Value
---- -----
domain CONTOSO
user jsmith
0 was CONTOSO\jsmith
Domain name:
CONTOSO
User name:
jsmith
For details, see about_Regular_Expressions.
Replacement operator
Replacement with regular expressions
Like -match
, the -replace
operator uses regular expressions to find the
specified pattern. But unlike -match
, it replaces the matches with another
specified value.
Syntax:
<input> -replace <regular-expression>, <substitute>
The operator replaces all or part of a value with the specified value using
regular expressions. You can use the operator for many administrative tasks,
such as renaming files. For example, the following command changes the file
name extensions of all .txt
files to .log
:
Get-ChildItem *.txt | Rename-Item -NewName { $_.name -replace '\.txt$','.log' }
By default, the -replace
operator is case-insensitive. To make it case
sensitive, use -creplace
. To make it explicitly case-insensitive, use
-ireplace
.
Examples:
"book" -ireplace "B", "C" # Case insensitive
"book" -creplace "B", "C" # Case-sensitive; hence, nothing to replace
Cook
book
Regular expressions substitutions
It is also possible to use regular expressions to dynamically replace text
using capturing groups, and substitutions. Capture groups can be referenced in
the <substitute>
string using the dollar sign ($
) character before the
group identifier.
In the following example, the -replace
operator accepts a username in the form
of DomainName\Username
and converts to the Username@DomainName
format:
$SearchExp = '^(?<DomainName>[\w-.]+)\\(?<Username>[\w-.]+)$'
$ReplaceExp = '${Username}@${DomainName}'
'Contoso.local\John.Doe' -replace $SearchExp,$ReplaceExp
[email protected]
Warning
The $
character has syntatic roles in both PowerShell and regular
expressions:
- In PowerShell, between double quotation marks, it designates variables and acts as a subexpression operator.
- In Regex search strings, it denotes end of the line
- In Regex substitution strings, it denotes captured groups.Be sure
to either put your regular expressions between single quotation marks or
insert a backtick (
`
) character before them.
For example:
$1 = 'Goodbye'
'Hello World' -replace '(\w+) \w+', "$1 Universe"
# Output: Goodbye Universe
'Hello World' -replace '(\w+) \w+', '$1 Universe'
# Output: Hello Universe
$$
in Regex denotes a literal $
. This $$
in the substitution string to
include a literal $
in the resulting replacement. For example:
'5.72' -replace '(.+)', '$ $1' # Output: $ 5.72
'5.72' -replace '(.+)', '$$$1' # Output: $5.72
'5.72' -replace '(.+)', '$$1' # Output: $1
To learn more, see about_Regular_Expressions and Substitutions in Regular Expressions.
Substituting in a collection
When the <input>
to the -replace
operator is a collection, PowerShell
applies the replacement to every value in the collection. For example:
"B1","B2","B3","B4","B5" -replace "B", 'a'
a1
a2
a3
a4
a5
Replacement with a script block
In PowerShell 6 and later, the -replace
operator also accepts a script block
that performs the replacement. The script block runs once for every match.
Syntax:
<String> -replace <regular-expression>, {<Script-block>}
Within the script block, use the $_
automatic variable to access the input
text being replaced and other useful information. This variable's class type is
System.Text.RegularExpressions.Match.
The following example replaces each sequence of three digits with the character equivalents. The script block runs for each set of three digits that needs to be replaced.
"072101108108111" -replace "\d{3}", {return [char][int]$_.Value}
Hello
Containment operators
The containment operators (-contains
, -notcontains
, -in
, and -notin
) are
similar to the equality operators, except that they always return a Boolean
value, even when the input is a collection. These operators stop comparing as
soon as they detect the first match, whereas the equality operators evaluate all
input members. In a very large collection, these operators return quicker than
the equality operators.
Syntax:
<Collection> -contains <Test-object>
<Collection> -notcontains <Test-object>
<Test-object> -in <Collection>
<Test-object> -notin <Collection>
-contains and -notcontains
These operators tell whether a set includes a certain element. -contains
returns True when the right-hand side (test object) matches one of the elements
in the set. -notcontains
returns False instead. When the test object is a
collection, these operators use reference equality, i.e. they check whether one
of the set's elements is the same instance of the test object.
Examples:
"abc", "def" -contains "def" # Output: True
"abc", "def" -notcontains "def" # Output: False
"Windows", "PowerShell" -contains "Shell" # Output: False
"Windows", "PowerShell" -notcontains "Shell" # Output: True
"abc", "def", "ghi" -contains "abc", "def" # Output: False
"abc", "def", "ghi" -notcontains "abc", "def" # Output: True
More complex examples:
$DomainServers = "ContosoDC1","ContosoDC2","ContosoFileServer","ContosoDNS",
"ContosoDHCP","ContosoWSUS"
$thisComputer = "ContosoDC2"
$DomainServers -contains $thisComputer
# Output: True
$a = "abc", "def"
"abc", "def", "ghi" -contains $a # Output: False
$a, "ghi" -contains $a # Output: True
-in and -notin
The -in
and -notin
operators were introduced in PowerShell 3 as the
syntactic reverse of the of contains
and -notcontain
operators. -in
returns True when the left-hand side <test-object>
matches one of the
elements in the set. -notin
returns False instead. When the test object
is a set, these operators use reference equality to check whether one of the
set's elements is the same instance of the test object.
The following examples do the same thing that the examples for -contain
and -notcontain
do, but they are written with -in
and -notin
instead.
"def" -in "abc", "def" # Output: True
"def" -notin "abc", "def" # Output: False
"Shell" -in "Windows", "PowerShell" # Output: False
"Shell" -notin "Windows", "PowerShell" # Output: True
"abc", "def" -in "abc", "def", "ghi" # Output: False
"abc", "def" -notin "abc", "def", "ghi" # Output: True
More complex examples:
$DomainServers = "ContosoDC1","ContosoDC2","ContosoFileServer","ContosoDNS",
"ContosoDHCP","ContosoWSUS"
$thisComputer = "ContosoDC2"
$thisComputer -in $DomainServers
# Output: True
$a = "abc", "def"
$a -in "abc", "def", "ghi" # Output: False
$a -in $a, "ghi" # Output: True
Type comparison
The type comparison operators (-is
and -isnot
) are used to determine if an
object is a specific type.
Syntax:
<object> -is <type-reference>
<object> -isnot <type-reference>
Example:
$a = 1
$b = "1"
$a -is [int] # Output: True
$a -is $b.GetType() # Output: False
$b -isnot [int] # Output: True
$a -isnot $b.GetType() # Output: True
SEE ALSO
Is this page helpful?
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK