'powershell to get exact date for passwordlastset
I'm working on scripts which send emails to users 14, 10, 7, 3 days before password expiring. Password expires in 60 days.
If I set like below it works for accounts with 3 and less days to expiring. I don't want accounts with 2 days, 1 day, etc.
$ExpiringUsers = $AdUsers | where PasswordLastSet -lt (get-date).AddDays(-57)
If I set like below it doesn't work at all
$ExpiringUsers = $AdUsers | where PasswordLastSet -eq (get-date).AddDays(-57)
How to set equal 3 days not more not less.
Thanks!
Solution 1:[1]
You need to define and filter by a time range, for example, set equal 3 days not more not less would be like this:
$start = [datetime].AddDays(-3) # => April 2 at 12:00 AM
$finish = [datetime].AddDays(-2) # => April 3 at 12:00 AM
# Note `-lt $finish` instead of `-le $finish`
$AdUsers | Where-Object { $_.PasswordLastSet -ge $start -and $_.PasswordLastSet -lt $finish }
Solution 2:[2]
A better approach is to use msDS-UserPasswordExpiryTimeComputed for checking how long until the account credential expires:
$serviceAccounts =
'[email protected]',
'[email protected]
$daysLeft = 20
$expiringAccounts = ( $serviceAccounts | Foreach-Object {
Get-AdUser -Filter "(UserPrincipalName -eq '$_' -Or sAMAccountName -eq '$_' ) -And ( PasswordNeverExpires -eq 'false' )" -Properties msDS-UserPasswordExpiryTimeComputed |
Where-Object { ( New-TimeSpan -Start $currentDate -End ( [DateTime]::FromFileTime( $_.'msDS-UserPasswordExpiryTimeComputed' ) ) ).Days -le $daysLeft }
} )
- As written, this code will gather the accounts expiring within 20 days. Adjust
$daysLeftto control the remaining threshold until expiry. - Note that
[DateTime]::FromFileTimeis required to transpose the value ofmsDS-UserPasswordExpiryTimeComputedfrom the file-time format it is stored in AD as to a workableDateTimeobject. - You can define the account as a
sAMAccountNameor inUniversal Principal Name (UPN)format. - This also exemplifies using AD filters in order to have AD return only the objects you need for this query, minimizing the local processing performed with
Where-Object.- The notable exception is
msDS-UserPasswordExpiryTimeComputed; because it is a Constructed Attribute within Active Directory, neither AD filters or LDAP filters can evaluate it and so this must be done via additional local processing. - Here is an answer I have also written which goes into deeper detail on using the AD filter syntax.
- The notable exception is
What is wrong with PasswordLastSet for checking credential expiration if you know the account's lifecycle?
The problem with checking PasswordLastSet is that, while it works, if the threshold until expiry changes on the Active Directory side, your script will need to be updated or it will incorrectly identify accounts whose credential is set to expire soon. It also becomes more difficult to track which accounts are beholden to different lifecycles in environments where not all accounts are beholden to the same security policies.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Santiago Squarzon |
| Solution 2 |
