Operators - PowerShell fundamentals - PowerShell in Depth, Second Edition (2015)

PowerShell in Depth, Second Edition (2015)

Part 1. PowerShell fundamentals

Chapter 6. Operators

This chapter covers

· Logical and comparison operators

· Bitwise operators

· Arithmetic operators

· Type operators

· Other special operators

In any computer language, operators provide a means of comparing and manipulating pieces of data. PowerShell’s no exception, offering a wide variety of operators for different tasks.

Powershell supplies a number of help files on the various operators. We recommend that you read them in conjunction with this chapter. The help files contain numerous examples that will aid your understanding. The following help files are available:

· about_Operators

· about_Arithmetic_Operators

· about_Assignment_Operators

· about_Comparison_Operators

· about_Logical_Operators

· about_Operator_Precedence

· about_Type_Operators

All of these operators have a common syntactical form. Practically all PowerShell operators start with a dash or a hyphen, followed by the operator name. You’ll see plenty of examples of this in the following sections and throughout the rest of the book. If you have prior experience with other scripting or programming languages, PowerShell’s operators can seem confusing or odd at first, but you’ll get used to them as you work with them.

6.1. Logical and comparison operators

Comparison operators are designed to take two pieces of data and compare them. They always return either True or False, known as Boolean values, based on whether or not the comparison was true.

Note

PowerShell has built-in variables ($True and $False) that represent the Boolean values True and False. Variables are covered in detail in chapter 16.

There are some cases where you may get an answer that isn’t a Boolean value:

PS C:\> $a = 1,2,3

PS C:\> $a -eq 1

1

In reality, you’re performing a comparison that doesn’t make sense in that you’re trying to compare an array of values to a single value. The correct comparison would be:

PS C:\> $a -contains 1

True

Or possibly:

PS C:\> $a[0] -eq 1

True

Table 6.1 shows the primary comparison operators in PowerShell. In the middle column, we’ve included the more common equivalent from other languages to allow you to match up operators with whatever prior experience you may have.

Table 6.1. PowerShell’s comparison operators

Operator

Other languages

Purpose

-eq

= or ==

Equal to

-ne

<> or !=

Not equal to

-gt

>

Greater than

-lt

<

Less than

-le

<=

Less than or equal to

-ge

>=

Greater than or equal to

-like, -notlike

n/a

Wildcard string comparison

Note

Another comparison operator set, -match, -cmatch, -notmatch, and -cnotmatch, is used with regular expressions. Because it’s a big topic, we’re devoting an entire chapter to it (chapter 13). The PowerShell help file called about_comparison_operators also discusses –contains, -notcontains, and -replace. These, together with the bitwise operators, are the subject of later sections in this chapter.

All string comparisons are case insensitive by default. The following example would return True (try running it in the shell to prove it):

"HELLO" –eq "hello"

There may be times when you explicitly need to perform a case-sensitive string comparison, and PowerShell offers a set of alternate, case-sensitive operators for those times. Add a “c” after the dash in the operator: -ceq, -cne, and so forth. For example

PS C:\> "Hello" -ceq "hello"

False

Note

It’s also possible to use an “i” to force a case-insensitive comparison, for example, –ieq, -ine, and so on. It may seem odd to have these available when PowerShell is case-insensitive by default, but consider the situation where you have multiple comparisons to perform and some have to be case-sensitive and some case-insensitive. It’d be useful to be able to easily differentiate the type of comparison.

Be careful with the way you build your comparison. These all return the same result:

"Hello" -eq "hello"

"Hello" -ieq "hello"

"Hello" -cne "hello"

We recommend that you always use the simplest possible operator to aid debugging and working with the code in the future.

The size operators, -gt, -ge, -lt, and -le, are self-explanatory when used with numerical data:

PS C:\> 10 -gt 9

True

They really come into their own when you’re using branching constructs, as explained in chapter 19. You may come across this apparent oddity:

PS C:\> 9 -gt "10"

False

PS C:\> 9 -lt "10"

True

PowerShell is converting the string to an integer so that it can perform the comparison. Any conversion activity involves the value on the right-hand side; that value is converted to the same type as the value on the left-hand side.

