More PowerShell Operators

learn-hero-img
In a previous article I introduced you to some common PowerShell operators. In that article, I left you with a code example that used a few new operators. Let me explain those and a few others.

Unary Operators

These operators are kind of fun, I think. They are designed to increase or decrease a value.

$i=1
$i++

The variable i has an initial value of 1, but after incrementing with the ++ operator, $i now has a value of 2. Yes, you could accomplish the same result with other operators.

$i=1
$i+=1

But if you are merely increasing or decreasing a counter, I find the unary operators a bit more elegant. Typically, you will use the operators with something like this:

for ($i = 1; $i -le 10; $i++) {
$file = Join-Path "c:\work" -ChildPath "TestFile_$i.dat"
New-Item -Path $file -ItemType File -Force | Out-Null
}

This snippet of code will loop through while $i is less than or equal to 10. Each time through the loop, $i is increased by one. I’m using the value of $i as part of the filename. The end result is a group of files called TestFile_1.dat through TestFile_10.dat.

Logical Operators

A logical operator is used to test the validity of an expression or condition. The result will be True or False.

-And

Use the -AND operator to determine if an overall set of expressions or conditions is true.

$x=2
$y=3
($x -gt 0) -And ($y -lt 5)

The use of parentheses isn’t required, but I find them helpful. In order for the -And operator to return True, all the conditions must be true. In this case $x must be greater than 0 and $y must be less than 5. Because both conditions are true, the entire expression is true. You might use something like this in an If construct.

If (($x -gt 0) -And ($y -lt 5)) {
$x*$y
}

There is no limit to the number of conditions.

$d = (Get-Date)
if ( ($d.DayOfWeek -eq 'Friday') -AND ($d.Day -eq 13) -And ( $PSVersionTable.PSVersion.Major -ge 4 )) {
#something scary happens
}

In order for something scary to happen, it must by Friday the 13th, and you must be running PowerShell version 4 or later. If any of those conditions are false, then the entire statement is false.

-Or

The -Or operator works much the same way, but you only need at least one of the expressions to be true for the entire statement to be true.

$x=20
$y=30
If (($x -gt 0) -Or ($y -lt 10)) {
  $x*$y
}

Even though one of the expressions is False, there is at least one that is True so the entire result is True.

-Xor

This operator is a bit trickier and frankly not one that I’ve had a need for in my scripts. This is a logical exclusive OR. In order for the entire expression to be True, one condition must be True and the other must be False.

If (($x -gt 0) -XOr ($y -lt 10)) {
  $x * $y
}

This is the same example as above and it gives the same result even with the operator change. The distinction is that with -Or only one condition needs to be True. With -XOr, you must have one True and one False.

-Not

Finally, the -Not operator turns things around by negating the result. In other words, if something is True, using -Not will give you False and vice versa. The operator can also be expressed with the ! symbol.

if (-Not (Test-Path C:\work\foodata.txt)) {
  #create the file
  Get-Process | Out-String | Set-Content -Path C:\work\foodata.txt -Encoding Ascii
}

Test-Path returns True or False, but code in the If block will only run if the result is True. So if the file does not exist, Test-Path returns False, but the -Not operator reverses it to True so the code in the If statement runs. When using this operator, I almost always find that I have to use parentheses.
In fact, if you intend to combine these operators, which you can, parentheses are critical.

$a = 1
$b = 5
$c = 10
($a -le $b) -Or (($a -gt 0) -And ( $c -le 20)) -Or ( (($a+$b) -ne 6) -And ( $b -eq 5 ))


I’ll let you copy and paste this code to try things out for yourself. Learn more by reading the help topic about_logical_operators.

About Logical Operators
About Logical Operators (Image Credit: Jeff Hicks)

Type Operators

The last set of operators I want to cover are those related to Type. As you know, everything in PowerShell is some type of object, such as a String, Integer or DateTime. PowerShell has a a set of operators you can use to test if something is of a particular type. These operators will give a True or False result. Or you can tell PowerShell to treat something as a particular type.

-Is

The -Is operator is like a comparison. If you run this:

100 -is [int]

PowerShell will tell you it is True. But not this:

"100" -is [int]

Because we are treating “100” as a string.

"100" -is [string]

You might use this operator in a script:

$p = get-process | where ws -ge 1gb
if ($p -is [array]) {
  Write-Warning "You have a problem."
}

-IsNot

Sometimes you want to test the opposite, which is where -IsNot comes into play.

$x="100"
$x -isnot [int]

Again, the result will be either True or False.

-As

Lastly, there may be situations where you want to treat something that is of one type as something else.

$x="10"
($x -as [int]) *2
$x -is [string]

In this example $x is a string, but I’m temporarily telling PowerShell to treat it as an integer. If you run the sample, you’ll see that it doesn’t change the original variable. Here are some other examples of this operator at work.

"7/4/1976" -as [datetime]
"The length of 12345 is $((12345 -as [string]).length)"
34.98734 -as [int]

Of course, PowerShell can’t always accomplish this or you might not get the results you expect. Try these to see what I’m talking about:

1234567 -as [datetime]
"foo" -as [datetime]

To wrap up, let’s pull everything together.

$i = 0
$OK = $False
cls
Do {
$i++
$Now = Get-Date
$r = Read-Host "Enter a cutoff date"
if (($r -as [datetime])) {
  $then = $r -as [datetime]
  #the entered date must be in the future and of the current year
  if (($then -gt $now) -AND ($now.year -eq $then.year)) {
    $OK = $True
  }
else {
  Write-Warning "You must pick a date in the future of the current year"
}
}
else {
  Write-Host "You didn't enter anything that looked like a date." -ForegroundColor Cyan
  If ($i -lt 3 ) {
    Write-Host "Try again" -ForegroundColor Cyan
  }
}
#continue until OK is True or 3 attempts
} until ($OK -Or $i -ge 3)
if ($OK) {
  Write-Host "Continuing with date $($then.ToShortDateString())"
  #your code here
}
else {
  Write-Warning "You apparently can't follow directions."
}

This is something you might use in a script where you are prompting the user to enter a date, but you are only giving them three attempts to get it right. Yes, I realize there are other ways to write this type of code, but I wanted to demonstrate some of the operators.

a PowerShell prompting example
a PowerShell prompting example (Image Credit: Jeff Hicks)


The best advice I can give you regarding these operators is to start out with simple expressions, and use parentheses when combining expressions. I have one more set of operators I want to discuss, so check back soon.