Testing 3 conditions in Powershell IF statement is driving me batty

JasonBA asked:

I’m trying to drive one of six outcomes from the combination of three variables being a ‘0’ or ‘1’ and I can’t get the right output when testing three conditions no matter how I try. I’ve tried 3 approaches and none generate the correct response. I attached them below but I may be way off track with all three.

Thanks in advance for the help.

$a = 1
$b = 0
$c = 1

if ($a = 0) {
    if ($b = 0) {
        if ($c = 0) {
            write-host "000"
        }
        else {
            write-host "001"
        }
    }
    else {
        if ($c = 0) {
            write-host "010"
        }
        else {
            write-host "011"
        }
    }
}
else {
    if ($b = 0) {
        if ($c = 0) {
            write-host "100"
        }
        else {
            write-host "101"
        }
    }
    else {
        if ($c = 0) {
            write-host "110"
        }
        else {
            write-host 111
        }
    }
}

attempt #2

$a = 1
$b = 0
$c = 1

if (($a = 0) -and ($b = 0) -and ($c = 0)) {
write-host "000"
}

elseif (($a = 0) -and ($b = 0) -and ($c = 1)) {
write-host "001"
}

elseif (($a = 0) -and ($b = 1) -and ($c = 0)) {
write-host "010"
}

elseif (($a = 0) -and ($b = 1) -and ($c = 1)) {
write-host "011"
}

elseif (($a = 1) -and ($b = 0) -and ($c = 0)) {
write-host "100"
}

elseif (($a = 1) -and ($b = 0) -and ($c = 1)) {
write-host "101"
}

elseif (($a = 1) -and ($b = 1) -and ($c = 0)) {
write-host "110"
}

elseif (($a = 1) -and ($b = 1) -and ($c = 1)) {
write-host "111"
}

attempt #3

$a = 1
$b = 0
$c = 1

switch ($a) {

0 {
    if (($b = 0) -and ($c = 0)) { write-host "000" }
    if (($b = 0) -and ($c = 1)) { write-host "001" }
    if (($b = 1) -and ($c = 0)) { write-host "010" }
    if (($b = 1) -and ($c = 1)) { write-host "011" }
  }

1 {
    if (($b = 0) -and ($c = 0)) { write-host "100" }
    if (($b = 0) -and ($c = 1)) { write-host "101" }
    if (($b = 1) -and ($c = 0)) { write-host "110" }
    if (($b = 1) -and ($c = 1)) { write-host "111" }
  }
}

Original script

$erroractionpreference="SilentlyContinue"

$ftppath = "\ServerFolder1Folder2Status Monitor"
$errorpath = "\ServerFolder1Folder2Status MonitorErrors"
$ftpstatusfiles = "opmessage21.txt","pgmessage21.txt","opmessage23.txt","pgmessage23.txt","opmessage24.txt","pgmessage24.txt","opmessage25.txt","pgmessage25.txt","opmessage26.txt","pgmessage26.txt"
$agelimit = 60
$to = "user@acme.com"
$from = "alert@acme.com"
$smtp = "smtp.acme.com"
$port = 25

function send-email {
    Send-MailMessage -Body "$body" -to $to -from $from -Subject "$subject" -smtp $smtp
}

foreach ($ftpstatusfile in $ftpstatusfiles) {

    # Set variables

    $fullftppath = $ftppath + $ftpstatusfile
    $fullerrorpath = $errorpath + $ftpstatusfile
    $lastupdated = (get-childitem $fullftppath).LastWriteTime
    $ftpmsgcontents = Get-Content -Path "$fullftppath" -Raw
    $errormsgcontents = Get-Content -Path "$fullerrorpath" -Raw
    $messageid = $ftpstatusfile.subString(0,$ftpstatusfile.length-4)
    $filestale = if ($lastupdated -lt (get-date).AddMinutes(-$agelimit)) { 1 } else { 0 }
    $fileerror = if ($ftpmsgcontents -ne 'OK') { 1 } else { 0 }

    # Define conditions where no alerting or copying tasks are necessary

    if (($filestale -eq 0) -and ($fileerror -eq 0) -and (!(Test-Path $fullerrorpath))) {
    write-host "Skipping to next iteration, file is fresh, indicates "OK", and there's nothing to clean up ($ftpstatusfile)."
    continue
    }

    if (($filestale -eq 1) -and (Test-Path $fullerrorpath)) {
    write-host "Skipping to next iteration, admin has already been notified of outdated file ($ftpstatusfile)."
    continue
    }

    if (($filestale -eq 0) -and ($fileerror -eq 1) -and (Test-Path $fullerrorpath)) {
    write-host "Skipping to next iteration, admin has already been notified of error ($ftpstatusfile)."
    continue
    }

    # Cleanup after an alert condition that's been resolved

    if (($filestale -eq 0) -and ($fileerror -eq 0) -and (Test-Path $fullerrorpath)) {
        write-host "$messageid reported an error that has since been resolved. Deleting $ftpstatusfile from $errorpath."
        Remove-Item $fullerrorpath
        continue
    }

    # Get LastWriteTime of the file and alert the admin if LastWriteTime is older than X minutes

    if (($filestale -eq 1) -and (!(Test-Path $fullerrorpath))) {
        write-host "As of $lastupdated, $ftpstatusfile is older than $agelimit minutes. Copying $ftpstatusfile to $errorpath and alerting admin.s"
        Copy-Item $fullftppath -destination $errorpath      
        $subject = "$messageid is older than $agelimit minutes"
        $body = "Last updated: $lastupdated"
        send-email
        continue
    }

    # Check the file for an error and alert the admin if the status is not OK

    if (($filestale -eq 0) -and ($fileerror -eq 1) -and (!(Test-Path $fullerrorpath))) {
        write-host "As of $lastupdated, $messageid reported the following error: $ftpmsgcontents. Copying $ftpstatusfile to $errorpath and alerting admins."        
        Copy-Item $fullftppath -destination $errorpath
        $subject = "Error reported by $messageid"
        $body = "$ftpmsgcontents (Last updated: $lastupdated)"
        send-email
    }

}

My answer:


In PowerShell, = is always an assignment operator. So, your first if statements are always reassigning 0 to the variables, and your output is always 000.

The correct equality operator is -eq.

if ($a -eq 1) {
    Write-Host "111111111111oneoneone!!!!!"
}

View the full question and answer on Server Fault.

Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.