The –like operator, along with the case-sensitive –clike operator (case-insensitive versions exist as well), permits you to use ? and * as wildcards. For example, the following would return True:

"PowerShell" –like "*sh*"

You’ll also find the –notlike and –cnotlike operators, which reverse the normal logic. This would return False:

"PowerShell" –notlike "*sh*"

You can type any of these examples directly into the PowerShell console, press Enter, and see the result. It offers an easy way to test different comparisons before using them in a longer command or script.

6.1.1. The –contains operator

We want to call special attention to this operator because it’s often confused for –like. For example, you’ll see folks try the following example, which won’t work:

"PowerShell" –contains "*sh*"

The previous comparison will work fine if you use the –like operator, because its job is to compare strings using a wildcard comparison. But –contains is different. It’s designed to look inside a collection of objects and see if that collection contains another object. For example, you could create a collection containing three strings and then test to see if the collection contains a fourth string:

$collection = "one","two","three"

$collection –contains "one"

That comparison would return True. The –contains operator is easy to understand with simple objects like strings or numbers. But with more complicated objects it becomes less straightforward. For example, consider the following:

PS C:\> $collection = Get-Process

PS C:\> $process = Get-Process | select -first 1

PS C:\> $collection -contains $process

False

Wait, False? What’s going on?

You started by getting all processes on the system and placing them into the $collection variable. Next, you retrieved the first running process and put it into the variable, $process. Surely $collection contains $process, right?

Note

If you’re curious about variables, we devoted an entire chapter to them (chapter 16). For now, think of them as storage boxes that contain things—in this case, processes.

Well, sort of. On our system, the first running process was Conhost, and $collection definitely contains Conhost. The problem is in the way –contains works. When it looks for a match, it tries to match every single property of the object. In addition to looking at the name Conhost, it’ll look at the other 65 properties of a process object. Some of those properties—such as memory and CPU consumption—are constantly changing. In the short span of time between filling $collection and then filling $process, some properties of that Conhost process changed. That means the snapshot of Conhost in $collection is slightly different from the snapshot in $process; therefore, the –contains operator doesn’t believe they’re the same, and it returns False.

You can show that –contains does work by trying the following:

PS C:\> $collection = Get-Process

PS C:\> $process = $collection | select -First 1

PS C:\> $collection -contains $process

True

In the previous example, the $process variable is populated by selecting the first member of the collection. The collection has to contain the first member to return a result of True. As long as you understand that –contains compares every property when dealing with objects, you’re fine.

Note

You’ll also find –notcontains, which is the logical opposite of –contains.

6.1.2. The -in and -notin operators

Related to –contains is an operator introduced in PowerShell v3 called –in, which also has an inverse, -notin. You can use this operator to test whether a value is part of a collection of values. This operator always returns a Boolean value:

PS C:\> "Bruce" -notin "Don","Jeff","Richard"

True

PS C:\> "Bruce" -in "Don","Jeff","Richard"

False

The only difference between the previous and the –contains lies in the order. With -contains you’re testing if an array contains something:

PS C:\> "Don","Jeff","Richard" -contains "don"

True

With –in you’re testing whether a value is in an array. This is a subtle distinction. In practical terms no real differences exist between the two operators. The choice of which to use may come down to how you like to read code. For example, consider the following:

$names = Get-Process | select -ExpandProperty Name

If ($names -contains "calc"){

Stop-Process -Name "calc" -WhatIf

}

if ("notepad" -in $names) {

Stop-Process -Name "notepad" -WhatIf

}

As you can see, you get a list of process names and then test whether a particular process name is in the list. Using –in reads a little more simply, but both if statements do the same job. If you’re using the simplified syntax for Where-Object (see chapter 7) you need to use –in rather than–contains; that’s why it was invented.

6.1.3. Boolean, or logical, operators

The comparison operators we’ve discussed accept only two values. They compare them and return either True or False. But what if you need to compare more than one thing? That’s where Boolean, or logical, operators come into play.

