We have a subset of users whose passwords are not expired while they are in a certain stage of their existence. We store these accounts in 1 particular OU, and once they are ready to move on to their next stage of evolution, we expect them to learn how to change their passwords.
In the past, we’ve utilized a VB script to update the ‘pwdLastSet’ field on the account, but as the number of users matching the parameters for this stage has increased, the amount of time that it takes this script to function has risen dramatically.
So, I took some time to go ahead and rewrite it in Powershell as it is simple enough to not need a C# executable.
I’ve run it through performance testing, and it’s a massive increase in performance. On average (in my testing), for every hour of the old code running, you’re left with 1 minute worth of new code processing time.
## Requires Server 2008 R2 or later ## Import the Active Directory Powershell module Import-Module ActiveDirectory ## Path to the applicants OU $ADsPath = [ADSI]“LDAP://OU=TestOU,DC=Domain,DC=Local” ## Create the directory search object to the find the matching objects $Search = New-Object DirectoryServices.DirectorySearcher($ADsPath) ## Filter translates to "Any user account that is not disabled" $Search.filter = “(&(objectCategory=person)(objectClass=user)(!userAccountControl:1.2.840.113556.1.4.803:=2))” ## Required to exceed 1000 records automatically $Search.PageSize = 1000 ## Limits the search to the specified OU $Search.SearchScope = “OneLevel” ## Perform the search and return the records into the array $results $results = $Search.Findall() ## Loop through the array to process the changes Foreach($result in $results) { ## Get the directory entry $User = $result.GetDirectoryEntry() ## Get the accounts samAccountName $name = [string]$User.samAccountName ## Produce an ADUser object to represent the account with only the properties needed $adoUser = Get-ADUser $name -Properties pwdLastSet ## Perform the first reset - 0 sets the account to require the password be changed $adoUser.pwdLastSet = 0 Set-ADUser -Instance $adoUser ## Perform the second reset - 1 actually sets the pwdLastSet value to automatically enter the current datetime value $adoUser.pwdLastSet = -1 Set-ADUser -Instance $adoUser }
As usual, make sure that you know what you’re doing, and test this out on a test domain first with a few test objects. I am not responsible if you hose everything under the sun.