Password Expiry Notification after comparing with Fine Grained Password Policy

Hi @Olaf , you’ve helped me on this one almost a month back, but now I have an error in this output, could you please correct it ? Many thanks in advance.

$WarningDays = 14
$passwordsetdate = (get-aduser $ADUser -properties * | foreach { $_.PasswordLastSet })
$maxPasswordAge = ($PasswordPol).MaxPasswordAge
$expireson = $passwordsetdate + $maxPasswordAge
$smtpServer="<SMTPSERVER>"
$from = "<FROMMAILID>"
$link1 = "<LINK1GOESHERE>"
$link2 = "<LINK2GOESHERE>"
$PasswordExpireLimitDate = (Get-Date).Date.AddDays($WarningDays)
$SearchBase = 'DISTINGUISHEDPATHGOESHERE'
$ADUserList = Get-ADUser -SearchBase $SearchBase -Filter "Enabled -eq '$true' -and PasswordNeverExpires -eq '$False'" -Properties 'DisplayName', 'msDS-UserPasswordExpiryTimeComputed', 'emailaddress'

$bodyTemplate =
@"
Dear $($ADUser.Name),
<p>  Your password will expire on $ExpiresOn. It's time to reset the Password. <br>
    <p> To reset your password from your Industry computer, press Ctrl+Alt+Delete and choose Change Password. <br>
    <p> If you are traveling or working from a office location, please ensure that you have connected to the VPN application before attempting to reset your password. <br>
    <p> If you do not have access to an office Computer, please visit $link1 and submit an incident. If you have forgotten your password, $link2 . <br>
<p> <br>
    <b><font color=red>Please note that replies to this email will not be answered</font></b>
    <p><br>Have a great day, <br>
    </P> Service Desk
</P>DL-HERE"

"@

foreach ($ADUser in $ADUserList) {

    $PasswordExpireDate = [datetime]::FromFileTime($($ADUser.'msDS-UserPasswordExpiryTimeComputed')).Date
    if ($PasswordExpireDate -lt $PasswordExpireLimitDate) {
        $ExpireDaySpan = New-TimeSpan -Start (Get-Date).Date -End $PasswordExpireDate

        $SendMailmessageParams = @{
            smtpServer = $smtpServer
            from       = $from
            to         = $ADUser.emailaddress
            subject    = "Password will expire in $($ExpireDaySpan.TotalDays) days"
            body       = $bodyTemplate
            bodyasHTML = $true
            priority   = 'High'
        }
        Send-Mailmessage @SendMailmessageParams
    }
}

##### Error Message ######
Cannot convert argument "1", with value: "", for "op_Addition" to type "System.TimeSpan": "Cannot convert null to type "System.TimeSpan"."
At line:4 char:1
+ $expireson = $passwordsetdate + $maxPasswordAge
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodException
    + FullyQualifiedErrorId : MethodArgumentConversionInvalidCastArgument


You can’t add a TimeSpan object and a DateTime object. MaxPasswordAge is a TimeSpan so you either need to get the Days property with Select-Object, or use dot notation, and then use the AddDays() method.

$maxPasswordAge = ($PasswordPol).MaxPasswordAge | Select-Object -ExpandProperty Days
$expiresOn = $passwordSetDate.AddDays($maxPasswordAge)

or

$maxPasswordAge = ($PasswordPol).MaxPasswordAge
$expiresOn = $passwordSetDate.AddDays($maxPasswordAge.Days)
1 Like

Thanks a million matt-bloomfield.

It worked… I have used the second portion in your reply and it gave the correct output. Thanks again a million times.

Regards,
Shyam.

1 Like