Password Expiry Date as Emails

Hi Champs,

Could you please help me with this? I am trying to find the password expiry date of users in an OU and send the report as email. I have the script as two parts mentioned below, it works fine as two different sections but when I try run it as one script it fails with a lot of errors.

Could you please help? Thanks in advance.

#########################################################

Configurable Variables

$smtpServer=“SMTPSERVERNAME”

$expireindays = 14
$from = “USERID”
$date = Get-Date -format ddMMyyyy

###################################################################################################################

Get Users From AD who are Enabled, Passwords Expire and are Not Currently Expired

Import-Module ActiveDirectory
$users = Get-ADUser -filter {Enabled -eq $True -and PasswordNeverExpires -eq $False} -SearchBase ‘DNOUPATH’ –Properties “DisplayName”, “msDS-UserPasswordExpiryTimeComputed” |
Select-Object -Property “Displayname”,@{Name=“ExpiryDate”;Expression={[datetime]::FromFileTime($_.“msDS-UserPasswordExpiryTimeComputed”)}}

#####UNTIL THE ABOVE PART IT WORKS, BUT WHEN I JOIN IT TO THE NEXT SECTION IT FAILS############

Process Each User for Password Expiry

foreach ($user in $users)
{
$Name = (Get-ADUser $user | foreach { $.Name})
$emailaddress = $user.emailaddress
$passwordSetDate = (get-aduser $user -properties * | foreach { $
.PasswordLastSet })
$PasswordPol = (Get-AduserResultantPasswordPolicy $user)
# Check for Fine Grained Password
if (($PasswordPol) -ne $null)
{
$maxPasswordAge = ($PasswordPol).MaxPasswordAge
}

$expireson = $passwordsetdate + $maxPasswordAge
$today = (get-date)
$daystoexpire = (New-TimeSpan -Start $today -End $Expireson).Days
    
# Set Greeting based on Number of Days to Expiry.

# Check Number of Days to Expiry
$messageDays = $daystoexpire

if (($messageDays) -ge "1")
{
    $messageDays = "in " + "$daystoexpire" + " days"
}
else
{
    $messageDays = "today."
}

# Email Subject Set Here
$subject="EMAILSUBJECT $messageDays"

# Email Body Set Here
$body ="
Dear $name,

EMAIL BODY"

# If a user has no email address listed
if (($emailaddress) -eq $null)
{
    $emailaddress = $testRecipient    
}# End No Valid Email

# Send Email Message
if (($daystoexpire -ge "0") -and ($daystoexpire -lt $expireindays))
{
    # Send Email Message
    Send-Mailmessage -smtpServer $smtpServer -from $from -to $emailaddress -subject $subject -body $body -bodyasHTML -priority High  

} # End Send Message

} # End User Processing

End

######THE ABOVE IS THE SECOND PART OF THE SCRIPT#########

Thanks again,
Syam.

Your code is incomplete because you did not format it correctly as code. :wink:

When you post code, please place your cursor on an empty line, click the preformatted text button ( </> ) and then paste our code. :point_up_2:t4:

When you get error messages you should post them as well - completely - formatted as code as well. Error messages are important!!

Thanks in advance.

Hey Olaf,
Hope you are doing great !

Thank you for looking into this.
Sorry I didn’t know how to use the </> button. Trying it once again now.

The complete code is here:

##################################################

# Configurable Variables
$smtpServer="SMTPSERVERNAME"

$expireindays = 14
$from = "USERID"
$date = Get-Date -format ddMMyyyy
$link1 = "URL1"
$link2 = "URL2"

#
###################################################################################################################

# Get Users From AD who are Enabled, Passwords Expire and are Not Currently Expired
Import-Module ActiveDirectory
$users = Get-ADUser -filter {Enabled -eq $True -and PasswordNeverExpires -eq $False} -SearchBase 'DNOUPATH' –Properties "DisplayName", "msDS-UserPasswordExpiryTimeComputed" |
Select-Object -Property "Displayname",@{Name="ExpiryDate";Expression={[datetime]::FromFileTime($_."msDS-UserPasswordExpiryTimeComputed")}}

