powershelllogical-operatorsequivalence

Converting VBScript's Eqv Operator


If you google for PowerShell Eqv you currently will find the VBScript-to-Windows PowerShell Conversion Guide on top of the list. Yet the answer is much of technical help:

Eqv Operator

Definition: Performs a logical equivalence on two expressions.
No doubt Eqv has its uses; we’re just not sure if it has any practical uses. Although there might be a Windows PowerShell equivalent we have to be honest: we didn’t look real hard for one.

In fact, I used the Eqv operator (also written as: A↔B) a number of times in VBScript and likely would have used it in PowerShell if it existed.

Example

I have a list of groups ("HR", "SAP", "!IT", "..."). If a user is a member of all the listed groups and explicitly not a member of groups that are preceded with an escalation mark (like "!IT", which is unraveled to: $Negate = $True and $Group = "IT") a specific task should be done. The script needs to iterate through the groups and immediately break the iteration when a group condition is not met (to save time).
A command for this would have been something like:

If ($Negate -eqv (IsMember($Group))) {Break}

How can I build a logical equivalence operator with a minimum of code?


Solution

  • If you take definition quiet literally, you will probably already see a possible way to achieve a logical equivalence operation:

    If ([Bool]$Expression1 -eq [Bool]$Expression2) {...}
    

    But if you take a close look to the truth table you might notice that the results for Eqv are exactly the opposite of an Xor operation. Meaning that you can also achieve logical equivalence operation with an inverted Xor:

    If (!(Expression1 -xor $Expression2)) {...}
    

    And as it doesn’t matter what you invert for an Xor (either the whole operation or one of the expressions), you can even simplify it to:


    If (!Expression1 -xor $Expression2) {...}
    

    Check

    0..3 | ForEach {
        $Expression1, $Expression2 = [Int]($_ / 2), [Int]($_ % 2)
        New-Object PSObject -Property @{
            Expression1 = [Bool]$Expression1
            Expression2 = [Bool]$Expression2
            Equivalence = !$Expression1 -xor $Expression2
        }
    } | Format-Table -AutoSize
    

    Truth Table

    Expression1 Expression2 Equivalence
    ----------- ----------- -----------
          False       False        True
          False        True       False
           True       False       False
           True        True        True
    

    Note: In this solution $Null expressions are considered $False. This differs from the VBScript Eqv implementation but is consistent with other PowerShell operators that contain $Null expressions. e.g. The VBScript statement: If 1 And vbNull Then msgbox "True" Else msgbox "False", returns True where the PowerShell statement If (1 -and $Null) {"True"} Else {"False"}, returns False.

    Bitwise

    If you looking for a bitwise Eqv operator (which should probably be called -bEqv, if it existed), then it would be:

    $Equivalence = -bNot Expression1 -bXOr Expression2    # e.g.: -bNot 3 -bXOr 5 = -7 (-bAnd 0xF = 9)