AD Password Expiry Notice Script Need Help!

i’m with @neemobeer on this one. Firstly, there is a baked in notification within AD/GPO that lets users know their password is expiring in two weeks. People at my work get them all the time.

Secondly, you gotta format code when you’re sharing it online. There’s a “preformatted text” button in the toolbar within the plus symbol that lets you create a code block to put code in. Guide to Posting Code . Please use that.

Lastly, on the line where you define your filter for Get-AdUser you’re comparing PasswordLastSet to a variable named $expirydate containing a datetime object. Theoretically this should work right? Comparing two datetime objects. However, PasswordLastSet is a computed property that I don’t believe can be leveraged within a filter argument, but maybe I’m wrong on that. What I’ve done in the past is get the users from AD with the msds-userpasswordexpirytimecomputed property so I can get their literal expiration date without doing any calculations myself, then filter with Where-Object based on that property.
Something like this for the setup

$GetADUserArgs = [ordered]@{
    Filter = "Enabled -eq 'TRUE' -and PasswordNeverExpires -eq 'FALSE'"
    Server = $DomainName
    Properties = @('Displayname','Passwordlastset','msDS-userpasswordexpirytimecomputed','PasswordNeverExpires','PasswordExpired')
    ErrorAction = "Stop"
    SearchBase = $null
}

$SelObjArgs = [ordered]@{
    Property = @(@{Name="User";Expression={$_.UserPrincipalName}},
                "DisplayName",
                "PasswordLastSet",
                @{Name="ExpiryDate";Expression={[datetime]::fromfiletime($_."msds-userpasswordexpirytimecomputed")}},
                'PasswordNeverExpires',
                'PasswordExpired',
                'Enabled'
    )
}

And then with those defined we can go out to AD and get users. Here $OUs is defined beforehand as an array of specific places to check.

$UsersToCheck = Foreach ($OU in $OUs) {
    $GetADUserArgs.SearchBase = $OU
    try {
        Get-ADUser @GetADUserArgs | Select-Object @SelObjArgs
    } catch {
        Write-Error $Error[0]
    }
}

$UsersToNotify = Foreach ($User in $UsersToCheck) {
    if ($null -ne $User.PasswordLastSet -and $User.PasswordExpired -eq $false) {
        if ($User.ExpiryDate -le (Get-Date).AddDays($Threshold)) {
            $User
        }
    }
}
1 Like