# PasswordExpirationNotification.ps1
# Description:
# This script performs the following tasks
# a. Query Active Directory for a list of enabled users
# b. Email users basing on their password expiration dates by comparing to provided thresholds

# User input variables
$jumpBox='lax-dc03.hooli.com'
$authUrl='https://pwm.hooli.com'
$emailFrom='[email protected]'
$emailRelay="relay.hooli.com"
$thresholds=@(0,5,15)
$helpdeskPhone='1800-Hoo-liii'
$businessHours='24H'

function passwordExpirationNotification{
    param(
        $jumpBox,
        $emailFrom,
        $emailRelay,
        $authUrl,
        $thresholds,
        $helpdeskPhone,
        $businessHours
        )
    function generateEmailContent{
        param(
        $name,
        $email,
        $expireDays,
        $domain,
        $authUrl,
        $thresholds,
        $emailFrom,
        $helpdeskPhone,
        $businessHours
        )
        $thresholds=$thresholds|sort
        $days=if ($expireDays -le 0) {
                "<strong style='color: red;'>TODAY</strong>"
            }elseif($expireDays -le [int]$thresholds[1]){
                "in <font color=`"red`"><b>$expireDays days</b></font>"
            }elseif ($expireDays -le [int]$thresholds[2]) {
                "in <b>$expireDays days</b>"
            }else{
                "in $expireDays days"
                }
        
        return "
        <h3>Hello $name,</h3>
        <p>This email is a reminder that your <a href='#' style='text-decoration:none; color:#000'>$domain</a> password will expire in $days. Pleaes udpate it by following these options:</p>
        <h3>1. Use the password management tool:</h3>
        <ul>
            <li>While connected to VPN or direct-access to the company network, go to the following website using any browser: <a href='$authurl'>Self Service Password Portal</a></li>
            <li>Click on 'Sign In'</li>
            <li>Select the drop-down menu that corresponds: <a href='#' style='text-decoration:none; color:#000'>$($domain.toupper())</a> </li>
            <li>Enter your username (example: 'jdoe')</li>
            <li>Provide your existing password</li>
            <li>Click 'Sign in'</li>
            <li>If there are additional screens, follow that acccount setup wizard</li>
            <li>Proceed to the Main Menu and click the 'Change Password' button</li>
            <li>Enter a new password twice</li>
            <li>Click 'Change Password'</li>
        </ul>
        <h3>2. If you experience difficulties with the method above, contact our Help Desk for assistance</h3>
        <ul>
            <li><b>Phone:</b> $helpdeskPhone $businessHours</li>
            <li><b>Email:</b> $emailFrom</li>
        </ul>"
    }
    
    $domainObject=.{try{get-addomain -Server $jumpBox}catch{$false}}
    if (!$domainObject){break}
    $domain=$domainObject.DnsRoot
    $pdcEmulator=$domainObject.PDCEmulator
    $today=get-date
    $maxThreshold=($thresholds | Measure-Object -Maximum).Maximum
    $accounts = Get-ADUser -Server $pdcEmulator `
        -filter {Enabled -eq $true -and PasswordNeverExpires -ne $True -and PasswordExpired -ne $True} `
        -properties Name,Mail,PasswordLastSet,"msDS-UserPasswordExpiryTimeComputed"| `
        Where-Object{$null -ne $_.PasswordLastSet -AND $null -ne $_.Mail}                                                                                                                                                                                                                                                                                                                                                                                          
    foreach ($account in $accounts) {  
    $expiration=$account."msDS-UserPasswordExpiryTimeComputed"
    # The largest possible 64-bit value (2^63-1 = 9223372036854775807)
    # This value in property msDS-UserPasswordExpiryTimeComputed means that PasswordNeverExpires is true
    $max64BitValue=9223372036854775807
    $passwordExpiration=if ($expiration -ne $max64BitValue){
            [datetime]::FromFileTime($expiration)
        }else{
            $today.AddDays(-1)
            }
    [int]$daysDifference = (new-timespan $today $passwordExpiration).TotalDays
    [string]$name = $account.Name
    [string]$emailTo = $account.Mail
    write-host "Name: $name Email: $emailTo Password expires in: $daysDifference days..."
    if ($daysDifference -le $maxThreshold -and $daysDifference -ge 0){        
        write-host "Password of $name expires in: $daysDifference days. Email would be sent to: $emailTo"
        $emailContent=generateEmailContent $name $emailTo $daysDifference $domain $authUrl $thresholds $emailFrom $helpdeskPhone $businessHours
        try{
            Send-MailMessage -from "$emailFrom" -To "$emailTo" -subject "Password expiration notice" -bodyashtml $emailContent -smtpServer $emailRelay
        }catch{
            write-warning $_
        }
        }
    }
}

passwordExpirationNotification $jumpBox $emailFrom $emailRelay $authUrl $thresholds $helpdeskPhone $businessHours