Generally speaking, these operators are designed to take two subcomparisons, or subexpressions, which each produce a True or a False. The Boolean operators then take both True/False results and compare them, returning a True or a False for the entire expression. Typically, you limit the number of subexpressions to two, but you can have as many as you want, each separated by an operator.

Note

On a practical basis, the more logical operators and subexpressions you put into the comparison, the more difficult it becomes to understand and debug. Think carefully about what you’re doing if you find yourself building huge comparison strings. Usually, you can find a better way to accomplish the same thing.

Table 6.2 lists these Boolean operators.

Table 6.2. PowerShell’s Boolean operators

Operator

Purpose

-and

Return True if all subexpressions are True.

-or

Return True if any subexpression is True.

-not or !

Return the opposite: True becomes False, and False becomes True.

-xor

Return True if one subexpression is True, but not if both are True.

Let’s look at some examples. Note that we’ve used parentheses to group the subexpressions. You don’t necessarily need to do that in comparisons that are this simple, but we think it makes them easier to read (and debug):

PS C:\> (5 -gt 100) -and (5 -eq 5)

False

PS C:\> (5 -gt 100) -or (5 -eq 5)

True

PS C:\> (500 -gt 100) -and (5 -eq 5)

True

PS C:\> (500 -gt 100) -or (5 -eq 5)

True

PS C:\> (500 -gt 100) -xor (5 -eq 5)

False

You can make these comparisons as complex as you wish. Again, we find that using parentheses to contain each subexpression makes complex, multipart comparisons easier for your brain to digest and to edit when you revisit the code six months later. Keep in mind that PowerShell, like algebra, processes from the innermost parenthetical expression and works outward. The following is an example of a complex expression:

PS C:\> (((500 -gt 100) -or (1 -eq 2) -and 5 -eq 5) -and (10 -eq 10))

True

Did you get all that? It’s easier, sometimes, to break it down as PowerShell would. Start with the innermost parentheses and evaluate their expressions, and then work your way outward:

· (((500 -gt 100) -or (1 -eq 2) -and 5 -eq 5) -and (10 -eq 10))

· ((True -or False -and 5 -eq 5) -and True)

· ((True -or False -and True) -and True)

· ((True -and True) -and True)

· (True -and True)

· True

But letting PowerShell do the work is a lot faster.

6.1.4. Bitwise operators

Technically, these operators are comparison operators, but the way in which they perform their comparison requires a little explanation.

First, keep in mind that you can render any integer number in binary. For example, 18 in binary is 00010010. A bitwise operator takes two binary numbers and compares each digit, or bit, one at a time. The result is the total number of bits that passed the comparison. Table 6.3 shows the operators.

Table 6.3. PowerShell’s bitwise operators

Operator

Purpose

-band

Return 1 if both compared bits are 1

-bor

Return 1 if either compared bit is 1

-bxor

Return 1 if one compared bit is 1, but not if both are 1

Keep in mind that this comparison is executed on each bit, one at a time. Table 6.4 shows an example comparison.

Table 6.4. Example bitwise comparison using -band

Number

Binary

129

1

0

0

0

0

0

0

1

19

0

0

0

1

0

0

1

1

-band (1)

0

0

0

0

0

0

0

1

Note

When dealing with a binary, the least significant (first) bit is on the right-hand side.

In table 6.4, you ran 129 –band 19. PowerShell converted both 129 and 19 to binary, and those bits are shown in the table. The first bit, with a value of 1, was present in both 129 and 19. No other bits were present in both, so the final result is the first bit turned on, with a value of 1. Now look at table 6.5, which shows the same two numbers being compared with –bxor: 129 –bxor 19.

Table 6.5. Example bitwise comparison using -bxor

Number

Binary

129

1

0

0

0

0

0

0

1

19

0

0

0

1

0

0

1

1

-bxor (146)

1

0

0

1

0

0

1

0

In table 6.5, the second, fifth, and eighth bits return 1, because those bits were set to 1 in one, but not both, of the two numbers being compared. The individual values of those bits are 2, 16, and 128, respectively. The result is 128 + 16 + 2 = 146.

Table 6.6 presents the use of –bor for completeness. In this case the resultant bit is a 1 if either of the numbers being operated on contains a 1 at that location. The result is 128 + 16 + 2 + 1 = 147.

