PowerShell: Notify Each User Before Password Expires

# This script email users basing on their password expiration dates

# User input variables
$jumpBox='dc02.intranet.kimconnect.com'
$authUrl='https://pwm.kimconnect.com'
$emailFrom='helpdesk@kimconnect.com'
$helpdeskPhone='###-###-####'
$helpdeskUrl='https://helpdesk.kimconnect.com/'
$emailRelay="relay.kimconnect.com"
$thresholds=@(0,5,15)

function notifyPasswordExpiration{
  param(
      $jumpBox,
      $emailFrom,
      $emailRelay,
      $authUrl,
      $thresholds,
      $helpdeskPhone,
      $helpdeskUrl
      )
  function generateEmailContent{
      param(
      $name,
      $email,
      $expireDays,
      $domain,
      $authUrl,
      $thresholds,        
      $helpdeskEmail,
      $helpdeskPhone,
      $helpdeskUrl
      )
      #$subdomain=.{[void]($domain -match '^([\w\d-_]+)');$matches[1]}
      $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>Please be advised that your <a href='#' style='text-decoration:none; color:#000'>$domain</a> password will expire in $days. You may 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>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>
      $(if($helpdeskPhone -notin @('none',$null,$false)){"<li><b>Phone:</b> $helpdeskPhone</li>"})
      $(if($helpdeskEmail -notin @('none',$null,$false) -and $helpdeskEmail -notmatch '^no-reply'){"<li><b>Email:</b> $helpdeskEmail</li>"})
      $(if($helpdeskUrl -notin @('none',$null,$false)){"<li><b>Website:</b> $helpdeskUrl</li>"})
  </ul>"
  }
  
  $domainObject=.{try{get-addomain -Server $jumpBox}catch{$false}}
  if (!$domainObject){
    write-warning "Unable to connect to domain server of $jumpBox"
    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"| `
                  ?{$null -ne $_.PasswordLastSet -AND $null -ne $_.Mail}                                                                                                                                                                                                                                                                                                                                                                                          
  foreach ($account in $accounts) {  
  $expiration=$account."msDS-UserPasswordExpiryTimeComputed"
  $passwordExpiration=if ($expiration -ne 9223372036854775807){
          [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 $helpdeskUrl
      Write-host Send-MailMessage -from "$emailFrom" -To "$emailTo" -subject "Password expiration notice" -bodyashtml $emailContent -smtpServer $emailRelay
      }
  }
}

notifyPasswordExpiration $jumpBox $emailFrom $emailRelay $authUrl $thresholds $helpdeskPhone $helpdeskUrl

Leave a Reply

Your email address will not be published. Required fields are marked *