# Process Each User for Password Expiry
foreach ($user in $users)
{
    $Name = (Get-ADUser $user | foreach { $_.Name})
    $emailaddress = $user.emailaddress
    $passwordSetDate = (get-aduser $user -properties * | foreach { $_.PasswordLastSet })
    $PasswordPol = (Get-AduserResultantPasswordPolicy $user)
    # Check for Fine Grained Password
    if (($PasswordPol) -ne $null)
    {
        $maxPasswordAge = ($PasswordPol).MaxPasswordAge
    }
  
    $expireson = $passwordsetdate + $maxPasswordAge
    $today = (get-date)
    $daystoexpire = (New-TimeSpan -Start $today -End $Expireson).Days
        
    # Set Greeting based on Number of Days to Expiry.

    # Check Number of Days to Expiry
    $messageDays = $daystoexpire

    if (($messageDays) -ge "1")
    {
        $messageDays = "in " + "$daystoexpire" + " days"
    }
    else
    {
        $messageDays = "today."
    }

    # Email Subject Set Here
    $subject="EMAILSUBJECT $messageDays"
  
    # Email Body Set Here
    $body ="
    Dear $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>
    <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>DL@COMPANY.COM"
    # If a user has no email address listed
    if (($emailaddress) -eq $null)
    {
        $emailaddress = $testRecipient    
    }# End No Valid Email

    # Send Email Message
    if (($daystoexpire -ge "0") -and ($daystoexpire -lt $expireindays))
    {
        # Send Email Message
        Send-Mailmessage -smtpServer $smtpServer -from $from -to $emailaddress -subject $subject -body $body -bodyasHTML -priority High  

    } # End Send Message
    
} # End User Processing

# End
#######################################################


The error messages is here (sorry its too lengthy):

Get-ADUser : Cannot validate argument on parameter 'Identity'. The Identity property on the argument is null or empty.
At line:22 char:25
+     $Name = (Get-ADUser $user | foreach { $_.Name})
+                         ~~~~~
    + CategoryInfo          : InvalidData: (:) [Get-ADUser], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.ActiveDirectory.Management.Commands.GetADUser
 