Table 6.6. Example bitwise comparison using -bor

Number

Binary

129

1

0

0

0

0

0

0

1

19

0

0

0

1

0

0

1

1

-bor (147)

1

0

0

1

0

0

1

1

In practice, bitwise operators are generally used to test whether a certain bit is set or to set a specific bit. For example, some directory services store certain attributes as bitmasks, where each bit has a specific meaning. The first bit, for example, might indicate whether an account is locked out, and the second bit would indicate if a password is due to be changed. If you loaded that entire bit mask attribute into a variable named $flag, you’d test to see if the account was locked out by running $flag –band 1. If you got 1 as your result, then you’d know bit 1 is set in $flag. Similarly, to set bit 1 you’d run $flag –bor 1. The result would include bit 1 being set, with the other 7 bits in $flag left as they were. The following listing offers a slightly more practical example.

Listing 6.1. Comparing bitwise values

Listing 6.1 connects to a remote machine and gets all of the local user accounts. The userflags property is a bitmask value.

Note

In listing 6.1 the value 0x10000 given for the variable is expressed in hexadecimal (base 16). Its decimal value is 65536.

If you perform a binary and a (-band), you can determine whether an account has been set with a nonexpiring password:

Username PasswordNeverExpires Computername

-------- -------------------- ------------

Administrator True QUARK

Guest True QUARK

Jeff True QUARK

Lucky False QUARK

Okay, we’ll admit that the previous example is esoteric stuff. But it’s handy in the right situation.

6.2. Arithmetic operators

PowerShell supports the standard arithmetic operators, shown in table 6.7.

Table 6.7. PowerShell’s arithmetic operators

Operator

Purpose

+

Addition or string concatenation

-

Subtraction

/

Division

*

Multiplication (numeric or string)

%

Modulo (remainder)

++

Unary addition (increment)

--

Unary subtraction (decrement)

+=, -+, /=, *=

Shortcuts

The unary operators come from classic C syntax: $var++ means “add 1 to whatever is in $var, and put the result in $var.” The shortcut operators have a similar origin. For example, $var += 7 means “add 7 to whatever is in $var, and put the result in $var.” The equivalent—and also legal in PowerShell—syntax would be $var = $var + 7.

The + operator does double duty for both the concatenation of strings and the addition of numbers. Generally, PowerShell will look at the type of the first operand to decide what to do:

PS C:\> $string = "5"

PS C:\> $number = 5

PS C:\> $string + $number

55

PS C:\> $number + $string

10

When it’s able to convert (or coerce) one type into another to make the operation make sense, it’ll do so. In our first example, the number was treated as a string. In the second example, the string—because it was the second operand that time—was coerced into an integer.

The multiplication operator works exactly as you’d expect with numeric data:

PS C:\> 17*3

51

What you might not expect is the ability to multiply strings:

PS C:\> "PowerShell rocks " * 3

PowerShell rocks PowerShell rocks PowerShell rocks

When you multiply a string you get a new string with the original data repeated, no matter how many times you specified it—up to the memory constraints in your system!

The modulo operator performs division but only returns the remainder:

PS C:\> 5 % 3

2

6.3. Other operators

PowerShell includes a number of other operators you’ll find useful from time to time. These aren’t operators you’ll use constantly, but they’ll come in handy for special situations.

6.3.1. String and array manipulation operators

Three operators are designed to facilitate string manipulation: –replace, –split, and –join.

The –replace operator searches for a substring within a string and replaces that substring with another, for example:

PS C:\> "SERVER-DC2" -replace "DC","FILE"

SERVER-FILE2

PS C:\> "SERVER-DC2","SERVER-DC7" -replace "DC","FILE"

SERVER-FILE2

SERVER-FILE7

As you can see, the input string can be a single string or an array of strings. In the latter case, each string in the array will be searched and replaced.

The –split and –join operators are designed to transform between single strings and arrays. The –split operator takes a single string, along with a delimiter, and returns an array, for example:

PS C:\> "one,two,three,four,five" -split ","

one

two

three

four

five

