Find out when your Password Expires
Few weeks ago I came across this question “How to find out an account’s password expiration date” in one of our internal mailing-list. This looks like a simple question, but when we tried to find the answer we realized it is not a trivial task. One of my colleagues pointed to this 22-printed page detailed MSDN article that describes how to find a user account’s password expiration date. The steps described in this article are a bit outdated. It does not take Fine-Grained Password policy (a new feature added in Windows 2008) into account while calculating the maximum password age. With the addition of fine grained password policy, this becomes an even more daunting task to do. Using AD Powershell this task can be achieved with ~40 lines of script-code. Here is function that calculates the password expiration date of a user object given its samAccountName, security identifier or DistinguishedName.
function Get-XADUserPasswordExpirationDate() {
Param ([Parameter(Mandatory=$true, Position=0, ValueFromPipeline=$true, HelpMessage="Identity of the Account")]
[Object] $accountIdentity)
PROCESS {
$accountObj = Get-ADUser $accountIdentity -properties PasswordExpired, PasswordNeverExpires, PasswordLastSet
if ($accountObj.PasswordExpired) {
echo ("Password of account: " + $accountObj.Name + " already expired!")
} else {
if ($accountObj.PasswordNeverExpires) {
echo ("Password of account: " + $accountObj.Name + " is set to never expires!")
} else {
$passwordSetDate = $accountObj.PasswordLastSet
if ($passwordSetDate -eq $null) {
echo ("Password of account: " + $accountObj.Name + " has never been set!")
} else {
$maxPasswordAgeTimeSpan = $null
$dfl = (get-addomain).DomainMode
if ($dfl -ge 3) {
## Greater than Windows2008 domain functional level
$accountFGPP = Get-ADUserResultantPasswordPolicy $accountObj
if ($accountFGPP -ne $null) {
$maxPasswordAgeTimeSpan = $accountFGPP.MaxPasswordAge
} else {
$maxPasswordAgeTimeSpan = (Get-ADDefaultDomainPasswordPolicy).MaxPasswordAge
}
} else {
$maxPasswordAgeTimeSpan = (Get-ADDefaultDomainPasswordPolicy).MaxPasswordAge
}
if ($maxPasswordAgeTimeSpan -eq $null -or $maxPasswordAgeTimeSpan.TotalMilliseconds -eq 0) {
echo ("MaxPasswordAge is not set for the domain or is set to zero!")
} else {
echo ("Password of account: " + $accountObj.Name + " expires on: " + ($passwordSetDate + $maxPasswordAgeTimeSpan))
}
}
}
}
}
}
Here are some sample usages of this function:
PS AD:\> Get-XADUserPasswordExpirationDate testuser1
Password of account: testuser1 already expired!
PS AD:\> Get-XADUserPasswordExpirationDate JohnDoe
Password of account: John Doe expires on: 02/25/2010 13:03:20
Since the MSDN article explains the algorithm using a flow diagram, I too have tried creating a flow diagram that explains the logic used to compute the password expiration date of an account:
Hope you find this useful. Please leave a comment if you have any feedback on this topic or would like to see any other topic discussed in our blog.
Enjoy,
Swami
Comments
Anonymous
June 08, 2010
Will this script work on both 2003 and 2008?Anonymous
June 08, 2010
Hello again,Having problems getting this to run on a Windows 2003 server.-> Have upgraded Powershell:PS C:Documents and SettingsAdministrator.EX2K3Desktop> $PSVersionTableName Value---- -----CLRVersion 2.0.50727.3082BuildVersion 6.0.6002.18111PSVersion 2.0WSManStackVersion 2.0PSCompatibleVersions {1.0, 2.0}SerializationVersion 1.1.0.1PSRemotingProtocolVersion 2.1>Have set exectionpolicy to Unrestricted-> When trying to run the script it seems that the script doesn't run. How's that?:PS C:Documents and SettingsAdministrator.EX2K3Desktop> .GET-XADUserPasswordExpirationDate user1PS C:Documents and SettingsAdministrator.EX2K3Desktop>/GAnonymous
August 09, 2010
@Greg BThe Active Directory module for Powershell is only supported on Windows Server 2008 R2 or Windows 7 OS. Please see the following for the installation details:blogs.msdn.com/.../installationAnonymous
March 16, 2011
You can also read the (new in 2008) account attribute msDS-UserPasswordExpiryTimeComputed. This will tell you the password expiration date.Anonymous
January 17, 2012
If the password is already expired, checking the "Password Never Expires" checkbox will un-expire the password until the user is located on a site with a DC.If the DC to be reachable over the VPN (which is a requirement for the lock/unlock suggestion that you have), why not just go ahead and change the password? Doing the change password will still cache the new password, so cached logons will work fine.http://www.lepide.com/Anonymous
July 31, 2012
The comment has been removedAnonymous
August 16, 2012
The net user command won't take note of fine grained password policies in a 2008r2 native domain. The attributes added to the schema that account for the functionality of fine grained password policies came after net user. That application has nothing that can account for those new attributes.Anonymous
January 29, 2014
How do we use this in powershell? I create a test4.ps1 file with the code from above pasted. Then in powershell i run .Test4.ps1 Get-XADUserPasswordExpirationDate USERNAME and nothing shows up. Am i running this correctly?ThanksAnonymous
March 24, 2014
Thank you, This is an awesome scriptfunction, I'm most certainly adding this to my arsenal of scripts!Cheers,Matthew Kerfootwww.matthewkerfoot.comAnonymous
April 24, 2014
Yours is too long. I just use old dos command on powershellnet user username <Enter> (for local user)net user username /domain <Enter> (for domain user)They will give you the same result.Anonymous
May 06, 2014
Hi Swami,Thank you, the script is very useful and others for sharing ideas. If you wish to check password/ account expiration using GUI, you can checkout JiJi Password Expiration Notification Tool.Regards,Gopiwww.jijitechnologies.comAnonymous
May 26, 2014
Go to boot from Windows CD, then go to command modeAnonymous
June 11, 2014
Change the last else statement as follows:$expiryDate = Get-Date ($passwordSetDate + $maxPasswordAgeTimeSpan) -format D echo ("Password of account: " + $accountObj.Name + " expires on: " + $expiryDate)This returns the expiry date in a non-ambiguous format.Anonymous
July 06, 2014
Powershell script just to find a password expiry? Seriously? Thi is so much easier:www.dolejarz.com/how-to-find-password-age-in-active-directoryAnonymous
July 23, 2014
The comment has been removedAnonymous
September 02, 2014
Even though I was able to obtain the password expiration via a dos command/prompt, I do appreciate this PowerShell function. I had no issues getting it to light up, since we run a Windows 2008 R2 infrastructure. In addition, I am able to re-purpose much of the code.Thanks again M.Ali!Anonymous
September 05, 2014
I have a strange situation where every now and again the if ($maxPasswordAgeTimeSpan -eq $null -or $maxPasswordAgeTimeSpan.TotalMilliseconds -eq 0) evaluates true. not sure why. Is there a way to manually set the $maxPasswordAgeTimeSpan equal to a 60 day time span as a work around?Anonymous
December 31, 2014
Found this script to be extremely helpful during an implementation of FGPP. I was having a problem with LDAP calls to active directory from an application that was returning results based off of the domain GPO rather than the FGPP. When trying to identify the problem, the net user command was also misleading as it does not report values based off of the FGPP's. This script was useful in finding and verifying the actual password expiration date for accounts with an FGPP applied.Thanks!Anonymous
January 14, 2015
One liner : Get-ADUser $user -Properties "msDS-UserPasswordExpiryTimeComputed"Then, just convert to datetime.Anonymous
February 01, 2015
Really Very good blog post, thanks for the useful information about password expiration notification and find out all users who have password never expires via PowerShell command. I also found good information from password-expiration-notification.blogspot.in whose provide the script to notify users through email notification about their impending AD password expiry and get the complete reports on the delivery status of password change reminder.Anonymous
March 06, 2015
Kindly have a look at adsysnet ad inactive account tracker,. This tool notify the password and account expiration info . And options for scheduling actions on those ad user accounts.try this link, adsysnet.com/asn-active-directory-inactive-account-tracker-download.aspxAnonymous
October 01, 2015
How do you run this script in powershell?Anonymous
October 28, 2015
Steve - thanks for the one-liner. The way powershell should work for something so simple!Anonymous
November 25, 2015
Automatically computes the date and time, assigns it to column named PasswordExpirationDate get-aduser -filter {Enabled -eq $True -and PasswordNeverExpires -eq $False -and Name -notlike "$" -and Mail -like "@"} -Properties msDS-UserPasswordExpiryTimeComputed,mail | select givenname,surname,samaccountname,@{name="PasswordExpirationDate";expression={([datetime]::FromFileTime($."msDS-UserPasswordExpiryTimeComputed"))}} | sort PasswordExpirationDate | ft Or this to save to .csv file get-aduser -filter {Enabled -eq $True -and PasswordNeverExpires -eq $False -and Name -notlike "$" -and Mail -like "@"} -Properties msDS-UserPasswordExpiryTimeComputed,mail | select givenname,surname,samaccountname,@{name="PasswordExpirationDate";expression={([datetime]::FromFileTime($."msDS-UserPasswordExpiryTimeComputed"))}} | sort PasswordExpirationDate | export-csv -path passwordsexpiring.csv Want to know how many passwords expire tomorrow in a one liner? get-aduser -filter {Enabled -eq $True -and PasswordNeverExpires -eq $False -and Name -notlike "$" -and Mail -like "@"} -Properties msDS-UserPasswordExpiryTimeComputed,mail | select givenname,surname,samaccountname,mail,@{name="PasswordExpirationDate";expression={([datetime]::FromFileTime($."msDS-UserPasswordExpiryTimeComputed"))}} | where {(($.PasswordExpirationDate).toshortdatestring()) -like (((get-date).adddays(1)).ToShortDateString())} | ftAnonymous
November 25, 2015
Automatically computes the date and time, assigns it to column named PasswordExpirationDate. Previous post would only display if they had an email address in AD. Used the previous to send expiration notice to end user. get-aduser -filter {Enabled -eq $True -and PasswordNeverExpires -eq $False -and Name -notlike "$"} -Properties msDS-UserPasswordExpiryTimeComputed | select givenname,surname,samaccountname,@{name="PasswordExpirationDate";expression={([datetime]::FromFileTime($."msDS-UserPasswordExpiryTimeComputed"))}} | sort PasswordExpirationDate | ft Or this to save to .csv file get-aduser -filter {Enabled -eq $True -and PasswordNeverExpires -eq $False -and Name -notlike "$"} -Properties msDS-UserPasswordExpiryTimeComputed | select givenname,surname,samaccountname,@{name="PasswordExpirationDate";expression={([datetime]::FromFileTime($."msDS-UserPasswordExpiryTimeComputed"))}} | sort PasswordExpirationDate | export-csv -path passwordsexpiring.csv Want to know how many passwords expire tomorrow in a one liner? get-aduser -filter {Enabled -eq $True -and PasswordNeverExpires -eq $False -and Name -notlike "$"} -Properties msDS-UserPasswordExpiryTimeComputed | select givenname,surname,samaccountname,mail,@{name="PasswordExpirationDate";expression={([datetime]::FromFileTime($."msDS-UserPasswordExpiryTimeComputed"))}} | where {(($.PasswordExpirationDate).toshortdatestring()) -like (((get-date).adddays(1)).ToShortDateString())} | ft Hope it helps someone else,Anonymous
February 04, 2016
Hey Swami, your scripts is gr8 and working. I'll like to have this script sending the email to user about password expire and it should be automated whereas above we need t manually run the Get-XADUserPasswordExpirationDate username command to get the details. Can you update the script and provide as i'm stuck up on it. Appreciate your help. Thanks, Admin