2

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!

3 Answers 3

5

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.
Sign up to request clarification or add additional context in comments.

Comments

3

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'
}

Comments

-3

Just remove these {} brackets from the if statement

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

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

3 Comments

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.
@mklement0 if (($a -and $b) -ne ($c -and $d)) { ... } would clarify the precedence?
@Jelphy: It would clarify the precedence, but it doesn't do what the OP wants (see my answer for what it actually does).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.