The default delimiter is a space, which means even though the example might look odd, it works:

PS C:\> -split "one two three four five"

one

two

three

four

five

It’s also possible to control the number of elements returned by defining a maximum number of substrings:

PS C:\> "one,two,three,four,five" -split ",", 3

one

two

three,four,five

You’ve told PowerShell to return three substrings, so it performs the split to give the first two, as previously shown, and then puts what’s left into the final element.

You also have the option of case sensitive or case insensitive splits (using –csplit and –isplit, respectively). These operators follow the same case rules as the logical and comparison operators discussed earlier:

PS C:\> "one,Two,three,four,five" -split "two"

one,

,three,four,five

PS C:\> "one,Two,three,four,five" -csplit "two"

one,Two,three,four,five

PS C:\> "one,Two,three,four,five" -isplit "two"

one,

,three,four,five

It’s also possible to use regular expressions to determine how a string is split. This is well covered in the about_Split help file.

The –join operator does the opposite, taking the elements of an array and creating a single string, with the array elements separated by a delimiter:

PS C:\> $names = Get-Service | select -expand name

PS C:\> $names -join ','

ADWS,AeLookupSvc,ALG,AppHostSvc,AppIDSvc,Appinfo,AppMgmt,aspnet_state,Audi

oEndpointBuilder,AudioSrv,BFE,BITS,Browser,c2wts,CertPropSvc,clr_optimizat

ion_v2.0.50727_32,clr_optimization_v2.0.50727_64,COMSysApp,CryptSvc,CscSer

vice,DcomLaunch,defragsvc,Dfs,DFSR,Dhcp,DNS,Dnscache,dot3svc,DPS,EapHost,E

FS,eventlog,EventSystem,FCRegSvc,fdPHost,FDResPub,FontCache,FontCache3.0.0

.0,gpsvc,hidserv,hkmsvc,idsvc,IISADMIN,IKEEXT,IPBusEnum,iphlpsvc,IsmServ,k

dc,KeyIso,KtmRm,LanmanServer,LanmanWorkstation,lltdsvc,lmhosts,MMCSS,MpsSv

c,MSDTC,MSiSCSI,msiserver,MSMQ,MSSQL$SQLEXPRESS,MSSQLServerADHelper100,nap

agent,Netlogon,Netman,NetMsmqActivator,NetPipeActivator,netprofm,NetTcpAct

ivator,NetTcpPortSharing,NlaSvc,nsi,NTDS,NtFrs,PerfHost,pla,PlugPlay,Polic

yAgent,Power,ProfSvc,ProtectedStorage,RasAuto,RasMan,RemoteAccess,RemoteRe

gistry,RpcEptMapper,RpcLocator,RpcSs,RSoPProv,sacsvr,SamSs,SCardSvr,Schedu

le,SCPolicySvc,seclogon,SENS,SessionEnv,SharedAccess,ShellHWDetection,SNMP

Optionally, the –join operator can combine the array elements without a delimiter:

PS C:\> -join $names

ADWSAeLookupSvcALGAppHostSvcAppIDSvcAppinfoAppMgmtaspnet_stateAudioEndpoin

tBuilderAudioSrvBFEBITSBrowserc2wtsCertPropSvcclr_optimization_v2.0.50727_

32clr_optimization_v2.0.50727_64COMSysAppCryptSvcCscServiceDcomLaunchdefra

gsvcDfsDFSRDhcpDNSDnscachedot3svcDPSEapHostEFSeventlogEventSystemFCRegSvcf

dPHostFDResPubFontCacheFontCache3.0.0.0gpsvchidservhkmsvcidsvcIISADMINIKEE

XTIPBusEnumiphlpsvcIsmServkdcKeyIsoKtmRmLanmanServerLanmanWorkstationlltds

6.3.2. Object type operators

PowerShell provides three operators that identify and manipulate object types. First, the –is operator is used to test the type of an object:

PS C:\> "world" -is [string]

True

The second operator, –isnot, performs the converse action—it tests if an object is not of a specific type. We tend to avoid using this operator because it frequently puts us into double negative territory. Third, the –as operator attempts to convert an object of one type into another type. If it’s unsuccessful in doing so, it’ll usually produce no output, rather than an error:

