Windows PowerShell
Operators
PowerShell is
designed to be an interactive command-line shell, but it's also a programming
language. As you advance in your PowerShell understanding and knowledge, it's
inevitable you're going to run into a number of core computer programming
concepts. Operators are one of these core programming concepts, and you've
probably already been using them without necessarily knowing everything about
them.
The term operator refers
to one or more characters in a command or expression that PowerShell interprets
in a specific way. For example, the addition operator is the + character, and
PowerShell interprets the + character to mean addition. Operators depend on
context. For example, the + character doesn't behave as the addition operator
inside a quoted string. Also, not all operators are a single character (like
+); some are multiple characters (such as -eq, -or, and -not).
PowerShell
operators fall into a number of different categories. For example, arithmetic
operators perform operations primarily on numbers, but they also affect strings
and other data types. Along with the basic assignment, math, comparison, and
logical operators, PowerShell has a number of operators that save time and
coding effort (such as -like, -match, -replace, -contains, -split, and -join).
Let's take a look at the different categories of operators and how to use them
in PowerShell.
The Arithmetic
Operators
The arithmetic
operators consist of the following characters: + (add), - (subtract), *
(multiply), / (divide), and % (modulus, or division remainder). These operators
behave exactly as expected when using numbers. This means you can use
PowerShell as a simple calculator by typing expressions at the PowerShell
prompt. Figure 1 shows some simple examples.
PowerShell
evaluates arithmetic expressions from left to right and according to the normal
order of operations (multiplication, division, addition, then subtraction),
unless you use parentheses for grouping. PowerShell ignores the spaces between
the operators, so you can use spaces in your arithmetic expressions if it makes
things clearer.
Besides working
with numbers, the + and * operators work with strings, as shown in Figure 1.
When you use the + operator, it concatenates strings. When you use the *operator,
it repeats a string.
The Assignment
Operators
The assignment
operators assign values to variables or object properties. The most common
assignment operator is =, which sets a variable or object property to a value.
There are some other assignment operators as well: +=, -=, *=, /=, %=, ++, and
--. These other assignment operators modify the value before assigning it. The
commands in Figure 2 demonstrate some of the assignment operators.
The Comparison
Operators
The comparison
operators compare values in PowerShell. There are four kinds of comparison
operators: equality, match, containment, and replace. Let's take a look at each
of these.
Equality operators. The equality
operators are equal (-eq), not equal (-ne), greater than (-gt), greater than or
equal (-ge), less than (-lt), and less than or equal (-le). PowerShell doesn't
use an equals sign (=) to test equality because it's used for the assignment
operator. Similarly, PowerShell doesn't use the greater than (>) or less
than (<) characters because they're used for output and input redirection,
respectively.
All the equality
operators return a Boolean value ($true or $false) that indicates the result of
the comparison. For example, the expression
$var -eq 5
returns $true if
$var contains 5 or $false otherwise.
Match operators. The match
operators are -like, -notlike, -match, and -notmatch. These operators perform
pattern matching. The -like and -notlike operators use wildcards characters (?
and *), whereas the -match and -notmatch operators use regular expressions.
These operators return a Boolean value ($true or $false), depending on whether
the expression on the left side of the operator matches (or doesn't match) the
expression on the right side of the operator. Figure 3 shows the match
operators in action.
Containment
operators. There are two containment operators: -contains and
-notcontains. These operators return a Boolean value ($true or $false)
depending on whether the value on the right side of the operator exists (or
doesn't exist) in the set of values on the left side of the operator. These
operators provide a convenient way to see if a value exists in an array. For
example, the expression
"A","B","C"
-contains $str
returns $true if
$str contains the character A, B, or C (case insensitive). If the expression on
the left side is a single value (rather than an array), the -contains and
-notcontains operators work the same way as the -eq and -ne operators,
respectively.
Replace operator. The -replace
operator replaces a pattern in an input value using a regular expression. This
operator uses two arguments (separated by a comma): a regular expression
pattern and its replacement value. For example, the expression
"The rain in Seattle" -replace
"rain","hail"
returns the string
"The hail in Seattle". As noted, the -replace operator also works
with regular expressions, so the PowerShell expression
"kenmyer@contoso.com" -replace
'^[\w]+@(.+)', '$1'
returns the string
"contoso.com". If you're unfamiliar with regular expressions, the
PowerShell Help topic about_Regular_Expressions provides a
good introduction.
By default, all the
PowerShell comparison operators (as well as the split operator, which I'll
describe in a moment) are case insensitive. If you want a case-sensitive
version of the operator, prefix it with the letter c. For example,
-ceq is the case-sensitive version of -eq, -creplace is the case-sensitive
version of -replace, and -csplit is the case-sensitive version of -split.
Technically, PowerShell also supports using the prefix i to
specify case-insensitive operators (e.g., -ieq, -ireplace, and -isplit), but
this prefix is rarely used because these operators are case insensitive by
default.
The Split and Join
Operators
The -split operator
splits a string into an array of substrings. The -join operator is its
inverse—it joins an array of strings into a single string. The -split and -join
operators make converting a string into an array (or vice versa) a snap. Both
operators let you specify one or more delimiter characters that define how
PowerShell should split or join the string. Figure 4 shows some examples of how
you can use these operators.
The Logical
Operators
You can use the
logical operators to connect expressions or statements together to form a
single expression. These operators are -and, -or, -xor, -not, and ! (! is the
same as -not). Just as with the arithmetic operators, you can use parentheses
in your expressions to coerce PowerShell to evaluate them in the order you
want. These operators work like you would expect in other programming
languages. For example, the expression
($var + 3 -eq 6) -or ($var - 3 -eq 0)
returns $true if
$var contains 3.
PowerShell stops
evaluating the expressions on either side of a logical operator once it gets a
$true result. This is sometimes called short-circuit evaluation.
The Test-Truth.ps1 script in Listing 1 demonstrates how PowerShell uses
short-circuit evaluation.
Listing 1: Test-Truth.ps1
function AddOne($number) {
$number++
write-host "AddOne: $number"
$number # Output result
}
function SubtractOne($number) {
$number--
write-host "SubtractOne: $number"
$number # Output result
}
$number = 1
write-host "Short-circuit evaluation:"
# Example of short-circuit evaluation: The expression
# on the left side of the -or operator is $true, so
# PowerShell doesn't need to evaluate the expression
# on the right side of the -or operator.
(AddOne $number) -eq 2 -or (SubtractOne $number) -eq 0
# Outputs "AddOne: 2" and "True", but doesn't output
# "SubtractOne: 0".
write-host
# PowerShell must evaluate the expressions on both sides
# of the -and operator to determine whether the entire
# expression is $true or $false.
(AddOne $number) -eq 2 -and (SubtractOne $number) -eq 0
# Outputs "AddOne: 2", "SubtractOne: 0", and "True".
$number++
write-host "AddOne: $number"
$number # Output result
}
function SubtractOne($number) {
$number--
write-host "SubtractOne: $number"
$number # Output result
}
$number = 1
write-host "Short-circuit evaluation:"
# Example of short-circuit evaluation: The expression
# on the left side of the -or operator is $true, so
# PowerShell doesn't need to evaluate the expression
# on the right side of the -or operator.
(AddOne $number) -eq 2 -or (SubtractOne $number) -eq 0
# Outputs "AddOne: 2" and "True", but doesn't output
# "SubtractOne: 0".
write-host
# PowerShell must evaluate the expressions on both sides
# of the -and operator to determine whether the entire
# expression is $true or $false.
(AddOne $number) -eq 2 -and (SubtractOne $number) -eq 0
# Outputs "AddOne: 2", "SubtractOne: 0", and "True".
In the script, the
AddOne and SubtractOne functions both use the Write-Host cmdlet. Based on the
script's output, you can clearly see when PowerShell calls (and doesn't call)
the functions.
The Type Operators
The type operators
are -is and -isnot. These operators test whether the value on the left side of
the operator is (or isn't) a specific Microsoft .NET type. For example, the
expression
3 -is [Int]
returns $true,
whereas the expression
"fabrikam" -isnot [String]
returns $false.
The Redirection
Operators
The redirection
operators are listed in Table 1. As you can see, many new redirection operators
were introduced in PowerShell 3.0. At this time, PowerShell supports only
output redirection, but it might support input redirection in a future version.
Table
1: PowerShell Redirection Operators
|
||
Operator
|
Description
|
Available
In
|
>
|
Redirects standard (non-error)
output to a file
|
All PowerShell versions
|
>>
|
Redirects output and appends it to
a file
|
All PowerShell versions
|
2>
|
Redirects error output to a file
|
All PowerShell versions
|
2>>
|
Redirects error output and appends
it to a file
|
All PowerShell versions
|
2>&1
|
Redirects error output to the same
location as standard output
|
All PowerShell versions
|
3>
|
Redirects warning output to a file
|
PowerShell 3.0 and later
|
3>>
|
Redirects warning output and
appends it to a file
|
PowerShell 3.0 and later
|
4>
|
Redirects verbose output to a file
|
PowerShell 3.0 and later
|
4>>
|
Redirects verbose output and
appends it to a file
|
PowerShell 3.0 and later
|
5>
|
Redirects debug output to a file
|
PowerShell 3.0 and later
|
5>>
|
Redirects debug output and appends
it to a file
|
PowerShell 3.0 and later
|
n>&1
|
Redirects warning (n =
3), verbose (n = 4), or debug (n = 5) output to the
same location as standard output
|
PowerShell 3.0 and later
|
*>
|
Redirects all output streams
(standard, errorwarning, verbose, and debug) to a file
|
PowerShell 3.0 and later
|
*>>
|
Redirects all output streams and
appends them to a file
|
PowerShell 3.0 and later
|
The redirection
operators are easy to use. For example, if you want to redirect the
Get-ChildItem cmdlet's output to the file Output.txt, you'd run the command:
Get-ChildItem C:\,nofile > Output.txt
2>&1
The Output.txt file
will also contain error messages.
When using
redirection operators, it's important to remember that PowerShell writes to the
output file using Unicode text. If you don't want Unicode output, you can use
the Out-File cmdlet instead of the > or >> operators.
The Special
Operators
PowerShell's
special operators are a collection of operators that don't fall into other
categories. There are nine special operators:
The
invocation (&) operator. The & operator
runs a command, script, or script block. (PowerShell's documentation also
refers to it as the call operator.) This operator tells PowerShell
that the expression that follows is something it should run.
When using
PowerShell interactively, you need to use the & operator to run a program
that contains spaces in its name or path. For example, if you use the command
"C:\Program Files (x86)\Test
App\MyApp.exe"
PowerShell doesn't
start the program MyApp.exe. It just displays the string onscreen. If you want
to run MyApp.exe as a program, you need to place the & operator before the
string:
& "C:\Program Files (x86)\Test
App\MyApp.exe"
The property
dereference (.) operator. You use the property
dereference operator to indicate that the expression on the left side of the
dot character is an object and the expression on the right side is an object
member (a property or method). For example, $file.Name refers to the Name
property of the object in the $file variable.
The dot
sourcing (.) operator. You can also use the dot
character to run a script in the current scope. Normally when you run a script,
PowerShell creates a new scope for the script—that is, the variables and
functions the script creates are discarded when the script terminates. If you
don't want PowerShell to create a new scope when you run a script, you need to
prefix the script with the dot sourcing operator. For example, suppose you have
a list of useful functions in the script file MyFunctions.ps1. You can use the
dot sourcing operator to load the scripts:
. MyFunctions.ps1
The functions
defined in MyFunctions.ps1 will now be available after the script terminates.
The static member
(::) operator. To access a static member of a .NET class, you can use the
static member operator. A class is a type of object, and a static member is a
property or method of a class. For example, the expression
[DateTime]::Now
refers to the Now
static property of the DateTime .NET class.
The range (..)
operator. The range operator returns an array of integers
represented by the lower and upper bounds of the integers on either side of the
two consecutive dots. For example, the expression 1..3 outputs a three-element
array (1, 2, 3), and the expression 9..6 outputs a four-element array (9, 8, 7,
6).
The
format (-f) operator. The -f operator formats a
string based on .NET string formatting rules. The input string (i.e., the
string on the left side of the -f operator) should include substrings
containing curly braces and an expression index, as in {0:N2}. The -f operator
accepts an array on its right side, so the first number after the opening curly
brace in the substring tells PowerShell which array element to format (0 for
the first element, 1 for the second, and so forth). For example, the expression
"{0:N1} and {1:N2}" -f
(100/3),(76/3)
returns the string
"33.3 and 25.33". That is, the first expression (index 0) after -f
(100/3) will be formatted with formatting code N1 (one decimal place), and the
second expression (index 1) after -f (76/3) will be formatted with formatting
code N2 (two decimal places). For information about the formatting codes, see
MSDN's Formatting Types web page.
The subexpression
operator. The $( ) operator causes PowerShell to evaluate the
expression in between the $( and the ) characters.
This operator is helpful when you want to force PowerShell to evaluate an
expression inside a quoted string, such as when you want to get an object's
property. For example, suppose you have a variable $myString that contains the
string "KenDyer". The expression
"$myString is $myString.Length characters
long"
will output
"KenDyer is KenDyer.Length characters long", which is probably not
what you intended. To solve this, you can use the $( ) operator to get the
desired result. In this example, the expression
"$myString is $($myString.Length)
characters long"
will output the
result you were probably expecting ("KenDyer is 7 characters long").
The array
subexpression operator. The @( ) operator is useful when you have some data
(such as an object property or the output of a function or method) that might
be empty, a single value, or an array. For example, an Active Directory (AD)
group might have no members, a single member, or multiple members. The
subexpression operator coerces the data into an array to make processing
easier. To demonstrate, I created the Test-Array.ps1 script in Listing 2.
Listing 2: Test-Array.ps1
# Returns nothing
function Null {
}
# Returns a single item
function SingleItem {
"A"
}
# Returns multiple items
function MultipleItems {
"A","B","C"
}
$testVar = @(Null)
$numElements = $testVar.Count
"Number of elements: $numElements"
# Outputs "Number of elements: 0"
$testVar = @(SingleItem)
$numElements = $testVar.Count
"Number of elements: $numElements"
# Outputs "Number of elements: 1"
$testVar = @(MultipleItems)
$numElements = $testVar.Count
"Number of elements: $numElements"
# Outputs "Number of elements: 3"
function Null {
}
# Returns a single item
function SingleItem {
"A"
}
# Returns multiple items
function MultipleItems {
"A","B","C"
}
$testVar = @(Null)
$numElements = $testVar.Count
"Number of elements: $numElements"
# Outputs "Number of elements: 0"
$testVar = @(SingleItem)
$numElements = $testVar.Count
"Number of elements: $numElements"
# Outputs "Number of elements: 1"
$testVar = @(MultipleItems)
$numElements = $testVar.Count
"Number of elements: $numElements"
# Outputs "Number of elements: 3"
This script
contains three functions: Null (which returns nothing), SingleItem (which
returns a single item), and MultipleItems (which returns multiple items). When
the script calls each function, it uses @( ) around each function call to
ensure that the $testVar variable contains an array, no matter how many items
are returned from the function. If the script didn't use @( ) when calling the
functions, it wouldn't work as expected because the Count property would be
different based on the objects returned from the functions. For example,
SingleItem returns a single string; strings don't have a Count property, so the
$numElements variable would be $null. Using @( ) helps the script maintain
consistency, regardless of the number of elements returned from any of the
functions.
The comma (,)
operator. If you place the comma operator before a single value, you
can create a one-element array. For example, the expression
$items = ,"A"
assigns a
one-element array to the variable $items. You can also place the comma operator
between items in a list to create a multiple-element array. For example, the
expression
$items =
"A","B","C"
assigns a
three-element array to the variable $items.
Know Your Operators
As you can see,
PowerShell has a long list of operators. The PowerShell Help topics, starting
with about_Operators, does a good job of introducing the different
categories of operators and providing examples. A good understanding of
PowerShell's operators is a must if you want to increase your understanding of
PowerShell and the efficiency of your code.
No comments:
Post a Comment