Windows OS Hub
  • Windows Server
    • Windows Server 2016
    • Windows Server 2012 R2
    • Windows Server 2012
    • Windows Server 2008 R2
    • SCCM
  • Active Directory
    • Group Policies
  • Windows Clients
    • Windows 10
    • Windows 8
    • Windows 7
    • MS Office
    • Outlook
  • Virtualization
    • VMWare
    • Hyper-V
  • PowerShell
  • Exchange
  • Home
  • About

Windows OS Hub

  • Windows Server
    • Windows Server 2016
    • Windows Server 2012 R2
    • Windows Server 2012
    • Windows Server 2008 R2
    • SCCM
  • Active Directory
    • Group Policies
  • Windows Clients
    • Windows 10
    • Windows 8
    • Windows 7
    • MS Office
    • Outlook
  • Virtualization
    • VMWare
    • Hyper-V
  • PowerShell
  • Exchange

 Windows OS Hub / Active Directory / Password Change Notification When an AD User Password is About to Expire

November 9, 2020 Active DirectoryGroup PoliciesPowerShellWindows 10Windows Server 2016

Password Change Notification When an AD User Password is About to Expire

In this article we’ll show how to find out when a password of an Active Directory user account expires using PowerShell, how to set a password to never expire (PasswordNeverExpires = True), and notify users in advance to change their password.

If a user password in a domain has expired, the account is not locked, but it cannot be used to access domain resources until the user changes the expired password to a new one. The most often, remote users come across problems with expired passwords, since they cannot change their passwords using standard tools.

Contents:
  • How to Get a User Password Expiration Date in Active Directory?
  • How to Set AD User Password to Never Expire?
  • Active Directory Password Expiration Notification Policy
  • Password Expiration Email Notification via Powershell

A user password expiry time limit in a domain, how often it must be changed (maximum password age) and complexity requirements are set in the AD domain password policy. These parameters are set in the Default Domain Policy or the Fine-Grained Password Policy.

You can get the current password expiration policy settings in a domain using this PowerShell command:

Get-ADDefaultDomainPasswordPolicy|select MaxPasswordAge

In our example, the maximum user password age in the domain is 60 days.

powershell: Get-ADDefaultDomainPasswordPolicy|select MaxPasswordAge

How to Get a User Password Expiration Date in Active Directory?

You can view the password age and the date when it was changed last time in the command prompt using the Net user command:

net user jsmith /domain

net user domain - get password last set and expiration date values

You can find the information you need in these lines:

  • Password last set — 9/9/2020 9:23:59 AM
  • Password expires — 1/7/2021 9:23:59 AM
  • Password changeable — 9/10/2020 9:23:59 AM
You can get the password expiration date for any user. To do it, you don’t need administrator privileges or delegated privileges on the AD container with user accounts.

To view the settings of AD accounts, we will use a special PowerShell for Active Directory module that allows you to get values of different AD object attributes (see how to install and import the AD PowerShell module in Windows 10 and Windows Server 2012 R2/2016).

Using the Get-ADUser cmdlet, you can view the date when the user’s password was changed last time and check if the PasswordNeverExpires option is set:

get-aduser jsmith -properties PasswordLastSet, PasswordNeverExpires, PasswordExpired |ft Name, PasswordLastSet, PasswordNeverExpires,PasswordExpired

powershell: get-aduser PasswordLastSet, PasswordNeverExpires,PasswordExpired

  • PasswordLastSet is the date and time of the last password change;
  • PasswordNeverExpires returns True if a user password is never expires;
  • PasswordExpired – if a user password has expired, it returns True, if the password is not expired, it returns False.
You can check the time of the last password change in the graphical MMC snap-in Active Directory Users & Computers (dsa.msc). To do it, open user properties, go to the Attribute Editor tab and check the value of the pwdLastSet attribute.

But as you can see, the MMC snap-in only shows the time when the password was changed. It is not clear when the password expires.

pwdlastset value in user properties ADUC

To get the password expiry date instead of the time it was last changed, use a special constructed AD attribute: msDS-UserPasswordExpiryTimeComputed. The msDS-UserPasswordExpiryTimeComputed value is calculated automatically based on the date of the last password change and the domain password policy.

The UserPasswordExpiryTimeComputed parameter returns the date in the TimeStamp format, so I use the FromFileTime function to convert it to human readable value:

Get-ADUser -Identity jsmith -Properties msDS-UserPasswordExpiryTimeComputed | select-object @{Name="ExpirationDate";Expression= {[datetime]::FromFileTime($_."msDS-UserPasswordExpiryTimeComputed") }}

Thus, we got a user password expiration date.