PS C:\> "55.2" -as [int]

55

PS C:\> "string" -as [int]

PS C:\>

These conversions can be quite handy. For example, when converting a floating-point number to an integer, PowerShell follows standard rounding rules:

PS C:\> (185739 / 1KB) -as [int]

181

This also illustrates the use of the KB (kilobyte) shortcut; PowerShell also recognizes KB, MB, GB, TB, and PB for kilobytes, megabytes, gigabytes, terabytes, and petabytes, respectively. When you use any of these shortcuts, the returned values will be in bytes, unless you further manipulate them:

PS C:\> 1mb

1048576

PS C:\> 10mb

10485760

PS C:\> 250MB+1GB

1335885824

PS C:\> 4590932427/1gb

4.27563900779933

PS C:\> 4590932427/1gb -as [int]

4

6.3.3. Format operator

You can use the –f format operator to create formatted strings. On the left side of the operator, provide a string that includes one or more placeholders. On the right side of the operator, provide a comma-separated list of values to be placed into those placeholders:

PS C:\> "Today is {0} and your name is {1}" -f (Get-Date),($Env:USERNAME)

Today is 12/8/2013 3:13:29 PM and your name is Administrator

In this example, the right-side list includes two parenthetical expressions, each of which ran a command. The results of those commands are then placed into the numbered placeholders.

The placeholders can also contain instructions for formatting the right-side values. These work primarily for numbers, dates, and simple strings:

PS C:\> "Today is {0:d} and Pi is {1:N}" -f (Get-Date),[math]::pi

Today is 12/8/2013 and Pi is 3.14

The d specifies a short date format, whereas the N specifies a standard decimal display for numbers. A list of standard formatting codes for dates can be found at http://msdn.microsoft.com/en-us/library/az4se3k1.aspx, and a list of numbers is available at http://msdn.microsoft.com/en-us/library/dwhawy9k.aspx. These standard codes typically provide an entire predefined format; you’ll also find custom codes:

PS C:\> "Today is {0:ddd d MMMM yyyy}" -f (Get-Date)

Today is Sat 8 December 2013

The previous example made use of the custom date codes documented at http://msdn.microsoft.com/en-us/library/8kb3ddd4.aspx; custom numeric codes are at http://msdn.microsoft.com/en-us/library/0c899ak8.aspx. You can also reference http://msdn.microsoft.com/en-us/library/txafckwd.aspx, which discusses the entire underlying .NET Framework formatting system and which provides additional links to formatting codes for time spans.

Note that the right-side values are expected to be simple values, including numbers, dates, and strings. If you provide an entire object on the right side, PowerShell will attempt to make a string representation of it. This approach may provide unexpected and less-than-useful results:

PS C:\> "Services running include {0}" -f (Get-Service)

Services running include ADWS

In the example, PowerShell retrieved all of the services but couldn’t put them all into the single placeholder. Therefore, it selected only the first service and displayed its name. PowerShell tends to prefer a “Name” property if one exists, because “Name” properties typically include human-readable, useful text identifiers.

6.3.4. Miscellaneous operators

Finally, PowerShell has several other operators that perform a variety of tasks. We’ll cover these in this chapter for completeness, but you’ll see more detailed information on them throughout the rest of this book as you encounter situations where these operators can be used effectively.

First is the call operator, which is the & sign (ampersand). Sometimes this is referred to as an invoke operator. You can use this to execute strings or script blocks, assuming they contain executable commands:

PS C:\> $cmd = "dir"

PS C:\> & $cmd

Directory: C:\

Mode LastWriteTime Length Name

---- ------------- ------ ----

d---- 10/21/2013 9:44 AM a00974d2e4c90e7814

d---- 11/27/2011 11:00 AM files

d---- 10/21/2011 9:50 AM inetpub

d---- 7/13/2009 8:20 PM PerfLogs

d-r-- 11/1/2011 8:38 AM Program Files

d-r-- 11/1/2011 8:07 AM Program Files (x86)

d---- 11/27/2012 11:05 AM Test

