powershellvalidationforeachsyntaxequality-operator

If all values in 'foreach' are true


I'm writing a Powershell script for finding all Azure Storage Accounts in which all containers 'LastModifiedDate' is less than 6 months. If ONLY one container is FALSE to this statement ASA should be ignored.

One way how to achieve this was to get an array of 'LastModifiedDate' for one Storage Account and then compare it with (Get-Date).AddDays(-180). The question is how to do this correctly? It should be ignored if only one value from an array if FALSE.

I achieved this with BREAK operator but I think this is not a good solution. Could anyone help me with this issue?

function check_stores {

     $stores = Get-AzureRmResource -ODataQuery "`$filter=resourcetype eq 'Microsoft.Storage/storageAccounts'" $x = (Get-Date).AddDays(-180)

     foreach($store in $stores){

         $storename = $store.Name

         $names = (Get-AzureRmStorageContainer -ResourceGroupName $store.ResourceGroupName -StorageAccountName $store.Name).Name

         foreach($name in $names){

             $date = (Get-AzureRmStorageContainer -ResourceGroupName $store.ResourceGroupName -StorageAccountName $store.Name -Name $name).LastModifiedTime

             if($date -gt $x){
                  break
             }
         }

         if($x -gt $date){
             "Storage Account Name: $storename"

         }
     }

}

check_stores

Solution

  • As commented: This is the beauty of PowerShell, you don't need to iterate yourself, the equality operators will iterate over the left argument collection by themself

    When the input to an operator is a scalar value, comparison operators return a Boolean value. When the input is a collection of values, the comparison operators return any matching values. If there are no matches in a collection, comparison operators return an empty array.

    As I do not have access to your environment, I have created a common answer for this:

    $Dates = [DateTime[]]('2020-03-10', '2020-03-11', '2020-03-12', '2020-03-14')
    $Date1 = [DateTime]'2020-03-09'
    $Date2 = [DateTime]'2020-03-12'
    $Date3 = [DateTime]'2020-03-15'
    

    Any date

    Check if any date is less then the given date

    If ($Dates -lt $Date1) {"Some dates are less then $Date1"} Else {"None of the dates are less then $Date1"}
    If ($Dates -lt $Date2) {"Some dates are less then $Date2"} Else {"None of the dates are less then $Date2"}
    If ($Dates -lt $Date3) {"Some dates are less then $Date3"} Else {"None of the dates are less then $Date3"}
    

    yields:

    None of the dates are less then 03/09/2020 00:00:00
    Some dates are less then 03/12/2020 00:00:00
    Some dates are less then 03/15/2020 00:00:00
    

    All dates

    This implies that if you want to check whether all dates falls within the range you will need to do the opposite (check if any date is not greater or equal then the given date):

    If (!($Dates -ge $Date1)) {"All dates are less then $Date1"} Else {"Some of the dates aren't less then $Date1"}
    If (!($Dates -ge $Date2)) {"All dates are less then $Date2"} Else {"Some of the dates aren't less then $Date2"}
    If (!($Dates -ge $Date3)) {"All dates are less then $Date3"} Else {"Some of the dates aren't less then $Date3"}
    

    yields:

    Some of the dates aren't less then 03/09/2020 00:00:00
    Some of the dates aren't less then 03/12/2020 00:00:00
    All dates are less then 03/15/2020 00:00:00
    

    All True

    Generally speaking, if you want to check if all values are true, you might just check for if none of the values are not true:

    $SomeTrue = $False, $True, $False, $True # (Not all true)
    $AllTrue = $True, $True, $True, $True
    
    !($SomeTrue -ne $True) # => All true?
    False
    !($AllTrue -ne $True) # => All true ?
    True