Get-ADUser msDS-UserPasswordExpiryTimeComputed

If the value of msDS-UserPasswordExpiryTimeComputed is 0, it means that pwdLastSet is empty (null) or equals to 0 (the password has never been changed).

To get password expiry dates for all users from the specific container (OU) in AD, you can use the following PowerShell script:

$Users = Get-ADUser -SearchBase 'OU=Users,OU=NewYork,DC=woshub,DC=com' -filter {Enabled -eq $True -and PasswordNeverExpires -eq $False} -Properties msDS-UserPasswordExpiryTimeComputed, PasswordLastSet, CannotChangePassword
$Users | select Name, @{Name="ExpirationDate";Expression= {[datetime]::FromFileTime ($_."msDS-UserPasswordExpiryTimeComputed")}}, PasswordLastSet

It results in a table with the list of active users, expiration date and time of the last password change.

How to Get AD Users Password Expiration Date using powershell

You can display only the list of users with expired passwords:

$Users = Get-ADUser -SearchBase 'OU=Users,OU=NewYork,DC=woshub,DC=com' -filter {Enabled -eq $True -and PasswordNeverExpires -eq $False} -Properties msDS-UserPasswordExpiryTimeComputed, PasswordLastSet, CannotChangePassword
foreach($user in $Users){
if( [datetime]::FromFileTime($user."msDS-UserPasswordExpiryTimeComputed") -lt (Get-Date)) {
$user.Name
}
}

How to Set AD User Password to Never Expire?

If you want to set a permanent password for an account, check the Password Never Expires option in the user properties in AD (it is one of the bit values of the UserAccoutControl attribute).

ADUC: user's option "Password never expires"

Or you can enable this option with PowerShell:

Get-ADUser jsmith | Set-ADUser -PasswordNeverExpires:$True

You can set the Password Never Expires option at once for multiple users from a list in a text file:

$users=Get-Content "C:\PS\users_password_never_expire.txt"
Foreach ($user in $users) {
Set-ADUser $user -PasswordNeverExpires:$True
}

You can display the list of all users with the disabled regular password change option:

Get-ADUser -filter * -properties Name, PasswordNeverExpires | where {$_.passwordNeverExpires -eq "true" } |  Select-Object DistinguishedName,Name,Enabled |ft

Active Directory Password Expiration Notification Policy

Windows has a special Group Policy parameter that allows to notify users that they must change their passwords.

The policy is called Interactive logon: Prompt user to change password before expiration and is located under the GPO section: Computer Configuration -> Policies -> Windows Settings -> Security Settings -> Local Policies -> Security Options.

By default, the policy is enabled on the local Windows settings, and the notifications start to appear 5 days before a password expires. You can change the number of days that users will see a password change notification.

Group Policy parameter: Interactive logon: Prompt user to change password before expiration

After enabling this policy, if the user’s password expires, a notification to change a password will appear in the tray each time a user logs on.

Consider changing your password
Your password will expire in xx days.

Consider changing your password notification in Windows 10

You can also use a simple PowerShell script that automatically shows a dialog window with the prompt to change a password if it expires in less than 5 days:

Add-Type -AssemblyName PresentationFramework
$curruser= Get-ADUser -Identity $env:username -Properties 'msDS-UserPasswordExpiryTimeComputed','PasswordNeverExpires'
if ( -not $curruser.'PasswordNeverExpires') {
$timediff=(new-timespan -start (get-date) -end ([datetime]::FromFileTime($curruser."msDS-UserPasswordExpiryTimeComputed"))).Days
if ($timediff -lt 5) {
$msgBoxInput = [System.Windows.MessageBox]::Show("Your password expires in "+ $timediff + " days!`nDo you want to change it now?","Important!","YesNo","Warning")
switch ($msgBoxInput) {
'Yes' {
cmd /c "explorer shell:::{2559a1f2-21d7-11d4-bdaf-00c04f60b9f0}"
}
'No' { }
}
}
}

If a user clicks YES, a Windows Security window appears that you see after pressing Ctrl+Alt+Del or Ctrl+Alt+End (in case of an RDP/RDS connection).

password expiration reminder using PowerShell

The script implies that the PowerShell for AD module is installed on users’ computers. It can be used even if RSAT is not installed. Check the article “Using AD module without installing RSAT”.

Enable automatic startup for the PS script or run it as a GPO logon script.

Password Expiration Email Notification via Powershell

If you want to notify users about their password expiry by email, you can use this PowerShell script:

