During my Managing Active Directory with Windows PowerShell session at Techmentor Orlando, an attendee asked about finding when a user's password would expire. He wanted to be able to come in on Monday morning and run a report to find whose passwords were going to expire during the week. I didn't have the time to go into a solution then, but promised something on my blog, and here it is.
ManageEngine ADManager Plus - Download Free Trial
Exclusive offer on ADManager Plus for US and UK regions. Claim now!
Using the Mircosoft Active Directory provicer, there is a cmdlet caled Get-ADDefaultDomainPasswordPolicy.
[cc lang="PowerShell"]
PS C:\> Get-ADDefaultDomainPasswordPolicy
ComplexityEnabled : True
DistinguishedName : DC=jdhlab,DC=local
LockoutDuration : 00:30:00
LockoutObservationWindow : 00:30:00
LockoutThreshold : 7
MaxPasswordAge : 50.00:00:00
MinPasswordAge : 1.00:00:00
MinPasswordLength : 7
objectClass : {domainDNS}
objectGuid : 9db48ea5-9dea-43c9-9301-f2262b244ce2
PasswordHistoryCount : 12
ReversibleEncryptionEnabled : False
[/cc]
This shows me the maximum password age for the domain. Using Get-ADUser I can retrieve a user account and display the PasswordLastSet property which is a date time value. To find users whose passwords will expire this week I need to find users whose passwords were set between 50 days ago, (those will expire today) and 45 days ago. That is the premise of my Get-PasswordWillExpire script.
[cc lang="PowerShell"]
#requires -version 2.0
#this script assumes all users have the same policy and does
#not take fine grained password policies into account.
#The -Next parameter indicates how many days to check. In other words
#user accounts with expiring passwords in the next X days.
Param([int]$Next=5)
Import-Module ActiveDirectory
#get current domain password policy
$policy=Get-ADDefaultDomainPasswordPolicy
#save the password age in days
$days=$Policy.MaxPasswordAge.TotalDays
$Start=(Get-Date).AddDays(-$days)
$End=(Get-Date).AddDays(-($days-$next))
Write-Host "Finding users with passwords set between $($Start.Date) and $($End.Date)" -ForegroundColor Green
#get all users with passwords that have not expired and was set between
#the start and end dates
#you can select as many other properties as you'd like
Get-ADUser -filter {
Enabled -eq $True -AND PasswordLastSet -ge $Start.Date -AND PasswordLastSet -le $End.Date
} -properties * |
Select Name,PasswordLastSet,@{Name="PasswordAge";Expression={(Get-Date) - $_.PasswordLastSet }}
[/cc]
This is a script, not a function so you need to specify the full path. However, the script does take a parameter to indicate how many days forward you want to check the default is 5. So in my domain this would check for users with passwords set between 1/31/2011 and 2/5/2011.
The script searches for enabled accounts that meet this criteria and then displays the account name, when the password was set a and a custom property indicating the password age. You might want to select different properties or modify the search scope. As written this searches the entire domain. Note that this script doesn't take fine grained password policies into account. There are a set of Microsoft cmdlets for managing these types of policies and you should be able to use the same logic as this script.
There's much, much more you can do with Active Directory and PowerShell. Keep an eye out for the 2nd edition of Managing Active Directory with Windows PowerShell: TFM which should be available in the next several weeks.
Thanks for providing the script. How can this be used with Powershell and loop for all the accounts that exist in a given OU ?
You would modify the Get-ADUser expression to limit your search scope. It wouldn’t be that difficult to parameterize the script more so you could specify an OU or container. Look at help for Get-ADUser to see how to do this.