Multiple Variable Conditions for If Statement in PowerShell

10,001

Solution 1

You can use Compare-Object to compare the value pairs as arrays:

if (Compare-Object $a, $b   $c, $d  -SyncWindow 0) {
  'different'
} else {
  'same'
}

Note that this is convenient, but relatively slow, which may matter in a loop with many iterations.

  • The Compare-Object cmdlet compares two arrays and by default returns information about their differences.

  • -SyncWindow 0 compares only directly corresponding array elements; in other words: $a must equal $c, and $b must equal $d; without -SyncWindow, the array elements would be compared in any order so that 1, 2 would be considered equal to 2, 1 for instance.

  • Using the Compare-Object call's result as a conditional implicitly coerces the result to a Boolean, and any nonempty result - indicating the presence of at least 1 difference - will evaluate to $True.


As for what you tried:

Use of { ... } in your conditional is not appropriate.
Expressions enclosed in { ... } are script blocks - pieces of code you can execute later, such as with & or .

Even if you used (...) instead to clarify operator precedence (-ne has higher precedence than
-and), your conditional wouldn't work as expected, however:

  • ($a -and $b) -ne ($c -and $d) treats all variables as Booleans; in effect, given PowerShell's implicit to-Boolean conversion, you're comparing whether one value pair has at least one empty string to whether the other doesn't.

Solution 2

In addition to the answer from mklement0 and avoiding the rather slow Compare-Object cmdlet:

In what you tried, you will need to compare one specific value with each of the rest of the vales:

($a -eq $b) -and ($a -eq $c) -and ($a -eq $d)

Because the Comparison Operators (-eq) take a higher precedence than the Logical Operators (-and), you can leave the brackets and simplify it to:

$a -eq $b -and $a -eq $c -and $a -eq $d

To make this code DRY and easily expandable for even more values:

if ($a, $b, $c | Where {$_ -ne $d}) {
  'different'
} else {
  'same'
}
Share:
10,001

Related videos on Youtube

Lachie White
Author by

Lachie White

DevOps Architect / Cloud Architect / Terraform Fanatic

Updated on June 04, 2022

Comments

  • Lachie White
    Lachie White almost 2 years

    Thanks for the help in this, I think i have over complicated the below but the logic just isn't responding how my mind is telling it too.

    Logic in Question:

    $a = "One"
    $b = "Two"
    $c = "Three"
    $d = "Four"
    
    If( {$a -and $b} -ne {$c and $d} ) {
       Write-Host "Values are Different"
    } Else {
       Write-Host "values are the same"
    }
    

    I want the If statement to run when $a and $b are different to $c and $d, If the are the same see below, I want it to output that the values are the same

    $a = "One"
    $b = "One"
    $c = "One"
    $d = "One"
    

    Thanks in advance!

  • mklement0
    mklement0 about 6 years
    Due to operator precedence, your conditional is the same as $a -and ($b -ne $c) -and $d, but even with precedence clarified with (...) the logic won't work as intended. You are correct about the {...} being inappropriate, however.
  • Jelphy
    Jelphy about 6 years
    @mklement0 if (($a -and $b) -ne ($c -and $d)) { ... } would clarify the precedence?
  • mklement0
    mklement0 about 6 years
    @Jelphy: It would clarify the precedence, but it doesn't do what the OP wants (see my answer for what it actually does).