$Sender = "info@woshub.com"
$Subject = 'Important! Your password expires soon!'
$BodyTxt1 = 'Your password for'
$BodyTxt2 = 'expires in '
$BodyTxt3 = 'days. Remember to change your password in advance. If you have other questions, contact the HelpDesk.'
$smtpserver ="smtp.woshub.com"
$warnDays = (get-date).adddays(7)
$2Day = get-date
$Users = Get-ADUser -SearchBase 'OU=Users,OU=NewYork,DC=woshub,DC=com' -filter {Enabled -eq $True -and PasswordNeverExpires -eq $False} -Properties msDS-UserPasswordExpiryTimeComputed, EmailAddress, Name | select Name, @{Name ="ExpirationDate";Expression= {[datetime]::FromFileTime($_."msDS-UserPasswordExpiryTimeComputed")}}, EmailAddress
foreach ($user in $users) {
if (($user.ExpirationDate -lt $warnDays) -and ($2Day -lt $user.ExpirationDate) ) {
$lastdays = ( $user.ExpirationDate -$2Day).days
$EmailBody = $BodyTxt1, $user.name, $BodyTxt2, $lastdays, $BodyTxt3 -join ' '
Send-MailMessage -To $user.EmailAddress -From $Sender -SmtpServer $smtpserver -Subject $Subject -Body $EmailBody
}
}

The script checks all active domain users whose passwords are about to expire. In 7 days before the password expires, a user starts to get emails sent to the address specified in AD. Emails are sent until the password is changed or gets expired.

An administrator can force the user password change using the Set-ADAccountPassword cmdlet.

Run this PowerShell script regularly on any computer/server in your domain (it is easier to do it with the Task Scheduler). Of course, you will have to add the IP address of the host that is sending emails to the allowed senders list (can send email without authentication) on your SMTP server.

2 comments
1
Facebook Twitter Google + Pinterest
previous post
How to Create a Self-Signed Certificate in Windows with PowerShell?
next post
Configuring VLAN Interfaces on Windows 10/Windows Server 2016

Related Reading

How to Disable NetBIOS and LLMNR Protocols in...

April 9, 2021

Enable Windows Lock Screen after Inactivity via GPO

April 8, 2021

How to Create and Manage Scheduled Tasks with...

April 7, 2021

Updating Windows VM Templates on VMWare with PowerShell

April 5, 2021

Running Multiple IIS Websites on the Same Port...

April 1, 2021

2 comments

Wayne March 10, 2021 - 4:43 pm

Hi, I tried your PowerShell script that automatically shows a dialog window with the prompt to change a password if it expires in less than 5 days: I change it from 5 days to 10 days and notify the user’s password to expire in 153470 days?

Can you help me with this. we struggle with VPN users changing their passwords.

Reply
Erik March 25, 2021 - 1:09 pm

Same problem as Wayne

Reply

Leave a Comment Cancel Reply

Categories

  • Active Directory
  • Group Policies
  • Exchange
  • Windows 10
  • Windows 8
  • Windows 7
  • Windows Server 2016
  • Windows Server 2012 R2
  • Windows Server 2008 R2
  • PowerShell
  • VMWare
  • MS Office

Recent Posts

  • How to Disable NetBIOS and LLMNR Protocols in Windows Using GPO?

    April 9, 2021
  • Enable Windows Lock Screen after Inactivity via GPO

    April 8, 2021
  • How to Create and Manage Scheduled Tasks with PowerShell?

    April 7, 2021
  • Updating Windows VM Templates on VMWare with PowerShell

    April 5, 2021
  • Running Multiple IIS Websites on the Same Port or IP Address

    April 1, 2021
  • Can’t Copy and Paste via Remote Desktop (RDP) Clipboard

    March 31, 2021
  • UAC: This App Has Been Blocked for Your Protection on Windows 10

    March 30, 2021
  • How to Unlock a File Locked by Any Process or SYSTEM?

    March 29, 2021
  • Configuring a Domain Password Policy in the Active Directory

    March 26, 2021
  • Using Native Package Manager (WinGet) on Windows 10

    March 24, 2021

Follow us

woshub.com
  • Facebook
  • Twitter
  • RSS
Popular Posts
  • How to Configure Google Chrome Using Group Policy ADMX Templates?
  • Allow RDP Access to Domain Controller for Non-admin Users
  • Get-ADUser: Getting Active Directory Users Info via PowerShell
  • How to Find the Source of Account Lockouts in Active Directory domain?
  • Get-ADComputer: Find Computer Details in Active Directory with PowerShell
  • Configuring Proxy Settings on Windows Using Group Policy Preferences
  • Changing Desktop Background Wallpaper in Windows through GPO
Footer Logo

@2014 - 2018 - Windows OS Hub. All about operating systems for sysadmins


Back To Top