Home > OS >  powershell to get exact date for passwordlastset
powershell to get exact date for passwordlastset

Time:04-06

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!

CodePudding user response:

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 }

CodePudding user response:

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 $daysLeft to control the remaining threshold until expiry.
  • Note that [DateTime]::FromFileTime is required to transpose the value of
    msDS-UserPasswordExpiryTimeComputed from the file-time format it is stored in AD as to a workable DateTime object.
  • You can define the account as a sAMAccountName or in Universal 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.

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.

  • Related