Shadowgroups and sending mail on specific days before password expires
I have no scripting skills, so please be patient with me :-)
We have FGPP in place in combination with shadow groups.
Used http://www.sole.dk/active-directory-shadow-group-script-will-let-you-spend-less-time-on-updating-group-memberships/
to create the shadow groups. Works great.

But now my manager wants to send mail to users, 14, 7, 3, 2, and 1 day before password expires.
I found a script here: http://gallery.technet.microsoft.com/Password-Expiry-Email-177c3e27#content

But I need to edit the script.

Questions 1:
I've created three shadowgroups, and want to query these groups.
Do I edit the script like this:

# Get Users From AD who are Enabled, Passwords Expire and are Not Currently Expired
Import-Module ActiveDirectory
$Group = get-ADGroupmember -identity groupname1, groupname2, groupname3 -filter
* -properties Name, PasswordNeverExpires, PasswordExpired, PasswordLastSet,
EmailAddress |where {$_.Enabled -eq "True"} | where { $_.PasswordNeverExpires
-eq $false } | where { $_.passwordexpired -eq $false }
$maxPasswordAge = (Get-ADDefaultDomainPasswordPolicy).MaxPasswordAge
# Process Each User
for Password Expiry
foreach ($user in $Group)

Question 2:
To send mail on the specific days before password expire, do I edit the script like this:
# Send Email Message
    if (($daystoExpire) -eq  (("14") -or (("7") -or (("3") -or (("2") -or ("1")))

I think the syntax is probably wrong.

Question 3:
Do I need to edit other lines in the script, or is there another (better) script on the net?

Thanks

September 16th, 2014 5:03am

I see you also posted where the script was posted in the gallery, here's some additional info.  Not in order...

Q2 - do it like this:

$expires = @(14,7,3,2,1)
If ($expires -contains $daystoexpire)

There was a lot wrong with how you were trying to do it, the method I just posted would be much better.

For Q1, I don't agree with the author of the script in the way that he told you to do it, although the way you've got it won't work because get-adgroupmember doesn't have a filter parameter and you can't supply an array as an identity parameter, AND Get-ADGroupMember doesn't expose the attributes you want to work with.  There are a number of ways you can get around those limitations, but there's a huge performance hit.  As much as I don't like using 3rd party tools when it isn't necessary, in this case you might be better of with the Quest AD cmdlets and the Get-QADuser cmdlet, which I believe would allow you to work with the memberof attribute in your filter:

http://wiki.powergui.org/index.php/Get-QADUser

I can't really test with that right now so can't give you much more specific advice about Get-QADUser, but what I can tell you is you will probably have orders of magnitude better performance using that cmdlet than to try to combine get-adgroupmember and get-aduser to arrive at the subset of users you want to target. 

Free Windows Admin Tool Kit Click here and download it now
September 16th, 2014 10:02am

Hi Biga_b,

Im writing to just check in to see if the suggestions were helpful. If you need further help, please feel free to reply this post directly so we will be notified to follow it up.

If you have any feedback on our support, please click here.

Best Regards,

Anna Wang

TechNet Community Support

September 23rd, 2014 11:50am

Sorry for my late response. Because of workshops and other stuff, I was not able to test the script. Now I have a few days to test it in my test environment. I tried editing the script, but get a lot of illegal characters and Missing closing '}' in statement block errors. I just don't have the powershell knowledge.

I also like to avoid third party tools, but like Rhys said, maybe the best thing to do is to use  Quest AD cmdlets. But first I want to have a working script.

I don' t use AD Default Domain Password Policy, but Fine Grained Password Policy. So I can delete the part in the script about Default Domain PW Policy. Right?

I added or edited the lines in bold.

#################################################################################################################
#
# Version 1.1 May 2014
# Robert Pearman (WSSMB MVP)
# TitleRequired.com
# Script to Automated Email Reminders when Users Passwords due to Expire.
#
# Requires: Windows PowerShell Module for Active Directory
#
# For assistance and ideas, visit the TechNet Gallery Q&A Page. http://gallery.technet.microsoft.com/Password-Expiry-Email-177c3e27/view/Discussions#content
#
##################################################################################################################
# Please Configure the following variables....
$smtpServer="ex2013.stibbeota.nl"
$expireindays = 15
$from = "StibbeOta Administrator <support@stibbeota.nl>"
$logging = "Enabled" # Set to Disabled to Disable Logging
$logFile = "<log file path>" # ie. c:\mylog.csv
$testing = "Enabled" # Set to Disabled to Email Users
$testRecipient = "testuser@stibbeota.nl"
$date = Get-Date -format ddMMyyyy
#
###################################################################################################################

# Check Logging Settings
if (($logging) -eq "Enabled")
{
    # Test Log File Path
    $logfilePath = (Test-Path $logFile)
    if (($logFilePath) -ne "True")
    {
        # Create CSV File and Headers
        New-Item $logfile -ItemType File
        Add-Content $logfile "Date,Name,EmailAddress,DaystoExpire,ExpiresOn"
    }
} # End Logging Check

# Get Users From AD who are Enabled, Passwords Expire and are Not Currently Expired
Import-Module ActiveDirectory
$users = get-aduser -filter * -properties Name, PasswordNeverExpires, PasswordExpired, PasswordLastSet, EmailAddress |where {$_.Enabled -eq "True"} | where { $_.PasswordNeverExpires -eq $false } | where { $_.passwordexpired -eq $false }
$maxPasswordAge = (Get-ADDefaultDomainPasswordPolicy).MaxPasswordAge

# Process Each User for Password Expiry
$groups = "PWNotification1","PWNotification2"
foreach ($group in $groups)
{
$members = Get-AdGroupMember $group
foreach ($member in $members)
{

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="Your password will expire $messageDays"
 
    # Email Body Set Here, Note You can use HTML, including Images.
    $body ="
    Dear $name,
    <p> Your Password will expire $messageDays.<br>
    To change your password on a PC press CTRL ALT Delete and chose Change Password <br>
    <p>Thanks, <br>
    </P>"

  
    # If Testing Is Enabled - Email Administrator
    if (($testing) -eq "Enabled")
    {
        $emailaddress = $testRecipient
    } # End Testing

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

    # Send Email Message
    if (($daystoexpire) -eq ((1) or (7) or (10) or (14))
    {....}
   
         # If Logging is Enabled Log Details
        if (($logging) -eq "Enabled")
        {
            Add-Content $logfile "$date,$Name,$emailaddress,$daystoExpire,$expireson"
        }
        # 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

Thanks

Free Windows Admin Tool Kit Click here and download it now
October 1st, 2014 12:32pm

Hi,

Here's the script I put together for expiration notification emails:

Import-Module ActiveDirectory

$users = Get-ADUser -Filter * -Properties PasswordLastSet,EmailAddress -SearchBase 'OU=Your Users,DC=domain,DC=com' | ForEach {

    If ($_.PasswordLastSet -and $_.EmailAddress -and $_.GivenName -and $_.Surname) {

        If ($_.DistinguishedName -notlike '*,OU=System,*' -and $_.DistinguishedName -notlike '*,OU=Administrator,*' -and $_.DistinguishedName -notlike '*,OU=Shared Resources,*' -and $_.SamAccountName -ne 'thebosswhoshouldnotbenotified') {

            $passwordAge = ((Get-Date) - $_.PasswordLastSet).Days

            If ($passwordAge -ge 106) {

                If (120 - $passwordAge -ge 0) {

                    $props = @{
                        Name = $_.Name
                        GivenName = $_.GivenName
                        Surname = $_.Surname
                        Username = $_.SamAccountName
                        EmailAddress = $_.EmailAddress
                        PasswordLastSet = $_.PasswordLastSet
                        PasswordExpiresOn = (Get-Date $_.PasswordLastSet).AddDays(120)
                        DaysRemaining = 120 - $passwordAge
                    }

                    New-Object PsObject -Property $props

                }

            }

        }

    }

} | Sort Name

foreach ($user in $users) {

    $daysLeft = $user.DaysRemaining

    $emailBody = @"
Hello $($user.GivenName),

IMPORTANT REMINDER: Your network password will be expiring in $daysLeft days ($($user.PasswordExpiresOn.DateTime)).

Please change your password at your earliest convenience.

Procedure:
1 - Press Control+Alt+Delete on your keyboard (or Control+Alt+End if connected via VPN).
2 - Select 'Change a password...'.
3 - Type your current password and your new password twice.
4 - Press Enter or click the arrow button. 

If you have any questions, please contact the helpdesk: helpdesk@domain.com

Thank you.

IT Department
"@

    If ($daysLeft -eq 14 -or $daysLeft -eq 10 -or $daysLeft -le 7) {
    
        Send-MailMessage -To $user.EmailAddress -From DoNotReply@domain.com -Subject 'Password Expiration Notification' -Body $emailBody -SmtpServer smtp.domain.com -Bcc you@domain.com

    }

}

Send-MailMessage -To you@domain.com -From donotreply@domain.com -Subject 'Password Expiration Notification Script Complete' -Body 'Script completed' -SmtpServer smtp.domain.com

Adjust the If ($daysLeft -eq .....) statement to meet your requirements. Currently it sends on 14, 10, and anything less than or equal to 7.

I run this as a scheduled task each day at noon.

October 1st, 2014 12:52pm

Hi Biga_b,

Any Update on this issue?

If there is anything else regarding this script, please feel free to post bacK.

Best Regards,

Anna Wang

Free Windows Admin Tool Kit Click here and download it now
October 6th, 2014 6:40am

Thanks for the script mike, but I didn't use it because I like the "test mode" option in the script I was testing. Also I use FGPP based on "shadow" groups, so I'm not sure if I can use you're script.

I have been testing the first script, and in "test mode" I got it working. I have 6 accounts in my test environment with different "$daytoexpire" values, and I do get 6 e-mails on the test recipient mailbox.

But if I disable $Testing, I get the following errors:

Send-MailMessage : Cannot validate argument on parameter 'To'. The argument is null, empty, or an element of the argument collection contains a null value. Supply a collection that does not contain any null values and then try the
command again.
At C:\Untitled3.ps1:121 char:65
+         Send-Mailmessage -smtpServer $smtpServer -from $from -to <<<<  $emailaddress -subject $subject -body $body -bodyasHTML -priority High 
    + CategoryInfo          : InvalidData: (:) [Send-MailMessage], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.SendMailMessage

What am I missing??

The script:

#################################################################################################################
# 
# Version 1.1 May 2014
# Robert Pearman (WSSMB MVP)
# TitleRequired.com
# Script to Automated Email Reminders when Users Passwords due to Expire.
#
# Requires: Windows PowerShell Module for Active Directory
#
# For assistance and ideas, visit the TechNet Gallery Q&A Page. http://gallery.technet.microsoft.com/Password-Expiry-Email-177c3e27/view/Discussions#content
#
##################################################################################################################
# Please Configure the following variables....
$smtpServer='ex2013.stibbeota.nl'
$expireindays = 15
$from = 'Stibbe Helpdesk <DoNotReply@Stibbe.com>'
$logging = "Enabled" # Set to Disabled to Disable Logging
$logFile = "c:\mylog.csv" # ie. c:\mylog.csv
$testing = 'disabled' # Set to Disabled to Email Users
$testRecipient = 'test.user@stibbeota.nl'
$date = Get-Date -format ddMMyyyy
#
###################################################################################################################

# Check Logging Settings
if (($logging) -eq "Enabled")
{
    # Test Log File Path
    $logfilePath = (Test-Path $logFile)
    if (($logFilePath) -ne "True")
    {
        # Create CSV File and Headers
        New-Item $logfile -ItemType File
        Add-Content $logfile "Date,Name,EmailAddress,DaystoExpire,ExpiresOn"
    }
} # End Logging Check

# Get Users From AD who are Enabled, Passwords Expire and are Not Currently Expired
Import-Module ActiveDirectory
$users = get-aduser -filter * -properties Name, PasswordNeverExpires, PasswordExpired, PasswordLastSet, EmailAddress |where {$_.Enabled -eq "True"} | where { $_.PasswordNeverExpires -eq $false } | where { $_.passwordexpired -eq $false }
$maxPasswordAge = (Get-ADDefaultDomainPasswordPolicy).MaxPasswordAge

# Process Each User for Password Expiry
$groups = 'PWNotification1','PWNotification2'
foreach ($group in $groups)
{
    $members = Get-AdGroupMember $group
        foreach ($user in $members)
        {
$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" + " dag(en)."
    }
    else
    {
        $messageDays = "today."
    }

    # Email Subject Set Here
    $subject="Uw wachtwoord zal verlopen $messageDays"
  
    # Email Body Set Here, Note You can use HTML, including Images.
    $body ="
    Beste $name,
    <p> Uw wachtwoord zal verlopen $messageDays <br>
    <p>De minimale eisen waaraan een wachtwoord moet voldoen is op advies van Microsoft als volgt bepaald: <br>
    - Een lengte van minimaal 8 karakters <br>
    - Ten minste drie van de vier verschillende type karakters moeten erin voorkomen (cijfer, hoofdletter, kleine letter en leesteken) <br>
    - Een niet eerder gebruikt wachtwoord (de laatste 3 wachtwoorden worden bewaard) <br>
    - Uw naam mag niet (voor een deel) in het wachtwoord voorkomen <br>
    <p>Met vriendelijke groet, <br>
    <p>ICT Helpdesk <br>
    7721 <br>
    </P>"

   
    # If Testing Is Enabled - Email Administrator
    if (($testing) -eq "Enabled")
    {
        $emailaddress = $testRecipient
    } # End Testing

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

    # Send Email Message

    $expires = @(14,13,12,11,10,7,6,3,2,1)
    If ($expires -contains $daystoexpire)
    
        {
         # If Logging is Enabled Log Details
        if (($logging) -eq "Enabled")
        {
            Add-Content $logfile "$date,$Name,$emailaddress,$daystoExpire,$expireson" 
        }
        # 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
Thanx

October 8th, 2014 12:02pm

This:

   $emailaddress = $user.emailaddress

Should be this:

   $emailaddress = $Name.emailaddress

The $user object wouldn't have an emailaddress property.

Edit:  Actually, I just noticed you are stripping out everything but the Name for $Name.  Then you are querying AD again for one other property.  You should just do one Get-ADUser, collecting all the properties you need, and use that object throughout.  Otherwise your script will take much longer than nece

Free Windows Admin Tool Kit Click here and download it now
October 8th, 2014 12:25pm

I think this should work, you're trying to get the email address from get-adgroupmember it won't give you that property, I've taken out the unnecessary get-aduser calls as well. I haven't been able to test it but it should be closer to what you're after:

#################################################################################################################
# 
# Version 1.1 May 2014
# Robert Pearman (WSSMB MVP)
# TitleRequired.com
# Script to Automated Email Reminders when Users Passwords due to Expire.
#
# Requires: Windows PowerShell Module for Active Directory
#
# For assistance and ideas, visit the TechNet Gallery Q&A Page. http://gallery.technet.microsoft.com/Password-Expiry-Email-177c3e27/view/Discussions#content
#
##################################################################################################################
# Please Configure the following variables....
$smtpServer='ex2013.stibbeota.nl'
$expireindays = 15
$from = 'Stibbe Helpdesk <DoNotReply@Stibbe.com>'
$logging = "Enabled" # Set to Disabled to Disable Logging
$logFile = "c:\mylog.csv" # ie. c:\mylog.csv
$testing = 'disabled' # Set to Disabled to Email Users
$testRecipient = 'test.user@stibbeota.nl'
$date = Get-Date -format ddMMyyyy
#
###################################################################################################################

# Check Logging Settings
if (($logging) -eq "Enabled")
{
    # Test Log File Path
    $logfilePath = (Test-Path $logFile)
    if (($logFilePath) -ne "True")
    {
        # Create CSV File and Headers
        New-Item $logfile -ItemType File
        Add-Content $logfile "Date,Name,EmailAddress,DaystoExpire,ExpiresOn"
    }
} # End Logging Check

# Get Users From AD who are Enabled, Passwords Expire and are Not Currently Expired
Import-Module ActiveDirectory
#$users = get-aduser -filter * -properties Name, PasswordNeverExpires, PasswordExpired, PasswordLastSet, EmailAddress |where {$_.Enabled -eq "True"} | where { $_.PasswordNeverExpires -eq $false } | where { $_.passwordexpired -eq $false }
$maxPasswordAge = (Get-ADDefaultDomainPasswordPolicy).MaxPasswordAge

# Process Each User for Password Expiry
$groups = 'PWNotification1','PWNotification2'
foreach ($group in $groups)
{
    $members = Get-AdGroupMember $group
        foreach ($user in $members)
        {
get-aduser $user -properties name,EmailAddress,PasswordLastSet | Select Name,EmailAddress,PasswordLastSet | %  {


$name = $_.Name
$EmailAddress = $_.EmailAddress
$passwordSetDate = $_.PasswordLastSet 


$PasswordPol = (Get-AduserResultantPasswordPolicy $name)
 
    # 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" + " dag(en)."
    }
    else
    {
        $messageDays = "today."
    }

    # Email Subject Set Here
    $subject="Uw wachtwoord zal verlopen $messageDays"
  
    # Email Body Set Here, Note You can use HTML, including Images.
    $body ="
    Beste $name,
    <p> Uw wachtwoord zal verlopen $messageDays <br>
    <p>De minimale eisen waaraan een wachtwoord moet voldoen is op advies van Microsoft als volgt bepaald: <br>
    - Een lengte van minimaal 8 karakters <br>
    - Ten minste drie van de vier verschillende type karakters moeten erin voorkomen (cijfer, hoofdletter, kleine letter en leesteken) <br>
    - Een niet eerder gebruikt wachtwoord (de laatste 3 wachtwoorden worden bewaard) <br>
    - Uw naam mag niet (voor een deel) in het wachtwoord voorkomen <br>
    <p>Met vriendelijke groet, <br>
    <p>ICT Helpdesk <br>
    7721 <br>
    </P>"

   
    # If Testing Is Enabled - Email Administrator
    if (($testing) -eq "Enabled")
    {
        $emailaddress = $testRecipient
    } # End Testing

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

    # Send Email Message

    $expires = @(14,13,12,11,10,7,6,3,2,1)
    If ($expires -contains $daystoexpire)
    
        {
         # If Logging is Enabled Log Details
        if (($logging) -eq "Enabled")
        {
            Add-Content $logfile "$date,$Name,$emailaddress,$daystoExpire,$expireson" 
        }
        # 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


  • Edited by Braham20 Thursday, October 09, 2014 11:36 AM
October 9th, 2014 2:35pm

Sorry, my fault - I passed $name instead of $user to the get-aduserresultantpasswordpolicy cmdlet try this version.

#################################################################################################################
# 
# Version 1.1 May 2014
# Robert Pearman (WSSMB MVP)
# TitleRequired.com
# Script to Automated Email Reminders when Users Passwords due to Expire.
#
# Requires: Windows PowerShell Module for Active Directory
#
# For assistance and ideas, visit the TechNet Gallery Q&A Page. http://gallery.technet.microsoft.com/Password-Expiry-Email-177c3e27/view/Discussions#content
#
##################################################################################################################
# Please Configure the following variables....
$smtpServer='ex2013.stibbeota.nl'
$expireindays = 15
$from = 'Stibbe Helpdesk <DoNotReply@Stibbe.com>'
$logging = "Enabled" # Set to Disabled to Disable Logging
$logFile = "c:\mylog.csv" # ie. c:\mylog.csv
$testing = 'disabled' # Set to Disabled to Email Users
$testRecipient = 'test.user@stibbeota.nl'
$date = Get-Date -format ddMMyyyy
#
###################################################################################################################

# Check Logging Settings
if (($logging) -eq "Enabled")
{
    # Test Log File Path
    $logfilePath = (Test-Path $logFile)
    if (($logFilePath) -ne "True")
    {
        # Create CSV File and Headers
        New-Item $logfile -ItemType File
        Add-Content $logfile "Date,Name,EmailAddress,DaystoExpire,ExpiresOn"
    }
} # End Logging Check

# Get Users From AD who are Enabled, Passwords Expire and are Not Currently Expired
Import-Module ActiveDirectory
#$users = get-aduser -filter * -properties Name, PasswordNeverExpires, PasswordExpired, PasswordLastSet, EmailAddress |where {$_.Enabled -eq "True"} | where { $_.PasswordNeverExpires -eq $false } | where { $_.passwordexpired -eq $false }
$maxPasswordAge = (Get-ADDefaultDomainPasswordPolicy).MaxPasswordAge

# Process Each User for Password Expiry
$groups = 'PWNotification1','PWNotification2'
foreach ($group in $groups)
{
    $members = Get-AdGroupMember $group
        foreach ($user in $members)
        {
get-aduser $user -properties name,EmailAddress,PasswordLastSet | Select Name,EmailAddress,PasswordLastSet | %  {


$name = $_.Name
$EmailAddress = $_.EmailAddress
$passwordSetDate = $_.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" + " dag(en)."
    }
    else
    {
        $messageDays = "today."
    }

    # Email Subject Set Here
    $subject="Uw wachtwoord zal verlopen $messageDays"
  
    # Email Body Set Here, Note You can use HTML, including Images.
    $body ="
    Beste $name,
    <p> Uw wachtwoord zal verlopen $messageDays <br>
    <p>De minimale eisen waaraan een wachtwoord moet voldoen is op advies van Microsoft als volgt bepaald: <br>
    - Een lengte van minimaal 8 karakters <br>
    - Ten minste drie van de vier verschillende type karakters moeten erin voorkomen (cijfer, hoofdletter, kleine letter en leesteken) <br>
    - Een niet eerder gebruikt wachtwoord (de laatste 3 wachtwoorden worden bewaard) <br>
    - Uw naam mag niet (voor een deel) in het wachtwoord voorkomen <br>
    <p>Met vriendelijke groet, <br>
    <p>ICT Helpdesk <br>
    7721 <br>
    </P>"

   
    # If Testing Is Enabled - Email Administrator
    if (($testing) -eq "Enabled")
    {
        $emailaddress = $testRecipient
    } # End Testing

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

    # Send Email Message

    $expires = @(14,13,12,11,10,7,6,3,2,1)
    If ($expires -contains $daystoexpire)
    
        {
         # If Logging is Enabled Log Details
        if (($logging) -eq "Enabled")
        {
            Add-Content $logfile "$date,$Name,$emailaddress,$daystoExpire,$expireson" 
        }
        # 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

 
  • Marked as answer by Biga_b 23 hours 18 minutes ago
Free Windows Admin Tool Kit Click here and download it now
October 9th, 2014 6:24pm

Sorry, my fault - I passed $name instead of $user to the get-aduserresultantpasswordpolicy cmdlet try this version.

#################################################################################################################
# 
# Version 1.1 May 2014
# Robert Pearman (WSSMB MVP)
# TitleRequired.com
# Script to Automated Email Reminders when Users Passwords due to Expire.
#
# Requires: Windows PowerShell Module for Active Directory
#
# For assistance and ideas, visit the TechNet Gallery Q&A Page. http://gallery.technet.microsoft.com/Password-Expiry-Email-177c3e27/view/Discussions#content
#
##################################################################################################################
# Please Configure the following variables....
$smtpServer='ex2013.stibbeota.nl'
$expireindays = 15
$from = 'Stibbe Helpdesk <DoNotReply@Stibbe.com>'
$logging = "Enabled" # Set to Disabled to Disable Logging
$logFile = "c:\mylog.csv" # ie. c:\mylog.csv
$testing = 'disabled' # Set to Disabled to Email Users
$testRecipient = 'test.user@stibbeota.nl'
$date = Get-Date -format ddMMyyyy
#
###################################################################################################################

# Check Logging Settings
if (($logging) -eq "Enabled")
{
    # Test Log File Path
    $logfilePath = (Test-Path $logFile)
    if (($logFilePath) -ne "True")
    {
        # Create CSV File and Headers
        New-Item $logfile -ItemType File
        Add-Content $logfile "Date,Name,EmailAddress,DaystoExpire,ExpiresOn"
    }
} # End Logging Check

# Get Users From AD who are Enabled, Passwords Expire and are Not Currently Expired
Import-Module ActiveDirectory
#$users = get-aduser -filter * -properties Name, PasswordNeverExpires, PasswordExpired, PasswordLastSet, EmailAddress |where {$_.Enabled -eq "True"} | where { $_.PasswordNeverExpires -eq $false } | where { $_.passwordexpired -eq $false }
$maxPasswordAge = (Get-ADDefaultDomainPasswordPolicy).MaxPasswordAge

# Process Each User for Password Expiry
$groups = 'PWNotification1','PWNotification2'
foreach ($group in $groups)
{
    $members = Get-AdGroupMember $group
        foreach ($user in $members)
        {
get-aduser $user -properties name,EmailAddress,PasswordLastSet | Select Name,EmailAddress,PasswordLastSet | %  {


$name = $_.Name
$EmailAddress = $_.EmailAddress
$passwordSetDate = $_.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" + " dag(en)."
    }
    else
    {
        $messageDays = "today."
    }

    # Email Subject Set Here
    $subject="Uw wachtwoord zal verlopen $messageDays"
  
    # Email Body Set Here, Note You can use HTML, including Images.
    $body ="
    Beste $name,
    <p> Uw wachtwoord zal verlopen $messageDays <br>
    <p>De minimale eisen waaraan een wachtwoord moet voldoen is op advies van Microsoft als volgt bepaald: <br>
    - Een lengte van minimaal 8 karakters <br>
    - Ten minste drie van de vier verschillende type karakters moeten erin voorkomen (cijfer, hoofdletter, kleine letter en leesteken) <br>
    - Een niet eerder gebruikt wachtwoord (de laatste 3 wachtwoorden worden bewaard) <br>
    - Uw naam mag niet (voor een deel) in het wachtwoord voorkomen <br>
    <p>Met vriendelijke groet, <br>
    <p>ICT Helpdesk <br>
    7721 <br>
    </P>"

   
    # If Testing Is Enabled - Email Administrator
    if (($testing) -eq "Enabled")
    {
        $emailaddress = $testRecipient
    } # End Testing

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

    # Send Email Message

    $expires = @(14,13,12,11,10,7,6,3,2,1)
    If ($expires -contains $daystoexpire)
    
        {
         # If Logging is Enabled Log Details
        if (($logging) -eq "Enabled")
        {
            Add-Content $logfile "$date,$Name,$emailaddress,$daystoExpire,$expireson" 
        }
        # 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

 
  • Marked as answer by Biga_b Friday, October 10, 2014 11:15 AM
October 9th, 2014 6:24pm

Changed it to $user. That got rid of the errors, but nobody receives an email now. I enabled $Testing, and also the testuser does not receive mail.

The current script
http://wouden.net/Issues/Powershell/PW_ExpireNotification.txt


  • Edited by Biga_b 20 hours 34 minutes ago
Free Windows Admin Tool Kit Click here and download it now
October 9th, 2014 10:20pm

Changed it to $user. That got rid of the errors, but nobody receives an email now. I enabled $Testing, and also the testuser does not receive mail.

The current script
http://wouden.net/Issues/Powershell/PW_ExpireNotification.txt


  • Edited by Biga_b Friday, October 10, 2014 1:59 PM
October 9th, 2014 10:20pm

Thanks Rhys. That did solve the error. But still the users do not receive a mail, only the testuser, although $Testing = disabled.

The problem would be that the users don't have a E-mail address listed

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

But if I look at the properties of the accounts in AD, I see a Email address. Am I looking in the wrong place??

Quote:

Edit:  Actually, I just noticed you are stripping out everything but the Name for $Name.  Then you are querying AD again for one other property.  You should just do one Get-ADUser, collecting all the properties you need, and use that object throughout.  Otherwise your script will take much longer than necessary.

Being a powershell dummy, I think I understand what you mean, but don't know how to edit the script

Performance was going to be my next question, but I first wanted to have a working script.

Thanx

Free Windows Admin Tool Kit Click here and download it now
October 10th, 2014 7:21am

Sorry my bad.. I edited $expires = @(14,13,12,11,10,9,8,7,6,5,4,3,2,1)to cover all days before password expiration.  Now the users do get mail. Offcourse I will change it when we go live with the script.

-Attachment parameter to include a pdf document as attachment.

http://wouden.net/Issues/Powershell/PW_ExpireNotification.txt

Thanks Braham20

Performance wise, is this the script?? Could I gain performance editing the script?


  • Edited by Biga_b 20 hours 34 minutes ago
October 10th, 2014 7:30am

I think this should work, you're trying to get the email address from get-adgroupmember it won't give you that property, I've taken out the unnecessary get-aduser calls as well. I haven't been able to test it but it should be closer to what you're after:

#################################################################################################################
# 
# Version 1.1 May 2014
# Robert Pearman (WSSMB MVP)
# TitleRequired.com
# Script to Automated Email Reminders when Users Passwords due to Expire.
#
# Requires: Windows PowerShell Module for Active Directory
#
# For assistance and ideas, visit the TechNet Gallery Q&A Page. http://gallery.technet.microsoft.com/Password-Expiry-Email-177c3e27/view/Discussions#content
#
##################################################################################################################
# Please Configure the following variables....
$smtpServer='ex2013.stibbeota.nl'
$expireindays = 15
$from = 'Stibbe Helpdesk <DoNotReply@Stibbe.com>'
$logging = "Enabled" # Set to Disabled to Disable Logging
$logFile = "c:\mylog.csv" # ie. c:\mylog.csv
$testing = 'disabled' # Set to Disabled to Email Users
$testRecipient = 'test.user@stibbeota.nl'
$date = Get-Date -format ddMMyyyy
#
###################################################################################################################

# Check Logging Settings
if (($logging) -eq "Enabled")
{
    # Test Log File Path
    $logfilePath = (Test-Path $logFile)
    if (($logFilePath) -ne "True")
    {
        # Create CSV File and Headers
        New-Item $logfile -ItemType File
        Add-Content $logfile "Date,Name,EmailAddress,DaystoExpire,ExpiresOn"
    }
} # End Logging Check

# Get Users From AD who are Enabled, Passwords Expire and are Not Currently Expired
Import-Module ActiveDirectory
#$users = get-aduser -filter * -properties Name, PasswordNeverExpires, PasswordExpired, PasswordLastSet, EmailAddress |where {$_.Enabled -eq "True"} | where { $_.PasswordNeverExpires -eq $false } | where { $_.passwordexpired -eq $false }
$maxPasswordAge = (Get-ADDefaultDomainPasswordPolicy).MaxPasswordAge

# Process Each User for Password Expiry
$groups = 'PWNotification1','PWNotification2'
foreach ($group in $groups)
{
    $members = Get-AdGroupMember $group
        foreach ($user in $members)
        {
get-aduser $user -properties name,EmailAddress,PasswordLastSet | Select Name,EmailAddress,PasswordLastSet | %  {


$name = $_.Name
$EmailAddress = $_.EmailAddress
$passwordSetDate = $_.PasswordLastSet 


$PasswordPol = (Get-AduserResultantPasswordPolicy $name)
 
    # 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" + " dag(en)."
    }
    else
    {
        $messageDays = "today."
    }

    # Email Subject Set Here
    $subject="Uw wachtwoord zal verlopen $messageDays"
  
    # Email Body Set Here, Note You can use HTML, including Images.
    $body ="
    Beste $name,
    <p> Uw wachtwoord zal verlopen $messageDays <br>
    <p>De minimale eisen waaraan een wachtwoord moet voldoen is op advies van Microsoft als volgt bepaald: <br>
    - Een lengte van minimaal 8 karakters <br>
    - Ten minste drie van de vier verschillende type karakters moeten erin voorkomen (cijfer, hoofdletter, kleine letter en leesteken) <br>
    - Een niet eerder gebruikt wachtwoord (de laatste 3 wachtwoorden worden bewaard) <br>
    - Uw naam mag niet (voor een deel) in het wachtwoord voorkomen <br>
    <p>Met vriendelijke groet, <br>
    <p>ICT Helpdesk <br>
    7721 <br>
    </P>"

   
    # If Testing Is Enabled - Email Administrator
    if (($testing) -eq "Enabled")
    {
        $emailaddress = $testRecipient
    } # End Testing

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

    # Send Email Message

    $expires = @(14,13,12,11,10,7,6,3,2,1)
    If ($expires -contains $daystoexpire)
    
        {
         # If Logging is Enabled Log Details
        if (($logging) -eq "Enabled")
        {
            Add-Content $logfile "$date,$Name,$emailaddress,$daystoExpire,$expireson" 
        }
        # 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


  • Edited by Braham20 22 hours 56 minutes ago
Free Windows Admin Tool Kit Click here and download it now
October 10th, 2014 7:51am

I think this should work, you're trying to get the email address from get-adgroupmember it won't give you that property, I've taken out the unnecessary get-aduser calls as well. I haven't been able to test it but it should be closer to what you're after:

#################################################################################################################
# 
# Version 1.1 May 2014
# Robert Pearman (WSSMB MVP)
# TitleRequired.com
# Script to Automated Email Reminders when Users Passwords due to Expire.
#
# Requires: Windows PowerShell Module for Active Directory
#
# For assistance and ideas, visit the TechNet Gallery Q&A Page. http://gallery.technet.microsoft.com/Password-Expiry-Email-177c3e27/view/Discussions#content
#
##################################################################################################################
# Please Configure the following variables....
$smtpServer='ex2013.stibbeota.nl'
$expireindays = 15
$from = 'Stibbe Helpdesk <DoNotReply@Stibbe.com>'
$logging = "Enabled" # Set to Disabled to Disable Logging
$logFile = "c:\mylog.csv" # ie. c:\mylog.csv
$testing = 'disabled' # Set to Disabled to Email Users
$testRecipient = 'test.user@stibbeota.nl'
$date = Get-Date -format ddMMyyyy
#
###################################################################################################################

# Check Logging Settings
if (($logging) -eq "Enabled")
{
    # Test Log File Path
    $logfilePath = (Test-Path $logFile)
    if (($logFilePath) -ne "True")
    {
        # Create CSV File and Headers
        New-Item $logfile -ItemType File
        Add-Content $logfile "Date,Name,EmailAddress,DaystoExpire,ExpiresOn"
    }
} # End Logging Check

# Get Users From AD who are Enabled, Passwords Expire and are Not Currently Expired
Import-Module ActiveDirectory
#$users = get-aduser -filter * -properties Name, PasswordNeverExpires, PasswordExpired, PasswordLastSet, EmailAddress |where {$_.Enabled -eq "True"} | where { $_.PasswordNeverExpires -eq $false } | where { $_.passwordexpired -eq $false }
$maxPasswordAge = (Get-ADDefaultDomainPasswordPolicy).MaxPasswordAge

# Process Each User for Password Expiry
$groups = 'PWNotification1','PWNotification2'
foreach ($group in $groups)
{
    $members = Get-AdGroupMember $group
        foreach ($user in $members)
        {
get-aduser $user -properties name,EmailAddress,PasswordLastSet | Select Name,EmailAddress,PasswordLastSet | %  {


$name = $_.Name
$EmailAddress = $_.EmailAddress
$passwordSetDate = $_.PasswordLastSet 


$PasswordPol = (Get-AduserResultantPasswordPolicy $name)
 
    # 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" + " dag(en)."
    }
    else
    {
        $messageDays = "today."
    }

    # Email Subject Set Here
    $subject="Uw wachtwoord zal verlopen $messageDays"
  
    # Email Body Set Here, Note You can use HTML, including Images.
    $body ="
    Beste $name,
    <p> Uw wachtwoord zal verlopen $messageDays <br>
    <p>De minimale eisen waaraan een wachtwoord moet voldoen is op advies van Microsoft als volgt bepaald: <br>
    - Een lengte van minimaal 8 karakters <br>
    - Ten minste drie van de vier verschillende type karakters moeten erin voorkomen (cijfer, hoofdletter, kleine letter en leesteken) <br>
    - Een niet eerder gebruikt wachtwoord (de laatste 3 wachtwoorden worden bewaard) <br>
    - Uw naam mag niet (voor een deel) in het wachtwoord voorkomen <br>
    <p>Met vriendelijke groet, <br>
    <p>ICT Helpdesk <br>
    7721 <br>
    </P>"

   
    # If Testing Is Enabled - Email Administrator
    if (($testing) -eq "Enabled")
    {
        $emailaddress = $testRecipient
    } # End Testing

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

    # Send Email Message

    $expires = @(14,13,12,11,10,7,6,3,2,1)
    If ($expires -contains $daystoexpire)
    
        {
         # If Logging is Enabled Log Details
        if (($logging) -eq "Enabled")
        {
            Add-Content $logfile "$date,$Name,$emailaddress,$daystoExpire,$expireson" 
        }
        # 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


  • Edited by Braham20 22 hours 49 minutes ago
October 10th, 2014 7:57am

No probs! Yeah I'm sure you could shave off a second or so if you tweaked a few bits, it seems to run quite quickly though so I don't think you'd make huge gains but by all means have a play about if you want, use it as a chance to improve your skills :)
Free Windows Admin Tool Kit Click here and download it now
October 10th, 2014 9:11am

Thanx for helping me with this Braham20, but I get the following error running the script:

Get-ADUserResultantPasswordPolicy : Cannot find an object with identity: 'Steve Wouden' under: 'DC=Stibbeota,DC=nl'.
At C:\Untitled3.ps1:56 char:54
+     $PasswordPol = (Get-AduserResultantPasswordPolicy <<<<  $name)
    + CategoryInfo          : ObjectNotFound: (Steve Wouden:ADUser) [Get-ADUserResultantPasswordPolicy], ADIdentityNotFoundException
    + FullyQualifiedErrorId : Cannot find an object with identity: 'Steve Wouden' under: 'DC=Stibbeota,DC=nl'.,Microsoft.ActiveDirectory.Management.Commands.GetADUserResultantPasswordPolicy

I googled this error, and it isn't a permission issue, because I'm running this script under a domain admin account on a domain controller. I use Fine Grained password Policy instead of default domain policy. I don't know if that's is the problem.

Thanx

October 10th, 2014 11:45am

Sorry, my fault - I passed $name instead of $user to the get-aduserresultantpasswordpolicy cmdlet try this version.

#################################################################################################################
# 
# Version 1.1 May 2014
# Robert Pearman (WSSMB MVP)
# TitleRequired.com
# Script to Automated Email Reminders when Users Passwords due to Expire.
#
# Requires: Windows PowerShell Module for Active Directory
#
# For assistance and ideas, visit the TechNet Gallery Q&A Page. http://gallery.technet.microsoft.com/Password-Expiry-Email-177c3e27/view/Discussions#content
#
##################################################################################################################
# Please Configure the following variables....
$smtpServer='ex2013.stibbeota.nl'
$expireindays = 15
$from = 'Stibbe Helpdesk <DoNotReply@Stibbe.com>'
$logging = "Enabled" # Set to Disabled to Disable Logging
$logFile = "c:\mylog.csv" # ie. c:\mylog.csv
$testing = 'disabled' # Set to Disabled to Email Users
$testRecipient = 'test.user@stibbeota.nl'
$date = Get-Date -format ddMMyyyy
#
###################################################################################################################

# Check Logging Settings
if (($logging) -eq "Enabled")
{
    # Test Log File Path
    $logfilePath = (Test-Path $logFile)
    if (($logFilePath) -ne "True")
    {
        # Create CSV File and Headers
        New-Item $logfile -ItemType File
        Add-Content $logfile "Date,Name,EmailAddress,DaystoExpire,ExpiresOn"
    }
} # End Logging Check

# Get Users From AD who are Enabled, Passwords Expire and are Not Currently Expired
Import-Module ActiveDirectory
#$users = get-aduser -filter * -properties Name, PasswordNeverExpires, PasswordExpired, PasswordLastSet, EmailAddress |where {$_.Enabled -eq "True"} | where { $_.PasswordNeverExpires -eq $false } | where { $_.passwordexpired -eq $false }
$maxPasswordAge = (Get-ADDefaultDomainPasswordPolicy).MaxPasswordAge

# Process Each User for Password Expiry
$groups = 'PWNotification1','PWNotification2'
foreach ($group in $groups)
{
    $members = Get-AdGroupMember $group
        foreach ($user in $members)
        {
get-aduser $user -properties name,EmailAddress,PasswordLastSet | Select Name,EmailAddress,PasswordLastSet | %  {


$name = $_.Name
$EmailAddress = $_.EmailAddress
$passwordSetDate = $_.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" + " dag(en)."
    }
    else
    {
        $messageDays = "today."
    }

    # Email Subject Set Here
    $subject="Uw wachtwoord zal verlopen $messageDays"
  
    # Email Body Set Here, Note You can use HTML, including Images.
    $body ="
    Beste $name,
    <p> Uw wachtwoord zal verlopen $messageDays <br>
    <p>De minimale eisen waaraan een wachtwoord moet voldoen is op advies van Microsoft als volgt bepaald: <br>
    - Een lengte van minimaal 8 karakters <br>
    - Ten minste drie van de vier verschillende type karakters moeten erin voorkomen (cijfer, hoofdletter, kleine letter en leesteken) <br>
    - Een niet eerder gebruikt wachtwoord (de laatste 3 wachtwoorden worden bewaard) <br>
    - Uw naam mag niet (voor een deel) in het wachtwoord voorkomen <br>
    <p>Met vriendelijke groet, <br>
    <p>ICT Helpdesk <br>
    7721 <br>
    </P>"

   
    # If Testing Is Enabled - Email Administrator
    if (($testing) -eq "Enabled")
    {
        $emailaddress = $testRecipient
    } # End Testing

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

    # Send Email Message

    $expires = @(14,13,12,11,10,7,6,3,2,1)
    If ($expires -contains $daystoexpire)
    
        {
         # If Logging is Enabled Log Details
        if (($logging) -eq "Enabled")
        {
            Add-Content $logfile "$date,$Name,$emailaddress,$daystoExpire,$expireson" 
        }
        # 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

 
Free Windows Admin Tool Kit Click here and download it now
October 10th, 2014 11:47am

Sorry my bad.. I edited $expires = @(14,13,12,11,10,9,8,7,6,5,4,3,2,1)to cover all days before password expiration.  Now the users do get mail. Offcourse I will change it when we go live with the script.

-Attachment parameter to include a pdf document as attachment.

http://wouden.net/Issues/Powershell/PW_ExpireNotification.txt

Thanks Braham20

Performance wise, is this the script?? Could I gain performance editing the script?


  • Edited by Biga_b Friday, October 10, 2014 1:59 PM
October 10th, 2014 2:15pm

Changed it to $user. That got rid of the errors, but nobody receives an email now. I enabled $Testing, and also the testuser does not receive mail.

The current script
http://www.wouden.net/Issues/Powershell/PW_ExpireNotification.txt

  • Edited by Biga_b 3 hours 19 minutes ago add script
Free Windows Admin Tool Kit Click here and download it now
October 10th, 2014 3:36pm

Changed it to $user. That got rid of the errors, but nobody receives an email now. I enabled $Testing, and also the testuser does not receive mail.

The current script
http://www.wouden.net/Issues/Powershell/PW_ExpireNotification.txt

  • Edited by Biga_b 3 hours 12 minutes ago add script
October 10th, 2014 3:42pm

Strange, I got chance to test it this morning with myself as the test recipient and it came through without any problems. Do you receive any sort of error?
Free Windows Admin Tool Kit Click here and download it now
October 11th, 2014 4:26am

One small question. My Boss want to address the user by their first name in the email, not firstname lastname.

$Firstname = $_.GivenName doesn't do it for me.. Trying to improve.. What am I doing wrong?

Thanx

October 11th, 2014 2:51pm

You already have a good solution to the problem you posed, but I thought I'd add a comment anyway.

I have had managers that would occasionally make a request such as the one yours gave you. The problem with some of these questions is that the manager does not give the exact problem, just what he thinks the solution might be. Sometimes there is a completely different solution that will do a more effective job of solving the actual problem.

In this case, your script sends an email, but the user will receive it only if he has not exceeded his email quota. In addition, it is my experience that users start to tune out automated messages, especially the repetitive ones.

Regardless, here is a sample powershell script that seems to do what you want:

    https://gallery.technet.microsoft.com/Password-Expiry-Email-177c3e27

But - if your users are logging on to your internal network (as opposed to accessing your email system with a web client), there are two other possibilities you could consider.

If you want to do the notification with a script, you could create one to run from the logon script. Instead of sending an email, it would popup some kind of a dialog box advising the user of the impending expiry of his password. Here is an example, but done in vbscript:

    http://community.spiceworks.com/scripts/show/1594-password-expiration-pop-up-for-windows-7

A better solution in my mind is to let windows do the notification for you. Windows can be configured to display a password expiry notice. One benefit is that it displays a "change password now" button, while the email solution requires the user to then remember to go somewhere else to change the password. Here is how the password expiry notice settings can be changed from the default:

    http://technet.microsoft.com/en-us/library/ee829687(v=ws.10).aspx

Free Windows Admin Tool Kit Click here and download it now
October 11th, 2014 5:08pm

Hi,

Change $name = $_.Name to $name = $_.GivenName

October 11th, 2014 7:53pm

Al Dunbar, thanks for your thorough commentary

You and I think the same about this issue. First, the script I use is the one you suggest in you're first link. See my first post.

I know about the second solution(vb script), but we do have users connecting through SSL and / or mailclient on their BYOD. So this wouldn't work for them.

And you're third solution is the one I have in place for almost 2 years, and it is working perfectly. But Why also an E-mail?

Standard the windows notification popup is 5 seconds. A few users start their PC, logon, and then go for a cup of coffee, a smoke, do their morning rituals, missing the notification. Or users that ignored it for the time being, forgot about it, and went on vacation. They then get issues with the mail client on their smartphone if password does expire. I thought a solution would be to extend the time the windows notification windows stays open, for example 5 minutes. But the problem here was that this is for ALL the windows notifications. Like printing a document. And we have a few secretaries that do a lot of printing, and they complained about the popup.

There are a few scenarios that forces us to send an E-mail. Not having any scripting skills, I didn't jump at this solution at once, but in the end I'm triggered to do more with powershell. It's almost a must to have some powershell knowledge (Active Directory, SCCM, SCOM, Exhange)

Anyway, I still have issues to address the user only by first name. I tried what Mike Laughin suggest, and also  tried $Firstname = $_.GivenName, but in de mail I don't get the firstname.

http://wouden.net/Issues/Powershell/PW_ExpireNotification.txt

Thanks

Free Windows Admin Tool Kit Click here and download it now
October 12th, 2014 6:44am

My mistake again. It works now. Forgot to query AD for that property.

get-aduser $user -properties Givenname,name,EmailAddress,PasswordLastSet | Select Givenname,Name,EmailAddress,PasswordLastSet | %  {

I'm beginning to get the hang of it. Powershell is easy :-) Just kidding. Have a lot to learn, but most important, understand how it works.

Got me this book/PDF. "Learn Windows PowerShell in a Month of Lunches". Looks like a good place to start, and I never mis a lunch. :-)

Thanks Guys. It was educational.

October 12th, 2014 10:11am

You need to include GivenName in your Get-ADUser select:

get-aduser $user -properties name,EmailAddress,PasswordLastSet | Select Name,GivenName,EmailAddress,PasswordLastSet | %  {
Edit: Oops, now I see you already found that :)
Free Windows Admin Tool Kit Click here and download it now
October 12th, 2014 10:16am

Al Dunbar, thanks for your thorough commentary

<snip>


You are welcome.

I've only ever supported users who normally logon directly and sometimes remotely, but even then they are effectively connected directly to our domain.

I guess the actual problem here is that some users will occasionally get locked out. No matter how many warning messages and popups they see, and no matter how long you extend the timeout on the popup, there is no way you can prevent users from either ignoring the warnings or just not noticing them And for the conscientious users, some will do well with the standard MS notification, some with a single email, some with a series, and some with popups. In the end the most direct information about a pending lockout is when they become locked out.

I think the answer is that it is up to the users to take steps to avoid being unable to work due to a lock out. Some might appreciate a script or tool that shows how long to lockout that they could run interactively or from the startup group on their computer.

Alternately, I understand that there are some scripts or applications out there by which a locked out user can submit a reset request. I have no experience with these, but they seem to be useful for remote users that do not actually logon to the domain.

As to dealing managers who think they know the kind of solution required, you have probably already developed some skill in this area. It is important to always demonstrate respect, as any sarcasm about their shortcomings will not help at all.

One of my managers once said to me when I was reticent to develop a system he thought would be useful but I knew to be infeasible: "I don't see how this system CANNOT be developed". To this I answered "perhaps. But in able to actually develop this system, at least one of us must be able to see how it CAN be done". Since he knew he did not know this, he realized he was unable to pass that knowledge along to me. And he also recognized that if I, his "expert" did not already know, then perhaps my viewpoint was correct.

October 12th, 2014 1:03pm

I'm still testing and finetuning the script. As you can see in the script I need to send a e-mail in both English and Dutch. The issue here is the $messageDays. I solved the issue by doing this:

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

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

    # Check Number of Days to Expiry in Dutch
    $messageDaysNL = $daystoexpire

    if (($messageDaysNL) -ge "1")
    {
        $messageDaysNL = "in " + "$daystoexpire" + " dag(en)."
    }
    else
    {
        $messageDaysNL = "Vandaag."
    }

It does solved my problem, but I don't know if this is the best way to do it. Also performance wise..

Thanx again.

Free Windows Admin Tool Kit Click here and download it now
October 12th, 2014 3:47pm

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics