none
Problem with IF statement -and -or comparisons [Resolved] RRS feed

  • Question

  • Hi everyone !

    I'm having problems with this IF statement:

    if (($UserCDriveInput -gt ($TargetCDrive*1.04)) -or ($UserCDriveInput -lt ($TargetCDrive*0.95)))
                    {
                $MyReport += Get-HTMLDetail "CAUTION ! You have allocated an incorrect amount of space ($UserCDriveInput GB) for the C: drive"
                    }
    
                else
                    {
                $MyReport += Get-HTMLDetail-Green "The correct amount of Disk Space has been provisionned for Disk C: "
                    }

                   


    The problem is that it always seem to trigger the 'CAUTION' no matter what, or sometimes even behave unpredictably. I have a feeling I'm not understanding the IF structure properly


    Basically I'm trying to allow for a 5% discrepancy when the user is trying to validate disk drives. How much space did they ask you to give ? Well okay you're within 5% of existing you pass.. That's basically the gist of it

    Thursday, March 10, 2016 5:37 AM

Answers

  • Please note that the -Or operator in the original script posted above was correct.

    $a = 1.04 * 100
    $b = 0.95 * 100
    $c = $1.01
    
    If (($c -gt $a) -Or ($c -lt $b)) {"Not in range"}
    Else {"In range"}


    Richard Mueller - MVP Enterprise Mobility (Identity and Access)

    No.  To be in between two values it must satisfy BOTH conditions.  Basic logic and basic math "a" is between "b" and "c" if it is BOTH greater than "a" and less than "c".  Think about it.

    (b < a < c)  also (a > b AND a < c)

    The original test was ranging the wrong value.  Size is constant and the users test needed to be ranged.  The question should have been "Is the size within  the users range?".


    \_(ツ)_/

    Thursday, March 10, 2016 2:58 PM
  • OK, I had a typo in my code example, which I just fixed. I had 1.01 instead of 101 for the value of $c. But when I tested the code it works as expected with the -Or operator, as it should. If you rearrange the tests, then the -And operator would be correct, but as posted originally, only the -Or operator will work.

    Richard Mueller - MVP Enterprise Mobility (Identity and Access)

    Thursday, March 10, 2016 3:04 PM
    Moderator

All replies

  • What is this: $TargetCDrive*1.04

    \_(ツ)_/

    Thursday, March 10, 2016 6:07 AM
  • EDIT: Not working

    if (($UserCDriveInput) -gt ($TargetCDrive*1.04) -and ($UserCDriveInput) -lt ($TargetCDrive*0.95))
    				{
    				$MyReport += Get-HTMLDetail "CAUTION ! You have allocated an incorrect amount of space ($UserCDriveInput GB) for the C: drive"
    				}
    
    			else
    				{
    			$MyReport += Get-HTMLDetail-Green "The correct amount of Disk Space has been provisionned for Disk C: "
    				}
    Sigh it put my hopes up :( Everything works except if you gave C:too little space (shows successful anyway) . What a bloody pain :( Maybe I'm not comparing properly ?


    Thursday, March 10, 2016 6:18 AM
  • Something with this IF statement. I can't for the life of me understand. The one for the D drive works fine with no problem.

    if (($UserCDriveInput) -gt ($TargetCDrive*1.04) -or ($UserCDriveInput) -lt ($TargetCDrive*0.95))

    Why would this always generate true in this instance ? If like quadruple checked the variables. Is my syntax wrong ?

    Thursday, March 10, 2016 1:07 PM
  • The -Or operator seems correct to me. Check the values of the variables $UserCDriveInput and $TargetCDrive.

    Also, is Get-HTMLDetail your own function? Should there be a space before "-Green"?


    Richard Mueller - MVP Enterprise Mobility (Identity and Access)

    Thursday, March 10, 2016 1:10 PM
    Moderator
  • yeah the values look fine, also yes the -Green is a different function. Just doing for various coloring in the report. They're echoed throughout and it looks fine sigh. Bloody thing is driving me nuts.

    Here's my validation section: http://pastebin.com/n0HC8MkC

    Here's my entire script: http://pastebin.com/vjnqEWuR



    EDIT: Lol my English is so broken this morning I haven't slept in a million years but you understand what I'm saying :P


    Thursday, March 10, 2016 1:20 PM
  • "Between" is a > b AND a < c

    $b=5
    $c=10
    $a=7
    if($a -gt $b -and $a -lt $c){'number is in range'}else{'number out of range'}

    Testing for between or within a range is always testing that both condition are true and not either condition is true.


    \_(ツ)_/

    • Proposed as answer by jrv Thursday, March 10, 2016 1:43 PM
    Thursday, March 10, 2016 1:43 PM
  • So you're saying ? :

                if (($UserCDriveInput) -gt ($TargetCDrive*1.04) -and ($UserCDriveInput) -lt ($TargetCDrive*0.95))


    Thursday, March 10, 2016 1:46 PM
  • I'm also, asked you before what is in "$TargetCDrive".  If it is a string then this will fail.

    Consider the following statement:

    '12'*20

    What is its result?


    \_(ツ)_/

    Thursday, March 10, 2016 1:50 PM
  • 1212.....

    TargetCDrive contains

    $TargetCDrive = Get-WmiObject -computername $Target -Class Win32_LogicalDisk -Credential $Global:UserCreds -filter "DeviceID = 'C:'" | select -ExpandProperty "Size"
                $TargetCDrive = [math]::Round($TargetCDrive / 1gb)

    Not sure what you're alluding to though I'm sorry, I'm trying to

    ok this is so weird:

    The D Validation works in every case, the C Validation, works in every case now EXCEPT if the user gave too little space, then it generates TRUE sigh.

    # VALIDATE DISK SPACE C
                $MyReport += Get-HTMLDetail " "
                
                $TargetCDrive = Get-WmiObject -computername $Target -Class Win32_LogicalDisk -Credential $Global:UserCreds -filter "DeviceID = 'C:'" | select -ExpandProperty "Size"
                $TargetCDrive = [math]::Round($TargetCDrive / 1gb)
                
                if (($UserCDriveInput) -gt ($TargetCDrive*1.04) -and ($UserCDriveInput) -lt ($TargetCDrive*0.95))
                    {
                    $MyReport += Get-HTMLDetail "CAUTION ! You have allocated an incorrect amount of space ($UserCDriveInput GB) for the C: drive"
                    }

                else
                    {
                $MyReport += Get-HTMLDetail-Green "The correct amount of Disk Space has been provisionned for Disk C: "
                    }
                    

                    # VALIDATE DISK SPACE D
            if ($TargetNoDDrive -eq (0))
            {
                $MyReport += Get-HTMLDetail " "
                
                $TargetDDrive = Get-WmiObject -computername $Target -Class Win32_LogicalDisk -Credential $Global:UserCreds -filter "DeviceID = 'D:'" | select -ExpandProperty "Size"
                $TargetDDrive = [math]::Round($TargetDDrive / 1gb)
                
                if (($UserDDriveInput) -gt ($TargetDDrive*1.04) -or ($UserDDriveInput) -lt ($TargetDDrive*0.95))
                    {
                $MyReport += Get-HTMLDetail "CAUTION ! You have allocated an incorrect amount of space ($UserDDriveInput GB) for the D: drive"
                    }

                else
                    {
                $MyReport += Get-HTMLDetail-Green "The correct amount of Disk Space has been provisionned for Disk D: "
                    }
            }
            
            else
            {}    

            $MyReport += Get-CustomHeaderClose


    Thursday, March 10, 2016 2:02 PM
  • Then you need to be sure that all things are numbers.  If so the -AND will work.


    \_(ツ)_/

    Thursday, March 10, 2016 2:03 PM
  • but that's the thing check my above edit. For the D Validation, only the -or statement works. For the C Validation, only the -and statement works, unless you provision lesser space then it's still wrong. Doesn't make sense.

    The D Validation works in every case.

    Thursday, March 10, 2016 2:05 PM
  • Of course what you are trying to do does not really make any sense.  Why are you asking a user to guess the size of a disk?


    \_(ツ)_/

    Thursday, March 10, 2016 2:05 PM
  • Can you just tell us in plain language what it is you are trying to accomplish?  Are you trying to guess the free space on a disk?


    \_(ツ)_/

    Thursday, March 10, 2016 2:07 PM
  • User provisions a VM, then the report asks him how much space where you asked to provision ? THen it compares when he gave to what's on the server... They insisted. I found it twice as stupid don't worry, what's wrong with just reading it off the report ?

    Anyway so I can't argue, I just need to make it happen.... The reason I'm allowing a 5% margin of error is due to disk reservations and all that crap. Obviously the value isn't always exact. And so I'm saying if they asked the guy to give them 10GB and the drive is 9.86 then say it's alright. If he gave them like 5GB or 15GB or something though trigger a CAUTION in the report


    Thursday, March 10, 2016 2:08 PM
  • yah see my post right under yours
    Thursday, March 10, 2016 2:09 PM
  • So your logic is backwards. You want to test the user variation against the actual.

    Is <size within +_ 5% of user choice.

    if($size -gt .95 * $choice -and $size -lt 1.05 * $choice){'good'}else{'warning'}


    \_(ツ)_/

    Thursday, March 10, 2016 2:13 PM
  • Hmm.. Interesting. You're half correct. Even though between us I think you're 100% correct just don't tell Powershell.

    This is the ONLY way this works it seems:# VALIDATE DISK SPACE C
                $MyReport += Get-HTMLDetail " "
                
                $TargetCDrive = Get-WmiObject -computername $Target -Class Win32_LogicalDisk -Credential $Global:UserCreds -filter "DeviceID = 'C:'" | select -ExpandProperty "Size"
                $TargetCDrive = [math]::Round($TargetCDrive / 1gb)
                
                if (($TargetCDrive) -gt (0.95*$UserCDriveInput) -and ($TargetCDrive) -lt (1.05*$UserCDriveInput))
                    {
                    $MyReport += Get-HTMLDetail-Green "The correct amount of Disk Space has been provisionned for Disk C: "
                    }

                else
                    {
                $MyReport += Get-HTMLDetail "CAUTION ! You have allocated an incorrect amount of space ($TargetCDrive GB) for the C: drive"
                    }
                    

                    # VALIDATE DISK SPACE D
            if ($TargetNoDDrive -eq (0))
            {
                $MyReport += Get-HTMLDetail " "
                
                $TargetDDrive = Get-WmiObject -computername $Target -Class Win32_LogicalDisk -Credential $Global:UserCreds -filter "DeviceID = 'D:'" | select -ExpandProperty "Size"
                $TargetDDrive = [math]::Round($TargetDDrive / 1gb)
                
                if (($UserDDriveInput) -gt ($TargetDDrive*1.04) -or ($UserDDriveInput) -lt ($TargetDDrive*0.95))
                    {
                $MyReport += Get-HTMLDetail "CAUTION ! You have allocated an incorrect amount of space ($TargetDDrive GB) for the D: drive"
                    }

                else
                    {
                $MyReport += Get-HTMLDetail-Green "The correct amount of Disk Space has been provisionned for Disk D: "
                    }
            }
            
            else
            {}    

            $MyReport += Get-CustomHeaderClose

    I don't know what it is that forces the D to have to be an OR and the C to be an AND, the C has to be your way and the D my way... Voodoo.

    Thursday, March 10, 2016 2:36 PM
  • Alright. So as usual thank you so much for your help guys. If you want to continue to discuss that phenomenon I'd love to.

    Meanwhile here is the complete script for other people that may eventually get stuck in my shoes or whatever.

    It's a server report tool, everything you need to know should be inside the comments section. There's no error correction and I'm a noob still so it isn't worthy of the repository but I'm sure it'll be useful for some.

    Feel free to add/critize etc.. It's a combination of many people's work.

    http://pastebin.com/nzGwssvF

    Thursday, March 10, 2016 2:41 PM
  • First learn to use the code posting control.  Second you need to do some more debugging.  The logic is correct.  You head is telling you things backwards and leading to wrong assumptions and analysis.

    Example of #1

    $MyReport += Get-HTMLDetail " "
    
    $TargetCDrive = Get-WmiObject -computername $Target -Class Win32_LogicalDisk -Credential $Global:UserCreds -filter "DeviceID = 'C:'" | select -ExpandProperty "Size"
    $TargetCDrive = [math]::Round($TargetCDrive / 1gb)
    
    if ($TargetCDrive -gt 0.95 * $UserCDriveInput -and $TargetCDrive -lt 1.05 * $UserCDriveInput) {
    	$MyReport += Get-HTMLDetail-Green "The correct amount of Disk Space has been provisionned for Disk C: "
    } else {
    	$MyReport += Get-HTMLDetail "CAUTION ! You have allocated an incorrect amount of space ($TargetCDrive GB) for the C: drive"
    }
    
    
    # VALIDATE DISK SPACE D
    if ($TargetNoDDrive -eq (0)) {
    	$MyReport += Get-HTMLDetail " "
    	
    	$TargetDDrive = Get-WmiObject -computername $Target -Class Win32_LogicalDisk -Credential $Global:UserCreds -filter "DeviceID = 'D:'" | select -ExpandProperty "Size"
    	$TargetDDrive = [math]::Round($TargetDDrive / 1gb)
    	
    	if (($UserDDriveInput) -gt ($TargetDDrive * 1.04) -or ($UserDDriveInput) -lt ($TargetDDrive * 0.95)) {
    		$MyReport += Get-HTMLDetail "CAUTION ! You have allocated an incorrect amount of space ($TargetDDrive GB) for the D: drive"
    	} else {
    		$MyReport += Get-HTMLDetail-Green "The correct amount of Disk Space has been provisionned for Disk D: "
    	}
    } else { }
    
    $MyReport += Get-CustomHeaderClose

    What if there is no 'D' drive?


    \_(ツ)_/

    Thursday, March 10, 2016 2:47 PM
  • Please note that the -Or operator in the original script posted above was correct.

    $a = 1.04 * 100
    $b = 0.95 * 100
    $c = 101
    
    If (($c -gt $a) -Or ($c -lt $b)) {"Not in range"}
    Else {"In range"}


    Richard Mueller - MVP Enterprise Mobility (Identity and Access)


    Thursday, March 10, 2016 2:51 PM
    Moderator
  • Please note that the -Or operator in the original script posted above was correct.

    $a = 1.04 * 100
    $b = 0.95 * 100
    $c = $1.01
    
    If (($c -gt $a) -Or ($c -lt $b)) {"Not in range"}
    Else {"In range"}


    Richard Mueller - MVP Enterprise Mobility (Identity and Access)

    No.  To be in between two values it must satisfy BOTH conditions.  Basic logic and basic math "a" is between "b" and "c" if it is BOTH greater than "a" and less than "c".  Think about it.

    (b < a < c)  also (a > b AND a < c)

    The original test was ranging the wrong value.  Size is constant and the users test needed to be ranged.  The question should have been "Is the size within  the users range?".


    \_(ツ)_/

    Thursday, March 10, 2016 2:58 PM
  • OK, I had a typo in my code example, which I just fixed. I had 1.01 instead of 101 for the value of $c. But when I tested the code it works as expected with the -Or operator, as it should. If you rearrange the tests, then the -And operator would be correct, but as posted originally, only the -Or operator will work.

    Richard Mueller - MVP Enterprise Mobility (Identity and Access)

    Thursday, March 10, 2016 3:04 PM
    Moderator
  • OK, I had a typo in my code example, which I just fixed. I had 1.01 instead of 101 for the value of $c. But when I tested the code it works as expected with the -Or operator, as it should. If you rearrange the tests, then the -And operator would be correct, but as posted originally, only the -Or operator will work.

    Richard Mueller - MVP Enterprise Mobility (Identity and Access)

    Yup.  We solved that about 30 minutes ago.  The new code has fixed that.  There is an issue with how the D drive resolves but that has to be a bug or oversight.

    Case closed.


    \_(ツ)_/

    Thursday, March 10, 2016 3:09 PM
  • Hi everyone !

    So first off, the D drive is resolved with the flag I made. It's in the pastebin. I'm using that instead of the code block because there's no /spoiler option (or did I miss it, I tried).

    The way it is now it works, reports caution for values over and under and green for values within 0.5%

    I'll be honest though I still don't get it. I think I've misunderstood how AND/OR actually works. Like it was mentioned above. btw the reason I did it backwards is because the normal way wasn't working, so I thought if I moved around the conditions in the loop it might point me to an answer..  eventually I just left it that way because finally everything was working and I just didn't want to touch it anymore lol.

    So what's the issue with the D drive resolve ? You guys want to see the whole script ? Seems to work fine, if you specify 0 size in the dialog box it doesn't show up in the report.


    Friday, March 11, 2016 1:42 AM
  • First learn to use the code posting control.  Second you need to do some more debugging.  The logic is correct.  You head is telling you things backwards and leading to wrong assumptions and analysis.

    Example of #1

    $MyReport += Get-HTMLDetail " "
    
    $TargetCDrive = Get-WmiObject -computername $Target -Class Win32_LogicalDisk -Credential $Global:UserCreds -filter "DeviceID = 'C:'" | select -ExpandProperty "Size"
    $TargetCDrive = [math]::Round($TargetCDrive / 1gb)
    
    if ($TargetCDrive -gt 0.95 * $UserCDriveInput -and $TargetCDrive -lt 1.05 * $UserCDriveInput) {
    	$MyReport += Get-HTMLDetail-Green "The correct amount of Disk Space has been provisionned for Disk C: "
    } else {
    	$MyReport += Get-HTMLDetail "CAUTION ! You have allocated an incorrect amount of space ($TargetCDrive GB) for the C: drive"
    }
    
    
    # VALIDATE DISK SPACE D
    if ($TargetNoDDrive -eq (0)) {
    	$MyReport += Get-HTMLDetail " "
    	
    	$TargetDDrive = Get-WmiObject -computername $Target -Class Win32_LogicalDisk -Credential $Global:UserCreds -filter "DeviceID = 'D:'" | select -ExpandProperty "Size"
    	$TargetDDrive = [math]::Round($TargetDDrive / 1gb)
    	
    	if (($UserDDriveInput) -gt ($TargetDDrive * 1.04) -or ($UserDDriveInput) -lt ($TargetDDrive * 0.95)) {
    		$MyReport += Get-HTMLDetail "CAUTION ! You have allocated an incorrect amount of space ($TargetDDrive GB) for the D: drive"
    	} else {
    		$MyReport += Get-HTMLDetail-Green "The correct amount of Disk Space has been provisionned for Disk D: "
    	}
    } else { }
    
    $MyReport += Get-CustomHeaderClose

    What if there is no 'D' drive?


    \_(ツ)_/

    That's what this is for: (When the user inputs 0 as size in one of the validation questions it won't show the D: drive in the Validation section of the report.

    if ($TargetNoDDrive -eq (0)) {

    Friday, March 11, 2016 1:45 AM
  • You see I had a feeling I needed to add more comparisons. Initially the concept seemed simple I didn't expect it to get so clever.
    Friday, March 11, 2016 1:48 AM
  • The magic idea screen has not been invented yet.  It is missing since Steve J. didn't finish it.

    Next century...it will arrive.


    \_(ツ)_/

    Friday, March 11, 2016 4:52 AM