28

How do you chain multiple sets conditions together when you want either one set or the other set of 2 conditions to be true?

To be more precise, I want to do:

If User is logged in AND Operating system version is Windows 10

OR

User is logged in AND LogonUI process is not running

For example I have:

if (
    (Get-WmiObject –ComputerName $poste –Class Win32_ComputerSystem).UserName`
    -and`
    (Get-WmiObject -Computer $poste -Class Win32_OperatingSystem).Version -like "*10*"
)
{ echo do X }

which is working fine. I want to add the other block of conditions within that same if. I tried this, but it's not working:

if (
    (Get-WmiObject –ComputerName $poste –Class Win32_ComputerSystem).UserName`
    -and`
    (Get-WmiObject -Computer $poste -Class Win32_OperatingSystem).Version -like "*10*"`
    -or`
    (Get-WmiObject –ComputerName $poste –Class Win32_ComputerSystem).UserName`
    -and -not`
    (Get-Process -ErrorAction SilentlyContinue -ComputerName $poste -name logonui)
)
{ echo do X }

How do you chain multiple "blocks" like this?

I know I could do two different if statements, but isn't there a way to chain it all together in one statement? The statement contains a lot of code and I don't want to duplicate it.

3 Answers 3

47

Put each set of conditions in parentheses:

if ( (A -and B) -or (C -and D) ) {
    echo do X
}

If either the first or the second set of conditions must be true (but not both of them) use -xor instead of -or:

if ( (A -and B) -xor (C -and D) ) {
    echo do X
}

Replace A, B, C, and D with the respective expressions.

Sign up to request clarification or add additional context in comments.

Comments

4

If you want to make the code in your own answer easier to understand you can remove the duplicate code to make the if statement cleaner.

Assigning the results to variables and using those instead:

$UserName = Get-WmiObject –ComputerName $poste –Class Win32_ComputerSystem | select -ExpandProperty UserName
$WindowsVersion = Get-WmiObject -Computer $poste -Class Win32_OperatingSystem | select -ExpandProperty Version
$LogonuiProcess = Get-Process -name logonui -ComputerName $poste -ErrorAction SilentlyContinue

Then either:

if (($UserName -and $WindowsVersion -like "*10*") -or ($UserName -and -not $LogonuiProcess)) {Write-Output "do X"}

Or

if ($UserName -and $WindowsVersion -like "*10*") {Write-Output "do X"}
elseif ($UserName -and -not $LogonuiProcess) {Write-Output "do Y"}

Comments

0

So after trying a few things, it seems there are two methods:

if (
        (Get-WmiObject –ComputerName $poste –Class Win32_ComputerSystem).UserName`
        -and`
        (Get-WmiObject -Computer $poste -Class Win32_OperatingSystem).Version -like "*10*"`

    ) { echo do X }

    elseif (

        (Get-WmiObject –ComputerName $poste –Class Win32_ComputerSystem).UserName`
        -and -not`
        (Get-Process -ErrorAction SilentlyContinue -ComputerName $poste -name logonui)

    )   { echo do X }

or using Ansgar Wiechers's excellent answer to chain it all in one IF:

if (
        (      
        (Get-WmiObject –ComputerName $poste –Class Win32_ComputerSystem).UserName`
        -and`
        (Get-WmiObject -Computer $poste -Class Win32_OperatingSystem).Version -like "*10*"`
        ) -or`
        (       
        (Get-WmiObject –ComputerName $poste –Class Win32_ComputerSystem).UserName`
        -and -not`
        (Get-Process -ErrorAction SilentlyContinue -ComputerName $poste -name logonui)`
        )

    ) { echo do X }

1 Comment

You can continue a line after an operator like -and. Open parentheses automatically continue on the next line. Note that -and and -or uniquely have equal precedence in powershell.

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.