Home > Software design >  Efficiently find the oldest date
Efficiently find the oldest date

Time:10-05

My code gets all suspended users, the last time they interacted, and what license the person has. Currently I think I could do some things better and I just realized I need to find users with the oldest interaction time that have the main license and then do stuff with the oldest.

$GSuspend = gam report users parameters accounts:is_disabled,gmail:last_interaction_time fulldatarequired accounts | ConvertFrom-Csv | Where-Object { $_.'accounts:is_disabled' -eq $true }

$GLicenses = gam print users licenses | ConvertFrom-Csv | Where-Object { $_.Licenses -contains '1010020020' -or $_.Licenses -contains '1010340001' }
#archive = 1010340001 , 1010020020 = main

$Result = $GSuspend | ForEach-Object {
    If ($GLicenses.primaryEmail -contains $_.email ) {
        foreach ($License in $GLicenses) {
            If ($License.primaryEmail -eq $_.email) {
                If ($License.licenses -contains '1010020020' ) {
                    $Type = 'Main'
                }
                ElseIF ($License.licenses -contains '1010340001' ) {
                    $Type = 'Archive'
                }
                Else {
                    $Type = $License.licenses
                }
            }
        }

        If ( $null -ne $_."gmail:last_interaction_time" ) {
            $GMailLastUsed = Get-date($_."gmail:last_interaction_time") -Format("MM-dd-yy")
        }
        Else { $GMailLastUsed = $null }

        [PSCustomObject]@{
            Email    = $_.email
            Type     = $Type
            LastUsed = $GMailLastUsed
        }
    }
}

Example output

<Email> Archive 06-24-20
<Email> Main    06-24-20
<Email> Main    07-30-21
<Email> Archive 06-24-20
<Email> Archive 05-06-19

Do I need to loop through $Result and if so I am not even sure how to find the oldest date? I feel like there must be a better way?

CodePudding user response:

You could keep track of the oldest assigned Main license throughout the loop:

# create a simple object to keep track of the oldest observed user with a main license
$oldest = [pscustomobject]@{
  When = $null
  User = $null
}

$Result = $GSuspend | ForEach-Object {
    If ($GLicenses.primaryEmail -contains $_.email ) {
        foreach ($License in $GLicenses) {
            If ($License.primaryEmail -eq $_.email) {
                If ($License.licenses -contains '1010020020' ) {
                    $Type = 'Main'
                    # we found a user with a main license - let's compare their date to the previous oldest user
                    $lastUse = (Get-Date $_.'gmail:last_interaction_time')
                    if($null -eq $oldest.User -or $oldest.When -gt $lastUse){
                        # update $oldest
                        $oldest.When = $lastUse
                        $oldest.User = $_
                    }
                }
            }
        }
        # ...
    }
}

Once you reach the end of the loop, $oldest.User will contain the oldest user found that matches the license criteria.


Alternatively, switch to a sortable datetime format when constructing your output objects:

$GMailLastUsed = Get-date $_."gmail:last_interaction_time" -Format "yyyy-MM-dd"

Now that the components of your date string are ordered from most to least significant, you can use string sorting to find the oldest:

$oldest = $Result |Where-Object Type -eq 'Main' |Sort-Object LastUsed |Select -First 1
  • Related