rss logo

Check AD User Password Expiration Time with PowerShell

PowerShell logo

Intro

It can be complicated for users to change their password from the RDS server once it has expired. So I worked on a PowerShell script that checks the password expiration time and sends an email to users to warn them 30 days before their passwords expires.

I'll detail all aspects of the PowerShell script here.

Get AD Users from a group

  • The first thing to do is to obtain the list of AD users. Here, we want to retrieve the users in the RDS group:
Screenshot of the RDS Properties dialog box showing the Members tab with a list of Active Directory users assigned to the RDS group.
  • Open Windows PowerShell as administrator:
Screenshot of a PowerShell command to check the password expiration date for a user using the msDS-UserPasswordExpiryTimeComputed property.
  • Enter this command to retrieve all users in the RDS group:
PS C:\ > (Get-ADGroupMember -Identity 'RDS').SamAccountName
  • Result of PowerShell command:
Screenshot of a PowerShell command listing the SamAccountName of members in the RDS Active Directory group using Get-ADGroupMember.
  • Add «where objectClass -eq 'user' » to get only users accounts (no groups):
PS C:\ > (Get-ADGroupMember -Identity 'RDS' | where objectClass -eq 'user').SamAccountName

Get AD User Expiration Time

  • To retrieve the expiration time, we need to add the msDS-UserPasswordExpiryTimeComputed property:
PS C:\ > $user = "e.cartman" PS C:\ > Get-ADUser "$user" -Properties msDS-UserPasswordExpiryTimeComputed
  • Result of PowerShell command:
Screenshot of a PowerShell command output showing detailed Active Directory properties for a user, including the msDS-UserPasswordExpiryTimeComputed attribute.
  • As we can see, we can't use the raw information retrieved. We need to use [DateTime]::FromFileTime to convert them into a human-readable format:
PS C:\ > $ADUser=(Get-ADUser "$user" -Properties msDS-UserPasswordExpiryTimeComputed) PS C:\ > [DateTime]::FromFileTime($ADUser.'msDS-UserPasswordExpiryTimeComputed')
  • Result of PowerShell command:
Screenshot of a PowerShell command to check the password expiration date for a user using the msDS-UserPasswordExpiryTimeComputed property.

Check if Password Never Expires is set

If the password never expires parameter is enabled for the user, we won't be able to obtain the expiration time.

So, when a user is in this situation, we need to deactivate the password never expires parameter, obtain the password modification time, then reactivate it.

  • Check that PasswordNeverExpires is set:
PS C:\ > if ( $($ADUser.PasswordNeverExpires) ) {
  • Disable the PasswordNeverExpires parameter:
PS C:\ > Set-ADUser $user -PasswordNeverExpires $false

Check if the account is enabled

  • We are only interested in enabled accounts:
PS C:\ > if ((Get-ADUser "$user").Enabled)

E-mail settings

I use the E-mail field in the Active Directory to retrieve the addresses of users to send messages to.

If this field is empty, we create the e-mail address with the First Name and Last Name parameters.

Comparison screenshot showing the update of an email address field in an Active Directory user profile, highlighting the change made to Eric Cartman's account.
  • Set EmailAddress:
PS C:\ > $user = "e.cartman" PS C:\ > Set-ADUser $user -EmailAddress $((Get-ADUser $user).GivenName.substring(0,1).ToLower() + (Get-ADUser $user).Surname.tolower() + "@shebangthedolphins.net") Screenshot of a PowerShell command generating an email address by concatenating the given name's initial, surname, and domain for a user in Active Directory.

PowerShell Script

########################### # author : shebangthedolphins.net # version : 1.0 # date : 2021.02 # role : Check AD password expiration # other : Tested on Windows 2019 Server # updates : # - 1.0 (2021/02) : First Version # - 1.1 (2021/02) : Add enabled accounts and users only Function Mail { param ([string]$emailbody, [string]$sujet, [string]$mail) $encoding = [System.Text.Encoding]::UTF8 Send-MailMessage -Encoding $encoding -To $mail -Subject $sujet -From $mail -smtpserver mx.shebangthedolphins.net -Body $emailbody } #get RDS users group foreach ($user in $(Get-ADGroupMember -Identity 'RDS' | where objectClass -eq 'user').SamAccountName) { if ((Get-ADUser "$user").Enabled) { #check if account is enabled #get AD users with PasswordNeverExpires, msDS-UserPasswordExpiryTimeComputed and mail parameters $ADUser=Get-ADUser "$user" -Properties PasswordNeverExpires, msDS-UserPasswordExpiryTimeComputed, mail #flag to know if password never expires parameter has been modified $Pne_Flag=$false #if current user has "PasswordNeverExpires" enabled if ( $($ADUser.PasswordNeverExpires) ) { Set-ADUser $user -PasswordNeverExpires $false #disable PasswordNeverExpires $Pne_Flag=$true #set flag to true } #if current user doesn't have mail parameter set if ( !($ADUser.mail) ) { Write-Host $user "doesn't have email set" #set email field Set-ADUser $user -EmailAddress $((Get-ADUser $user).GivenName.substring(0,1).ToLower() + (Get-ADUser $user).Surname.tolower() + "@shebangthedolphins.net") } $ADUser=Get-ADUser "$user" -Properties PasswordNeverExpires, msDS-UserPasswordExpiryTimeComputed, mail $ExpDate=[DateTime]::FromFileTime($ADUser.'msDS-UserPasswordExpiryTimeComputed') #get last modification date $DiffDays=$(New-TimeSpan -Start $(Get-Date) -End $($ExpDate)).Days #substract last modification date to current date if ( $DiffDays -lt 30 ) { #if less than 30 days Write-Host "User $user with e-mail :" $ADUser.mail "will have his password expired in" $DiffDays "days, the" $(get-date($ExpDate) -Format "yyyy.MM.dd") Mail ("Hello,`n`nYour password is going to expire in less than 30 days.`nAfter this date you will not be able to connect with your password.`nPlease consider to change it.`n`nThank you") "[ShebangTheDolphins] : Your remote desktop password is going to expire soon" $ADUser.mail if ($Pne_Flag) { #if the "PasswordNeverExpires" parameter has been modified Set-ADUser $user -PasswordNeverExpires $true #we enable PasswordNeverExpires } } else { Write-Host "User $user with e-mail :" $ADUser.mail "doesn't have to change his password, it expires in" $DiffDays "days, the" $(get-date($ExpDate) -Format "yyyy.MM.dd") } } }
Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.

Contact :

contact mail address