Get-ADUser : Cannot validate argument on parameter 'Identity'. The Identity property on the argument is null or empty.
At line:24 char:36
+     $passwordSetDate = (get-aduser $user -properties * | foreach { $_ ...
+                                    ~~~~~
    + CategoryInfo          : InvalidData: (:) [Get-ADUser], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.ActiveDirectory.Management.Commands.GetADUser
 
Get-AduserResultantPasswordPolicy : Object reference not set to an instance of an object.
At line:25 char:21
+     $PasswordPol = (Get-AduserResultantPasswordPolicy $user)
+                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (Microsoft.Activ...nagement.ADUser:ADUser) [Get-ADUserResultantPasswordPolicy], NullReferenceException
    + FullyQualifiedErrorId : ActiveDirectoryCmdlet:System.NullReferenceException,Microsoft.ActiveDirectory.Management.Commands.GetADUserResultantPasswordPolicy
 
Get-ADUser : Cannot validate argument on parameter 'Identity'. The Identity property on the argument is null or empty.
At line:22 char:25
+     $Name = (Get-ADUser $user | foreach { $_.Name})
+                         ~~~~~
    + CategoryInfo          : InvalidData: (:) [Get-ADUser], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.ActiveDirectory.Management.Commands.GetADUser
 
Get-ADUser : Cannot validate argument on parameter 'Identity'. The Identity property on the argument is null or empty.
At line:24 char:36
+     $passwordSetDate = (get-aduser $user -properties * | foreach { $_ ...
+                                    ~~~~~
    + CategoryInfo          : InvalidData: (:) [Get-ADUser], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.ActiveDirectory.Management.Commands.GetADUser
 
Get-AduserResultantPasswordPolicy : Object reference not set to an instance of an object.
At line:25 char:21
+     $PasswordPol = (Get-AduserResultantPasswordPolicy $user)
+                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (Microsoft.Activ...nagement.ADUser:ADUser) [Get-ADUserResultantPasswordPolicy], NullReferenceException
    + FullyQualifiedErrorId : ActiveDirectoryCmdlet:System.NullReferenceException,Microsoft.ActiveDirectory.Management.Commands.GetADUserResultantPasswordPolicy
 
Get-ADUser : Cannot validate argument on parameter 'Identity'. The Identity property on the argument is null or empty.
At line:22 char:25
+     $Name = (Get-ADUser $user | foreach { $_.Name})
+                         ~~~~~
    + CategoryInfo          : InvalidData: (:) [Get-ADUser], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.ActiveDirectory.Management.Commands.GetADUser
 
Get-ADUser : Cannot validate argument on parameter 'Identity'. The Identity property on the argument is null or empty.
At line:24 char:36
+     $passwordSetDate = (get-aduser $user -properties * | foreach { $_ ...
+                                    ~~~~~
    + CategoryInfo          : InvalidData: (:) [Get-ADUser], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.ActiveDirectory.Management.Commands.GetADUser
 
Get-AduserResultantPasswordPolicy : Object reference not set to an instance of an object.
At line:25 char:21
+     $PasswordPol = (Get-AduserResultantPasswordPolicy $user)
+                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (Microsoft.Activ...nagement.ADUser:ADUser) [Get-ADUserResultantPasswordPolicy], NullReferenceException
    + FullyQualifiedErrorId : ActiveDirectoryCmdlet:System.NullReferenceException,Microsoft.ActiveDirectory.Management.Commands.GetADUserResultantPasswordPolicy
 
Get-ADUser : Cannot validate argument on parameter 'Identity'. The Identity property on the argument is null or empty.
At line:22 char:25
+     $Name = (Get-ADUser $user | foreach { $_.Name})
+                         ~~~~~
    + CategoryInfo          : InvalidData: (:) [Get-ADUser], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.ActiveDirectory.Management.Commands.GetADUser
 
Get-ADUser : Cannot validate argument on parameter 'Identity'. The Identity property on the argument is null or empty.
At line:24 char:36
+     $passwordSetDate = (get-aduser $user -properties * | foreach { $_ ...
+                                    ~~~~~
    + CategoryInfo          : InvalidData: (:) [Get-ADUser], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.ActiveDirectory.Management.Commands.GetADUser
 
Get-AduserResultantPasswordPolicy : Object reference not set to an instance of an object.
At line:25 char:21
+     $PasswordPol = (Get-AduserResultantPasswordPolicy $user)
+                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (Microsoft.Activ...nagement.ADUser:ADUser) [Get-ADUserResultantPasswordPolicy], NullReferenceException
    + FullyQualifiedErrorId : ActiveDirectoryCmdlet:System.NullReferenceException,Microsoft.ActiveDirectory.Management.Commands.GetADUserResultantPasswordPolicy
 
Get-ADUser : Cannot validate argument on parameter 'Identity'. The Identity property on the argument is null or empty.
At line:22 char:25
+     $Name = (Get-ADUser $user | foreach { $_.Name})
+                         ~~~~~
    + CategoryInfo          : InvalidData: (:) [Get-ADUser], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.ActiveDirectory.Management.Commands.GetADUser
 
Get-ADUser : Cannot validate argument on parameter 'Identity'. The Identity property on the argument is null or empty.
At line:24 char:36
+     $passwordSetDate = (get-aduser $user -properties * | foreach { $_ ...
+                                    ~~~~~
    + CategoryInfo          : InvalidData: (:) [Get-ADUser], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.ActiveDirectory.Management.Commands.GetADUser
 
Get-AduserResultantPasswordPolicy : Object reference not set to an instance of an object.
At line:25 char:21
+     $PasswordPol = (Get-AduserResultantPasswordPolicy $user)
+                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (Microsoft.Activ...nagement.ADUser:ADUser) [Get-ADUserResultantPasswordPolicy], NullReferenceException
    + FullyQualifiedErrorId : ActiveDirectoryCmdlet:System.NullReferenceException,Microsoft.ActiveDirectory.Management.Commands.GetADUserResultantPasswordPolicy
 
Get-ADUser : Cannot validate argument on parameter 'Identity'. The Identity property on the argument is null or empty.
At line:22 char:25
+     $Name = (Get-ADUser $user | foreach { $_.Name})
+                         ~~~~~
    + CategoryInfo          : InvalidData: (:) [Get-ADUser], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.ActiveDirectory.Management.Commands.GetADUser
 
Get-ADUser : Cannot validate argument on parameter 'Identity'. The Identity property on the argument is null or empty.
At line:24 char:36
+     $passwordSetDate = (get-aduser $user -properties * | foreach { $_ ...
+                                    ~~~~~
    + CategoryInfo          : InvalidData: (:) [Get-ADUser], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.ActiveDirectory.Management.Commands.GetADUser
 
Get-AduserResultantPasswordPolicy : Object reference not set to an instance of an object.
At line:25 char:21
+     $PasswordPol = (Get-AduserResultantPasswordPolicy $user)
+                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (Microsoft.Activ...nagement.ADUser:ADUser) [Get-ADUserResultantPasswordPolicy], NullReferenceException
    + FullyQualifiedErrorId : ActiveDirectoryCmdlet:System.NullReferenceException,Microsoft.ActiveDirectory.Management.Commands.GetADUserResultantPasswordPolicy
 
Get-ADUser : Cannot validate argument on parameter 'Identity'. The Identity property on the argument is null or empty.
At line:22 char:25
+     $Name = (Get-ADUser $user | foreach { $_.Name})
+                         ~~~~~
    + CategoryInfo          : InvalidData: (:) [Get-ADUser], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.ActiveDirectory.Management.Commands.GetADUser
 
Get-ADUser : Cannot validate argument on parameter 'Identity'. The Identity property on the argument is null or empty.
At line:24 char:36
+     $passwordSetDate = (get-aduser $user -properties * | foreach { $_ ...
+                                    ~~~~~
    + CategoryInfo          : InvalidData: (:) [Get-ADUser], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.ActiveDirectory.Management.Commands.GetADUser
 
Get-AduserResultantPasswordPolicy : Object reference not set to an instance of an object.
At line:25 char:21
+     $PasswordPol = (Get-AduserResultantPasswordPolicy $user)
+                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (Microsoft.Activ...nagement.ADUser:ADUser) [Get-ADUserResultantPasswordPolicy], NullReferenceException
    + FullyQualifiedErrorId : ActiveDirectoryCmdlet:System.NullReferenceException,Microsoft.ActiveDirectory.Management.Commands.GetADUserResultantPasswordPolicy
 
Get-ADUser : Cannot validate argument on parameter 'Identity'. The Identity property on the argument is null or empty.
At line:22 char:25
+     $Name = (Get-ADUser $user | foreach { $_.Name})
+                         ~~~~~
    + CategoryInfo          : InvalidData: (:) [Get-ADUser], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.ActiveDirectory.Management.Commands.GetADUser
 
Get-ADUser : Cannot validate argument on parameter 'Identity'. The Identity property on the argument is null or empty.
At line:24 char:36
+     $passwordSetDate = (get-aduser $user -properties * | foreach { $_ ...
+                                    ~~~~~
    + CategoryInfo          : InvalidData: (:) [Get-ADUser], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.ActiveDirectory.Management.Commands.GetADUser
 
Get-AduserResultantPasswordPolicy : Object reference not set to an instance of an object.
At line:25 char:21
+     $PasswordPol = (Get-AduserResultantPasswordPolicy $user)
+                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (Microsoft.Activ...nagement.ADUser:ADUser) [Get-ADUserResultantPasswordPolicy], NullReferenceException
    + FullyQualifiedErrorId : ActiveDirectoryCmdlet:System.NullReferenceException,Microsoft.ActiveDirectory.Management.Commands.GetADUserResultantPasswordPolicy

You query your AD for users 3 times. Once actually for all users and twice for each individual user. And once again for the resultant password policy for each user. That’s an enormous waste of time and resources and some stress for your AD. It’s enough to query your AD once and use this data for the rest of the task.

Something like this should be enough actually:

$WarningDays = 14
$PasswordExpireLimitDate = (Get-Date).Date.AddDays($WarningDays)

$SearchBase = 'DNOUPATH'
$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 $($PasswordExpireDate.ToLongDateString()). 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>
<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>DL@COMPANY.COM
"@

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
    }
}

Or at least it should give you a little cleaner starting point.

2 Likes

Hey my dear Olaf,

"Superman is not my hero,
but you are;

Spiderman is not awesome,
but you are;

You just brighten my day,
a box of chocolates and love for you…"

Thanks a ton Olaf. It worked like a charm.
Syam.