Introduction to PowerShell Operators

learn-hero-img
At first glance, PowerShell may appear overwhelming, but the language and syntax is actually quite simple, at least compared to other technologies such as VBScript or Perl. One reason I think it is easier to learn is that the operators are either things you already know or are easy to learn. You will use operators in filters and scripting constructs like if statements, so you need to take a little bit of time familiarizing yourself with them. Let me give you a quick rundown of operators you will most likely encounter or need to use.

Math Operators

The arithmetic operators are the same ones that you most likely have used all of your life. You can do addition (+), subtraction (-), multiplication (*) and division (/).  You can use operators right at the command prompt.

PS C:\> 5 + 2

Or with variables

PS C:\> $i * 100

You can also use parentheses to group operations like you learned in elementary school. These two expressions yield different results.

8+3/2 * 11
((8+3)/2) * 11

Whenever I have a complex expression, I always use parentheses.

Get-CimInstance -ClassName win32_logicaldisk |
Select DeviceID,Size,@{Name="Used";Expression = {$_.size - $_.freespace}},
@{Name="PctUsed";Expression={ (($_.size - $_.freespace) /$_.size) * 100}}

math operators
math operators (Image Credit: Jeff Hicks)

Before we move on, one quick comment about the + operator. Some people will use it to join strings together.

$name = "Jeff"
$computername = $env:computername
$OS = get-ciminstance win32_operatingsystem
$logmsg = "[" + (Get-Date) + "] User: " + $name + " Computer: " + $computername + "->" + $OS.caption

Personally, I find this tedious to construct and error prone. When I see something like this, I also feel the author doesn’t fully understand PowerShell yet. This approach is what we did in the days of VBScript. Instead, I encourage you to take a PowerShell approach and use variable expansion.

$logmsg = "[$(Get-Date)] User: $name Computer: $computername -> $($OS.caption)"

Assignment Operators

The equal sign (=) is the primary assignment operator. Typically you are assigning a value to a variable. The value can a simple item or the result of a PowerShell expression.

$a = 1
$running = get-service | where {$_.status -eq 'running'}

For most of your work, this is all you really need. But there are a few variations on this that you might find useful. For example, I just defined $a to have a value of 1. Suppose I want to add 3 to the value of $a and then update $a. You might write the command like this:

$a = $a+3

That is perfectly legitimate and if you check, you’ll see the $a now has a value of 4. But the more elegant approach is to use a better assignment operator.

$a+=2

This is telling PowerShell, “add 2 to $a and update $a.” Now $a has a value of 6. You can also use subtraction, division and multiplication.

PowerShell assignment operators
PowerShell assignment operators (Image Credit: Jeff Hicks)


This will also work in your scripts.

$data = import-csv -Path c:\scripts\computers.csv
#initialize a result array
$online=@()
foreach ($computer in $data.computername) {
#ignore errors for offline computers
if (Test-WSMan -ComputerName $computer -ErrorAction SilentlyContinue) {
#build a list of online computers
$online+= $computer
}
}
Get-CimInstance win32_operatingSystem -computername $online |
Select PSComputername,@{Name="Uptime";Expression={(get-date)-$_.LastBootUptime}}

You can see that I use the assignment operator to define $online as an empty array. Then if the computer responds to Test-WSMan, the computer name is added to the variable. Now I can use the variable in the Get-CimInstance expression.

Comparison Operators

The last set of operators I want to cover today are comparison operators. These are operators you will use all the time. Very often you need to filter with Where-Object based on some comparison, and scripting constructs like if statements also usually rely on some sort of comparison. For the most part PowerShell is not case sensitive, so that should make things easier for you. All operators start with a dash and are usually two to three characters. The characters even make sense. Finally, remember that whenever you use a comparison operator PowerShell is going to evaluate the comparison as boolean, i.e. true or false.
To test equality, use -eq. You can try these commands yourself to see the results.

5 -eq 5
5 -eq 4
'jeff' -eq 'Jeff'
'jeff' -eq 'sam'

Notice that these a direct value comparisons. You can’t use -eq to compare objects.

$before = get-service bits
stop-service bits
$after = get-service bits
$before -eq $after
$before.name -eq $after.Name
$before.Status -eq $after.Status

But you can use it to compare specific properties. The opposite operator (not equal) is -ne.

5 -ne 5
5 -ne 4
'jeff' -ne 'Jeff'
'jeff' -ne 'sam'

As you might expect, you’ll get opposite results. If you really need a case-sensitive comparison, all you need to do is insert a c at the beginning of the operator.

'jeff' -ceq 'jeff'
'jeff' -ceq 'JEFF'
'jeff' -cne 'jeff'
'jeff' -cne 'JEFF'

The remaining comparison operators are equally straightforward.

Comparison

Legacy

PowerShell

greater than

>

-gt

greater than or equal to

>=

-ge

less than

<

-lt

less than or equal to

<=

-le

Here are some examples you can try that use these operators.

get-process | where { $_.workingset -gt 100mb}
(dir $home\Documents -file).where({$_.lastwritetime.Year -le 2013})
if ($PSVersionTable.PSVersion.Major -ge 3) { "OK" }

You can use these operators for some clever work. Suppose you have some commands you want to run for a specified amount of time.

$stop = (Get-Date).AddMinutes(1)
do {
  write-host "Pretending to do something" -ForegroundColor Cyan
  start-sleep -seconds 5
} until ((Get-Date) -ge $stop)

These commands are a proof of concept that demonstrate how to run a command repeatedly until the time is greater or equal to some value. In this case, one minute from now. Or perhaps you’d like to set a limit so that the commands will run X number of times or until a time condition is met, whichever happens first. Note the use of operators.

$stop = (Get-Date).AddMinutes(1)
$x = 0
do {
  $x++
  write-host "Pretending to do something on pass $x" -ForegroundColor Cyan
  #simulate running the command
  start-sleep -seconds (Get-Random -Minimum 1 -Maximum 10)
} until (((Get-Date) -ge $stop) -OR $x -ge 5 )


I’ve explained most of the operators in this article. The ones that you may not recognize I’ll cover next time. In the meantime, you can read about all of these operators in PowerShell help. Run help about_operators.