d-r-- 10/21/2011 9:51 AM Users

d---- 11/1/2011 8:38 AM Windows

Next is the subexpression operator, $(). Inside the parentheses, you can place expressions and PowerShell will execute them. This operator is primarily used within double quotation marks. Normally, PowerShell looks for escape characters and variables inside double quotes. Escape characters are executed, and variables are replaced with their contents. A subexpression enables you to have something more complicated than a single variable. For example, suppose $service contains a single Windows service, and you want to include its name. One way would be to first pull that name into a variable:

PS C:\> $service = Get-Service | select -first 1

PS C:\> $name = $service.name

PS C:\> "Service name is $name"

Service name is ADWS

Using a subexpression can result in more compact syntax, although many people find the $(syntax) difficult to read. The subexpression also avoids the creation of a variable, which saves a bit of memory:

PS C:\> $service = Get-Service | select -first 1

PS C:\> "Service name is $($service.name)"

Service name is ADWS

You may often want to work with a range of values, for example, the numbers 1 to 10. PowerShell has a range operator (designated by two dots, ..) that can be used for this task. A simple example will illustrate its use:

1..10 | foreach {Write-Host $_}

The numbers 1 to 10 will be written to your screen. You can also reverse the range so that the numbers decrement:

10..1 | foreach {Write-Host $_}

We’ve mentioned arrays a number of times, and though the full discussion of these objects is postponed until chapter 16, you need to know that the range operator can be used with arrays:

PS C:\> $procs = Get-Process

PS C:\> $procs[2..5]

Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName

------- ------ ----- ----- ----- ------ -- -----------

77 8 1952 6444 54 1.48 3152 conhost

403 11 1968 4052 44 1.20 516 csrss

351 39 2548 106424 169 16.69 580 csrss

351 18 4336 12560 73 0.09 1544 dasHost

There is one more type of operator you need to be aware of: The math operators are strictly .NET rather than PowerShell, but they’re the way you have to access math functionality in PowerShell.

6.4. Math operators

The .NET System namespace contains a class called Math (see http://msdn.microsoft.com/en-us/library/System.Math(v=vs.110).aspx). Chapter 7 explains classes, objects, methods, and other terminology you’ll need to know, but for now we’ll just show you how to use the math functionality.

The Math class has a number of methods (and a few fields) that supply the math functionality you’ll need in PowerShell. For example, if you need the value of pi, use this:

[math]::pi

[System.Math]::pi

This code is telling PowerShell to use the Math class by putting the name of the class in square brackets. The double colon (::) tells PowerShell to use a static field (or method), and pi determines the field or method to be accessed.

Note

A static method is one in which you don’t have to create an object from the class. You can use it directly.

Either example will give you the results you need. Case is optional, and the use of the namespace (System) is also optional.

A few examples will illustrate the versatility of this class:

· [math]::Sqrt(16)—Calculates the square root of a number. The result is 4.

· [math]::Sin([math]::pi/2)—Calculates the sin of an angle of pi/2 radians (90 degrees). The result is 1.

Other standard trigonometry functions such as cos and tan are also available.

Many calculations produce results with a large number of decimal places. For example, the free disk space on the machine used to produce this chapter is 190400217088 bytes. You, like us, would probably prefer to see that value in GB:

PS C:\> 190400217088 / 1GB

177.324020385742

That level of precision is unnecessary; you only need two or three places after the decimal point. The Math class supplies a Round() method that performs a mathematical rounding for you:

PS C:\> [math]::Round( (190400217088 / 1GB), 3)

177.324

The calculation is placed in parentheses to ensure it’s performed first. The Round() method takes two parameters: the value to be rounded and an integer that determines the number of decimal places to which rounding will occur. If you read the Math class documentation, you’ll discover that other rounding options exist.

The Math class provides the mathematical functionality that extends PowerShell without overwhelming you with an extra set of keywords to learn.

6.5. Summary

PowerShell’s operators are the basis for its logic-making capabilities, and you’ll use them extensively with scripting constructs such as If, Switch, and For. Obviously, the arithmetic operators have their uses, and the many miscellaneous operators come in handy as well.