Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

script to determine password expire date and send email notificati

1,607 views
Skip to first unread message

Eero J

unread,
Jan 5, 2009, 10:23:01 AM1/5/09
to
How can I use a script to determine password-expiration dates for users in a
organizational unit (OU) and send an email message to accounts whose
passwords expire soon?
For example, if my password expires after 14 days, then it sends me email
with that info.

Shay Levy [MVP]

unread,
Jan 5, 2009, 1:01:52 PM1/5/09
to
Hello Eero,


I've been working on a similar script, I did not test it extensively but
give it a try, you'll need Quest AD cmdlets (http://www.quest.com/powershell/activeroles-server.aspx).
If you want to run it against a specific OU, add the -ou parameter (alias
for searchRoot) to Get-QADUser with the value of the OU DN (e.g Get-QADUser
-ou <ou_dn> ...):

# get domain maximumPasswordAge password policy
$maximumPasswordAge = (Get-QADObject (Get-QADRootDSE).defaultNamingContextDN).maximumPasswordAge.value.days

if(!$maximumPasswordAge){
throw "Domain 'MaximumPasswordAge'password policy is not configured (set
to 0)."
}

# exclude users with no expiring password or cannot change password
$ldap = "(!userAccountControl:1.2.840.113556.1.4.803:=65536)(!userAccountControl:1.2.840.113556.1.4.803:=64)"


# create calculated property to display days until password expire
$daysUntilExpire = @{n="daysUntilExpire";e={$maximumPasswordAge-$_.passwordAge.value.days}}

$expireIn = 10

# get enabled users that meet the above criteria
Get-QADUser -enabled -size 0 -ldap $ldap | where {$_.passwordAge.value -gt
0 -AND ($maximumPasswordAge-$_.passwordAge.value.days) -gt $expireIn} | select
name,email,passwordAge,$daysUntilExpire

---
Shay Levy
Windows PowerShell MVP
http://blogs.microsoft.co.il/blogs/ScriptFanatic
PowerShell Toolbar: http://tinyurl.com/PSToolbar


EJ> How can I use a script to determine password-expiration dates for
EJ> users in a organizational unit (OU) and send an email message to
EJ> accounts whose passwords expire soon? For example, if my password
EJ> expires after 14 days, then it sends me email with that info.
EJ>


Eero J

unread,
Jan 6, 2009, 8:05:01 AM1/6/09
to
Hey Shay,
Thanks for the ideas. Could you please implement the OU part and email
sending notifications also?
I found this peace of script also, maybe you can get some ideas from it:

**First we need to know the maximum password age for the domain:
function Get-maxPwdAge{
$root = [ADSI]"LDAP://acf.americredit.com"
$filter = "(&(objectcategory=domainDNS)
(distinguishedName=DC=acf,DC=americredit,DC=com))"
$ds = New-Object system.DirectoryServices.DirectorySearcher($root,
$filter)
$dc = $ds.findone()
[int64]$mpa = ($dc.Properties[‘maxpwdage’][0]).ToString().Trim
("-")
$mpa*(.000000100)/86400
}

**Then we can take this information to calculate the current password
age of a user object:
[int]$maxpwdage = Get-maxPwdAge
[int]$gracedays = 14
[int]$days = $maxpwdage - $gracedays

$old = (Get-Date).AddDays(-$days) #Max Pwd Age - Lead Time (60 - 14)
$users = Get-QADUser -SearchRoot "OU=Users,DC=domain,DC=com"
write-Host "Creating Password Expiration Report. Please
wait.........."
$report = $users | foreach {$users | where {$users.pwdLastSet -le $old
-and $users.pwdLastSet -gt "1/1/1601" $users.objectclass -eq "user"} |
select name,email,pwdlastset}
$report | Export-Csv $reportfile -noType

$dt = "{0:d}" -f [datetime](get-date).adddays(-$days)
Import-Csv $reportfile | ForEach-Object {
$username = $_.Name
[datetime]$pwdset = $_.pwdLastSet
$email = $_.Email

#$daysleft = maxpwdage minus days since last change (60 - 50 = 10 days
before password expires)
$body = [string]::join([environment]::newline, (Get-Content
$emailbody ))
$daysleft = $maxpwdage - [int]((get-date).Subtract($pwdset)).days
if ($daysleft -le 0 -and $email -ne ""){
$subject = "Your login password has expired."
Send-smtpMail -smtphost smtphost -to $email -from "us...@domain.com" -
subject $subject -body $body.ToString()
Write-Host "Password for $username has Expired. A message will be sent
to $email"
}
if ($daysleft -gt 0 -and $email -ne ""){
$subject = "Your login password will expire in $daysleft days."
Send-smtpMail -smtphost smtphost -to $email -from "us...@domain.com" -
subject $subject -body $body.ToString()
Write-Host "User $username has $daysleft days left before password
expires. Message will be sent to $email."
}
}

send-smtpmail -smtphost smtphost -to "us...@domain.com" -from
"us...@domain.com" -subject "Password Report" -AttachmentPath $ProgLog

Eero J

unread,
Jan 6, 2009, 10:06:10 AM1/6/09
to
OK the only thing i need now is the email sending support for this:

# get domain maximumPasswordAge value (it is always constant in my case)
$maximumPasswordAge = 90

# exclude users with no expiring password or cannot change password
$ldap =
"(!userAccountControl:1.2.840.113556.1.4.803:=65536)(!userAccountControl:1.2.840.113556.1.4.803:=64)"

# create calculated property to display days until password expire
$daysUntilExpire =
@{n="daysUntilExpire";e={$maximumPasswordAge-$_.passwordAge.value.days}}

# get all users
$expireIn = 0

# get enabled users that meet the above criteria

Get-QADUser -ou 'OU=MyTest,DC=domain,DC=com' -enabled -size 0 -ldap $ldap |

where {$_.passwordAge.value -gt
0 -AND ($maximumPasswordAge-$_.passwordAge.value.days) -gt $expireIn} |

select Name,email,passwordAge,$daysUntilExpire | sort daysUntilExpire

##End of script

I need the script to send email to account who's daysUntilExpire value
equals 14

Eero J

unread,
Jan 7, 2009, 3:16:00 AM1/7/09
to
OK i managed to write this, displaying works great but it does not send
emails - any ideas whats wrong with the email sending part of the script?

#start of the script

# get domain maximumPasswordAge password policy

$maximumPasswordAge = 90

# exclude users with no expiring password or cannot change password
$ldap =
"(!userAccountControl:1.2.840.113556.1.4.803:=65536)(!userAccountControl:1.2.840.113556.1.4.803:=64)"

# create calculated property to display days until password expire
$daysUntilExpire =
@{n="daysUntilExpire";e={$maximumPasswordAge-$_.passwordAge.value.days}}

$expireIn = 0

# get enabled users that meet the above criteria
Get-QADUser -ou 'OU=MyTest,DC=domain,DC=com' -enabled -size 0 -ldap $ldap |
where {$_.passwordAge.value -gt
0 -AND ($maximumPasswordAge-$_.passwordAge.value.days) -gt $expireIn} |
select Name,email,passwordAge,$daysUntilExpire | sort daysUntilExpire

# send email to account who's password will expire in 14 days
$username = $_.Name
$email = $_.Email
$smtpServer = "mysmtpserver.domain.com"

if ($daysUntilExpire -eq 14 -and $email -ne "")
{
Write-Host "User $username has $daysUntilExpire days left before password

expires. Message will be sent to $email."

$subject = "Your login password will expire in $daysUntilExpire days."
$body = "Hello $username . Your login password will expire in
$daysUntilExpire days."
Send-smtpMail -smtphost $smtpServer -to $email -from
"passwex...@mydomain.com" -subject $subject -body $body
}

#end of the script

Shay Levy [MVP]

unread,
Jan 7, 2009, 5:52:36 AM1/7/09
to
Hello Eero,


I wouldn't set the $maximumPasswordAge var to a fixed value, someone may
change the password policy and you wont even know. This can lead the script
to send false emails.
I've also changed the ldap query, I removed the 'no expiring password' filter
and replaced it with the -passwordNeverExpires built-in parameter.

To get users that their password expires in 14 days: -eq $expireIn
To get users that their password expires in 14 days or more: -ge $expireIn

As a side note, PowerShell CTP3 has a new cmdlet to send emails, look for
: Send-MailMessage

function Send-Mail{

param($smtpServer,$from,$to,$subject,$body)

$smtp = new-object system.net.mail.smtpClient($SmtpServer)
$mail = new-object System.Net.Mail.MailMessage

$mail.from = $from
$mail.to.add($to)
$mail.subject = $subject
$mail.body = $body
#$mail.IsBodyHtml = $true

$smtp.send($mail)
}

# get domain maximumPasswordAge password policy

$maximumPasswordAge = (Get-QADObject (Get-QADRootDSE).defaultNamingContextDN).maximumPasswordAge.value.days

if(!$maximumPasswordAge){
throw "Domain 'MaximumPasswordAge'password policy is not configured (set
to 0)."
}

# exclude users that cannot change password
$ldap = "(!userAccountControl:1.2.840.113556.1.4.803:=64)"

# create calculated property to display days until password expire
$daysUntilExpire = @{n="daysUntilExpire";e={$maximumPasswordAge-$_.passwordAge.value.days}}

$expireIn = 14

# get enabled users that meet the above criteria

$expiredUsers = Get-QADUser -enabled -passwordNeverExpires $true -size 0

-ldap $ldap | where {$_.passwordAge.value -gt 0 -AND ($maximumPasswordAge-$_.passwordAge.value.days)

-eq $expireIn}

$expiredUsers | foreach {
if($_.email)
{
$subject="Your password will expire in $expireIn days"
$body="Your password will expire in $expireIn days"
Send-Mail -smtpServer exServerName -from "y...@domain.com" -to $_.email
-subject $subject -body $body
}
else
{
write-warning "user $($_.name) has no email address"
}
}
}
}

---
Shay Levy
Windows PowerShell MVP
http://blogs.microsoft.co.il/blogs/ScriptFanatic
PowerShell Toolbar: http://tinyurl.com/PSToolbar


EJ> OK i managed to write this, displaying works great but it does not
EJ> send emails - any ideas whats wrong with the email sending part of
EJ> the script?
EJ>
EJ> #start of the script
EJ>
EJ> # get domain maximumPasswordAge password policy
EJ> $maximumPasswordAge = 90
EJ> # exclude users with no expiring password or cannot change password
EJ>
EJ> $ldap =
EJ>
EJ> "(!userAccountControl:1.2.840.113556.1.4.803:=65536)(!userAccountCon
EJ> trol:1.2.840.113556.1.4.803:=64)"
EJ>
EJ> # create calculated property to display days until password expire
EJ> $daysUntilExpire =
EJ> @{n="daysUntilExpire";e={$maximumPasswordAge-$_.passwordAge.value.da
EJ> ys}}
EJ>
EJ> $expireIn = 0
EJ>
EJ> # get enabled users that meet the above criteria
EJ> Get-QADUser -ou 'OU=MyTest,DC=domain,DC=com' -enabled -size 0 -ldap
EJ> $ldap |
EJ> where {$_.passwordAge.value -gt
EJ> 0 -AND ($maximumPasswordAge-$_.passwordAge.value.days) -gt
EJ> $expireIn} |
EJ> select Name,email,passwordAge,$daysUntilExpire | sort
EJ> daysUntilExpire
EJ> # send email to account who's password will expire in 14 days
EJ> $username = $_.Name
EJ> $email = $_.Email
EJ> $smtpServer = "mysmtpserver.domain.com"
EJ> if ($daysUntilExpire -eq 14 -and $email -ne "")
EJ> {
EJ> Write-Host "User $username has $daysUntilExpire days left before
EJ> password
EJ> expires. Message will be sent to $email."
EJ> $subject = "Your login password will expire in $daysUntilExpire
EJ> days."
EJ> $body = "Hello $username . Your login password will expire in
EJ> $daysUntilExpire days."
EJ> Send-smtpMail -smtphost $smtpServer -to $email -from
EJ> "passwex...@mydomain.com" -subject $subject -body $body
EJ> }
EJ> #end of the script
EJ>


Eero J

unread,
Jan 7, 2009, 7:45:01 AM1/7/09
to
Thank you Shay,
But right now this code gives me error:
Missing expression after unary operator '-'.
At C:\ps\passwnotify.ps1:35 char:2
+ -l <<<< dap $ldap | where {$_.passwordAge.value -gt 0 -AND
($maximumPasswordAge-$_.passwordAge.value.days)

What might be the problem?
Eero

Shay Levy [MVP]

unread,
Jan 7, 2009, 8:23:27 AM1/7/09
to
Hello Eero,

It is probably due to the post wrapping. Make sure the $expiredUsers variable assigmnet is on one line. I've also attached the code as a text file, hopefully it will be posted.

---
Shay Levy
Windows PowerShell MVP
http://blogs.microsoft.co.il/blogs/ScriptFanatic
PowerShell Toolbar: http://tinyurl.com/PSToolbar


EJ> Thank you Shay,
EJ> But right now this code gives me error:
EJ> Missing expression after unary operator '-'.
EJ> At C:\ps\passwnotify.ps1:35 char:2
EJ> + -l <<<< dap $ldap | where {$_.passwordAge.value -gt 0 -AND
EJ> ($maximumPasswordAge-$_.passwordAge.value.days)
EJ> What might be the problem?
EJ> Eero
EJ> "Shay Levy [MVP]" wrote:
EJ>

expiringPasswords.txt

Eero J

unread,
Jan 7, 2009, 9:17:01 AM1/7/09
to
OK i removed the wraps but now i get this error:

Unexpected token 'Send-Mail' in expression or statement.
At C:\ps\passwordnotify.ps1:39 char:66
+ $body="Your password will expire in $expireIn days" Send-Mail <<<<
-smtpServer "mysmtpserver.mydomain.com" -from
"passw...@mydomain.com" -to $_.email -subject $subject -body $body

Can you see what is wrong here?
Big thanks,
Eero

Shay Levy [MVP]

unread,
Jan 8, 2009, 2:52:23 AM1/8/09
to
Hello Eero,


The Send-Mail call should be on a line of its own. The script is attached
to the previous thread. Do you see it?

---
Shay Levy
Windows PowerShell MVP
http://blogs.microsoft.co.il/blogs/ScriptFanatic
PowerShell Toolbar: http://tinyurl.com/PSToolbar


EJ> OK i removed the wraps but now i get this error:
EJ>
EJ> Unexpected token 'Send-Mail' in expression or statement.
EJ> At C:\ps\passwordnotify.ps1:39 char:66
EJ> + $body="Your password will expire in $expireIn days" Send-Mail
EJ> <<<<
EJ> -smtpServer "mysmtpserver.mydomain.com" -from
EJ> "passw...@mydomain.com" -to $_.email -subject $subject -body
EJ> $body
EJ> Can you see what is wrong here?
EJ> Big thanks,

Eero J

unread,
Jan 8, 2009, 4:29:01 AM1/8/09
to
The script works now but unfortunately everytime i run it, i always get the
result:
WARNING: user has no email address
It cannot display username and cannot find email address.
Any ideas?
Thank you,
Eero

Shay Levy [MVP]

unread,
Jan 8, 2009, 5:11:52 AM1/8/09
to
Hello Eero,


1. I had a logic error, replace '-passwordNeverExpires $true' with '-passwordNeverExpires $false'
2. I moved the email attribute check to the ldap filter, it will get only users that have the mail attribute set (now there is no need for if/else inside the last foreach)
3. It doesn't output anything because you probably have no users with exact number of days defined in '-eq $expireIn', try to use '-ge $expireIn'

The new script is attached to this thread.

---
Shay Levy
Windows PowerShell MVP
http://blogs.microsoft.co.il/blogs/ScriptFanatic
PowerShell Toolbar: http://tinyurl.com/PSToolbar


EJ> The script works now but unfortunately everytime i run it, i always
EJ> get the
EJ> result:
EJ> WARNING: user has no email address
EJ> It cannot display username and cannot find email address.
EJ> Any ideas?
EJ> Thank you,

Get-ExpiringPasswords.txt

Eero J

unread,
Jan 8, 2009, 5:31:02 AM1/8/09
to
For some reason, i can not find attached script anywhere.
If you can, please send it to my e-mail address eero....@emt.ee

Thank you very much,
Eero

Shay Levy [MVP]

unread,
Jan 8, 2009, 5:47:57 AM1/8/09
to
Check your email.


---
Shay Levy
Windows PowerShell MVP
http://blogs.microsoft.co.il/blogs/ScriptFanatic
PowerShell Toolbar: http://tinyurl.com/PSToolbar


EJ> For some reason, i can not find attached script anywhere. If you
EJ> can, please send it to my e-mail address eero....@emt.ee
EJ>
EJ> Thank you very much,

Eero J

unread,
Jan 8, 2009, 7:23:00 AM1/8/09
to
Thank you so much Shay! Everything works great now!
You have helped me very much and i am very grateful to you!
Your blog is awesome too, i found much useful information about powershell
from there.
Keep up the good work,
Your fan,
Eero J

die....@gmail.com

unread,
Jan 24, 2009, 6:40:54 PM1/24/09
to
amazing job !!
how can we filter out users that have already expired passwords ?

Shay Levy [MVP]

unread,
Jan 29, 2009, 6:40:39 AM1/29/09
to
I can't test right now but try to replace

... | where {$_.passwordAge.value -gt 0 -AND ($maximumPasswordAge-$_.passwordAge.value.days)

with

... | where { $_.passwordAge.value.days -gt $maximumPasswordAge)


---
Shay Levy
Windows PowerShell MVP
http://blogs.microsoft.co.il/blogs/ScriptFanatic
PowerShell Toolbar: http://tinyurl.com/PSToolbar

die....@gmail.com

unread,
Feb 4, 2009, 3:36:19 AM2/4/09
to
On Jan 29, 1:40 pm, Shay Levy [MVP] <n...@addre.ss> wrote:
> I can't test right now but try to replace
>
> ... | where {$_.passwordAge.value -gt 0 -AND ($maximumPasswordAge-$_.passwordAge.value.days)
>
> with
>
> ... | where { $_.passwordAge.value.days -gt $maximumPasswordAge)
>
> ---
> Shay Levy
> Windows PowerShell MVPhttp://blogs.microsoft.co.il/blogs/ScriptFanatic

> PowerShell Toolbar:http://tinyurl.com/PSToolbar
>
> > amazing job !!
> > how can we filter out users that have already expired passwords ?

Thanks will report !

Walt S

unread,
Feb 26, 2009, 12:10:26 PM2/26/09
to
The script works well but the logic might need some tweaking--if you want it
to run daily, and send an email with the notification eacy day, the
$expireIn variable doesn't increment down. Using the $daysUntilExpire seems
better, but displays in the sent email as " System.Collections.Hashtable "
so I guess that hash table needs to be parsed somehow?

I'm still coming to grips with hash tables so if someone has an idea for
tweaking it I'd appreciate it!

Thanks, W.


"Shay Levy [MVP]" <n...@addre.ss> wrote in message
news:89228ed260e398...@news.microsoft.com...

Walt S

unread,
Feb 26, 2009, 12:40:24 PM2/26/09
to
I think I solved this issue, I used a simple variable and assigned it to the
calculation of the max password age less the users password age.

text file attached.

Thanks, Walt.


"Walt S" <som...@example.com> wrote in message
news:%237UlfUD...@TK2MSFTNGP05.phx.gbl...

NotifyPasswordExpiry.txt

lundholmster

unread,
Mar 16, 2009, 3:14:42 PM3/16/09
to

Walt S, could you attach the txt file again or paste it? I can't see
your attachment.


--
lundholmster

mdbman66

unread,
Mar 17, 2009, 2:53:08 PM3/17/09
to

I am trying to accomplish the same thing with password notifications.
Could someone please send me the completed script as a text file. I am
just learning the scripting language.

Thank you.


--
mdbman66

Phr00zen

unread,
May 15, 2009, 1:07:02 PM5/15/09
to
Hello,

Can you guys please paste the completed script?
I tried to run this, but am getting error-ed out..

Thanks

mdbman66

unread,
May 15, 2009, 2:40:58 PM5/15/09
to

I have attached the script. Runs great. Notifies users 15 days out of
the expiring password. It will then notify them every 2nd day until
resolved. If you can't get the script. Send me your email address and I
will email it to you.


--
mdbman66

alexc

unread,
May 20, 2009, 12:42:58 PM5/20/09
to

can one of you guys re-post the entire script in plain text so i can
give it a shot.

thanks


--
alexc

hogcruzr05

unread,
Jul 13, 2009, 4:13:19 PM7/13/09
to

mdbman-can you repost the working script? PLEASE?
Thanks a million..


--
hogcruzr05

Chris Dent

unread,
Jul 14, 2009, 4:18:42 AM7/14/09
to

No idea if this is the same, the post you replied to is too old to see
in the newsgroups.

I use the script below. It is also possible to use Where-Object although
it's not as efficient as using an LDAP filter.

Chris


#
# Load Add-Ins
#

Get-PsSnapIn -Registered | Add-PsSnapIn -ErrorAction "SilentlyContinue"

#
# Constants
#

$SmtpServer = "mail.domain.com"

#
# Functions
#

Function GetUsersToNotify($MaximumAge, $DaysFromChange) {
# Finds all users in AD where the password will expire in $DaysFromChange

$StartDate = (New-TimeSpan $(Get-Date("01/01/1601 00:00:00")) `
((Get-Date).Date.AddDays(-$MaximumAge + $DaysFromChange))).Ticks

$EndDate = (New-TimeSpan $(Get-Date("01/01/1601 00:00:00")) `
((Get-Date).Date.AddDays(-$MaximumAge + $DaysFromChange + 1))).Ticks

$LdapFilter = "(&(pwdLastSet>=$StartDate)(pwdLastSet<=$EndDate))"

Get-QADUser -LdapFilter $LdapFilter `
-Enabled -IncludedProperties pwdLastSet | `
Select-Object Name, PwdLastSet, Mail
}

Function NotifyUser($Mail, $PasswordLastSet, $DaysFromChange) {
$Message = "<!DOCTYPE HTML PUBLIC `"-//W3C//DTD HTML 4.01//EN`"
`"http://www.w3.org/TR/html4/strict.dtd`">`r`n"
$Message += "<html>"
$Message += "<head>"
$Message += "<title>Password Expiry Warning</title>"
$Message += "<style type='text/css'>"
$Message += "body { font-family: verdana; font-size: 10pt; }"
$Message += "</style>"
$Message += "</head><body>"
$Message += "<p>Your password will expire in <b>$DaysFromChange</b>
days.</p>"
$Message += "<p>To change your password immediately please visit <a
href='https://mmail.domain.com/owa'>https://mail.domain.com/owa</a>.</p>"
$Message += "</body></html>"

$MailMessage = New-Object Net.Mail.MailMessage( `
"sen...@domain.com", `
$Mail, `
"Password Expiry Warning - $DaysFromChange Days", `
$Message)

$MailMessage.IsBodyHtml = $True

$SmtpClient = New-Object Net.Mail.SmtpClient($SmtpServer)
$SmtpClient.Send($MailMessage)
}

#
# Main code
#

# Maximum Password Age
$MaximumAge = (Get-QADObject -LdapFilter
"(objectClass=domainDNS)").MaximumPasswordAge.Days

# 14 days from change
GetUsersToNotify $MaximumAge 14 | %{
NotifyUser $_.Mail $_.PwdLastSet 14
}

# 7 days from change
GetUsersToNotify $MaximumAge 7 | %{
NotifyUser $_.Mail $_.PwdLastSet 7
}

# 1 day from change
GetUsersToNotify $MaximumAge 1 | %{
NotifyUser $_.Mail $_.PwdLastSet 1
}

mdbman66

unread,
Jul 14, 2009, 9:17:16 AM7/14/09
to

Here you go. If you need me to email the file to you please advise.
Watch the line breaks.

function Send-Mail{
param($smtpServer,$from,$to,$subject,$body)
$smtp = new-object system.net.mail.smtpClient($SmtpServer)
$mail = new-object System.Net.Mail.MailMessage
$mail.from = $from
$mail.to.add($to)
$mail.subject = $subject
$mail.body = $body
#$mail.IsBodyHtml = $true
$smtp.send($mail)
}

add-pssnapin "Quest.ActiveRoles.ADManagement"


# get domain maximumPasswordAge password policy
$maximumPasswordAge = (Get-QADObject
(Get-QADRootDSE).defaultNamingContextDN).maximumPasswordAge.value.days
if(!$maximumPasswordAge){
throw "Domain 'MaximumPasswordAge'password policy is not configured
(set to 0)."
}
# exclude users that cannot change password

$ldap = "(!userAccountControl:1.2.840.113556.1.4.803:=64)(mail=*)"


# create calculated property to display days until password expire
$daysUntilExpire =
@{n="daysUntilExpire";e={$maximumPasswordAge-$_.passwordAge.value.days}}

$expireIn = 15


# get enabled users that meet the above criteria

$expiredUsers = Get-QADUser -enabled -passwordNeverExpires $false -size
0 -ldap $ldap | where {($_.passwordAge.value -gt 0) -AND
($_.passwordAge.value.days -lt $maximumPasswordAge) -AND
(($maximumPasswordAge-$_.passwordAge.value.days) -le $expireIn)}
$minLogin = ([datetime]::Now).Date.AddDays(-60)
$newline = [char]13+[char]10
foreach ($user in $expiredUsers) {
if ($user.lastLogonTimestamp.value -eq $null) { continue }
if ($user.lastLogonTimestamp.value -lt $minLogin) { continue }
$remain = $maximumPasswordAge-($user.passwordAge.value.days)
if (($remain % 2) -ne 1) { continue }
$body="The password for your account '"+$user.samAccountName+"' will
expire in $remain days."+$newline+$newline+"To change your password,
YOUR INFORMATION HERE"
$body = $body + $newline+$newline + "YOUR INFORMATION HERE"
$body = $body + $newline+$newline + "YOUR INFORMATION HERE."
$subject="Your password will expire in $remain days"
$to = $user.email
Send-Mail -smtpServer "YOUR SMTP SERVER" -from "YOUR
ADMINISTRATOR ADDRESS" -to $to -subject $subject -body $body
}


--
mdbman66

hogcruzr05

unread,
Jul 14, 2009, 10:40:17 AM7/14/09
to

Thanks for posting this. I am receiving an error tho'... Our domain
policy is set to 90 days, yet I receive-

Domain 'MaximumPasswordAge'password policy is not configured (set to
0).

At C:\scripts\exppwv3.ps1:16 char:6
+ throw <<<< "Domain 'MaximumPasswordAge'password policy is not
configured (set to 0)."

Any idea why I am getting this?
gb


--
hogcruzr05

mdbman66

unread,
Jul 14, 2009, 11:04:35 AM7/14/09
to

no idea, unless you have a line break issue. This command simply checks
the policy and if it is not set then sets it to null


--
mdbman66

Shay Levy [MVP]

unread,
Jul 14, 2009, 11:27:26 AM7/14/09
to
Hi hogcruzr05,

Quest AD cmdlets has chnaged in v1.22 so chnage this line:

$maxPassAge = (Get-QADObject (Get-QADRootDSE).defaultNamingContextDN).MaximumPasswordAge.value.days

to

$maxPassAge = (Get-QADObject (Get-QADRootDSE).defaultNamingContextDN).MaximumPasswordAge.days


HTH

---
Shay Levy
Windows PowerShell MVP
http://blogs.microsoft.co.il/blogs/ScriptFanatic
PowerShell Toolbar: http://tinyurl.com/PSToolbar

h> Thanks for posting this. I am receiving an error tho'... Our domain
h> policy is set to 90 days, yet I receive-
h>
h> Domain 'MaximumPasswordAge'password policy is not configured (set to
h> 0).
h> At C:\scripts\exppwv3.ps1:16 char:6
h> + throw <<<< "Domain 'MaximumPasswordAge'password policy is not
h> configured (set to 0)."
h> Any idea why I am getting this? gb
h>


hogcruzr05

unread,
Jul 14, 2009, 11:37:25 AM7/14/09
to

Ya, it's weird. It does not like the throw statement for some reason.
Hmm. I tried every conceivable type of structure for that line. I am
using PowerGUI script editor, and it gives me the infamous squiggly red
line under the w in throw.. It hates that verb there for some reason
and stops the script.
Anyone out there have any ideas what I am doing wrong?


--
hogcruzr05

hogcruzr05

unread,
Jul 14, 2009, 12:02:53 PM7/14/09
to

That got me through that! Thanks so much.
Now this line barfs- is it the naming context again?
A parameter cannot be found that matches parameter name 'False'.
$expiredUsers = *Get-QADUser* --enabled- --passwordNeverExpires- $false
-size 0 -ldap $ldap | *where* {($_.passwordAge.days -gt 0) -AND
($_.passwordAge.days -lt $maximumPasswordAge) -AND
(($maximumPasswordAge-$_.passwordAge.days) -le $expireIn)}


--
hogcruzr05

Chris Dent

unread,
Jul 14, 2009, 1:07:32 PM7/14/09
to

It should be:

expiredUsers = Get-QADUser -enabled -passwordNeverExpires:$False `
-size 0 -ldap $ldap | `
Where-Object{ ($_.passwordAge.days -gt 0) `


-AND ($_.passwordAge.days -lt $maximumPasswordAge) `
-AND (($maximumPasswordAge-$_.passwordAge.days) -le $expireIn) }

It didn't get how you passed the value for passwordNeverExpires that's all.

Feel free to take out the ` above, I just don't like crowding things :)

Chris

hogcruzr05

unread,
Jul 14, 2009, 1:51:39 PM7/14/09
to

Ahh. Got it. I want to thank everyone who is helping me... I will
become a PowerShell guy if it kills me!
Chris, once I put in the *:*, it gave the following NEW error- (i think
that line hates me!)

Get-QADUser : Invalid filter format:
'userAccountControl:1.2.840.113556.1.4.803:=64)(mail=*'
At C:\scripts\plz.ps1:23 char:28
+ $expiredUsers = Get-QADUser <<<< -enabled
-PasswordNeverExpires:$false -size 0 -ldap $ldap | where
{($_.passwordAge.


days -gt 0) -AND ($_.passwordAge.days -lt $maximumPasswordAge) -AND
(($maximumPasswordAge-$_.passwordAge.days) -le $exp
ireIn)}


--
hogcruzr05

hogcruzr05

unread,
Jul 14, 2009, 4:21:01 PM7/14/09
to

I took out the -ldap and kept the $ldap and the script appears to run.
However, I redirected output to a txt file instead of email for testing,
and the file is empty.
Does anyone have any idea what I am doing wrong?
Thanks in advance.
gb


--
hogcruzr05

Chris Dent

unread,
Jul 14, 2009, 4:39:44 PM7/14/09
to

echo $ldap and tell us the contents of that at the moment? It looks like
a syntax error, nothing more, should be easy to fix (I hope).

Chris

hogcruzr05

unread,
Jul 14, 2009, 5:11:36 PM7/14/09
to

Since $ldap is a string isn't always equal to what is declared? Is this
correct for users who can not change their password?
$ldap =
\\\"(!userAccountControl:1.2.840.113556.1.4.803:=64)(mail=*)\\\"
Here is the entire line I have:
$expiredUsers = *Get-QADUser* --enabled- --passwordNeverExpires-:$False
-size 0 $ldap | *Where-Object*{ ($_.passwordAge.days -gt 0)-AND

($_.passwordAge.days -lt $maximumPasswordAge) -AND
(($maximumPasswordAge-$_.passwordAge.days) -le $expireIn) }
gb


--
hogcruzr05

Chris Dent

unread,
Jul 15, 2009, 5:20:19 AM7/15/09
to

This query won't work. Afraid you can't enumerate "cannot change
password" using userAccountControl (despite the documented flag with the
value you have), instead you have to look at the access control list
assigned to the object.

Just for interest, it's dying with the query because it's not valid.
Changing it to this would allow it to use the query:

$ldap = "(&(!userAccountControl:1.2.840.113556.1.4.803:=64)(mail=*))"

But, that only allows it to use the query string, it doesn't make the
query exclude CannotChangePassword.

Doing that is a bit more complex... it can go something like this:

$expiredUsers = Get-QADUser -passwordNeverExpires:$False `
-Enabled -Size 0 | `
?{ ($_.passwordAge.days -gt 0) `
-AND $_.passwordAge.days -lt $maximumPasswordAge `
-AND ($maximumPasswordAge - $_.passwordAge.days) -le $expireIn `
-AND `
!(Get-QADPermission $_.DN -Deny -Rights "ExtendedRight" `
-ExtendedRight "User-Change-Password") }

It will slow down your query considerably (as well as popping up lots of
yellow warning messages which you can ignore).

Chris

Chris Dent

unread,
Jul 15, 2009, 5:37:07 AM7/15/09
to

Incidentally, if checking for "cannot change password" is a requirement
I would push for you to tailor an LDAP Filter that only returns accounts
which match these two (rather than use Where-Object):

$_.passwordAge.days -gt 0)-AND
($_.passwordAge.days -lt $maximumPasswordAge)

Because if you do that you can at least limit the check for
CannotChangePassword to accounts within the specified range rather than
everyone. Makes quite a difference to the speed of the script.

I suppose you might also pass the results of the first two checks into a
second Where-Object statement to check for whether they can or cannot
change the password. Just stikes me as rather messy (my opinion, of course).

Chris

hogcruzr05

unread,
Jul 15, 2009, 9:21:07 AM7/15/09
to

A post in this thread made me believe that the logic was functional. I
believe a poster named Walt said it was working. Shays code was the
benchmark, and I thought it was working for him.
My question is this- has anyone gotten this logic to work in any way?
I can't imagine that they have, not as it is written. My boss has
handed me a 9 page VBscript that does work. I thought that PowerShell
would be able to handle this type of query. However, I feel that as it
stands now, it isn't possible without reworking the whole script. Shay,
could you please chime in and share your experience with the script that
you say works? I was thinking that it was possible to make the script
work with a few minor tweaks.
Thanks in advance,
gb...


--
hogcruzr05

Chris Dent

unread,
Jul 15, 2009, 10:25:39 AM7/15/09
to

userAccountControl will not give you reliable answers about the
PASSWD_CANT_CHANGE flag (decimal 64). Even AD Users and Computers
enumerates the DACL rather than using the flag.

That doesn't mean enumerating it is impossible (as I hoped to
demonstrate in my previous post), it just means that doing so is more
expensive as it requires a connection to each object.

If you have tens of thousands of objects to enumerate that cost may just
be too high. A few hundred, or even a few thousand, would still return
in a moderately reasonable time-frame.

This is the example using Where-Object twice:

$expiredUsers = Get-QADUser -passwordNeverExpires:$False `
-Enabled -Size 0 | `
?{ ($_.passwordAge.days -gt 0) `
-AND $_.passwordAge.days -lt $maximumPasswordAge `
-AND ($maximumPasswordAge - $_.passwordAge.days) -le $expireIn } | `

?{ !(Get-QADPermission $_.DN -Deny -Rights "ExtendedRight" `
-ExtendedRight "User-Change-Password") }

The first Where-Object drops all objects that don't meet the password
age criteria, only objects that pass the first are processed by the second.

I still feel it would be beneficial to deal with the PwdLastSet date
range within an LDAP filter rather than afterwards using Where-Object.
But I can appreciate that it's makes the code less easy to read :)

Do note that the check for PASSWD_CANT_CHANGE is not specific to any
language, it's a limitation within AD, you would see exactly the same
problem with VbScript. You can only work with what's there.

Chris

jemzzz

unread,
Jul 17, 2009, 2:37:58 AM7/17/09
to

Hi everyone,

I was also looking for a script that can determine a user's password
expiry date and send email notifications when they are about to expire..
I now have a working code (at least on my side), and I am happy to share
it with everyone..

The code below is developed from Shay's code... (I modified the code in
the earlier posts and took out the complex stuff and also modified it to
meet my needs)... This is the first time I've touched powershell and
maybe my code is inefficient and/or is missing a lot of things, but at
least it works for me.. i've tried to put a lot of comments for people
who have just started powershell like me... Hope this helps (watch out
for line breaks):


# Start of script
# Check_password_expiry.ps1
# 16/07/2009
#
# Purpose:
# Powershell script to find out a list of users
# whose password is expiring within x number of days (as specified in
$days_before_expiry).
# Email notification will be sent to them reminding them that they need
to change their password.
#
# Requirements:
# password expiry.ps1 is dependant on Quest.ActiveRoles.ADManagement
snapin to get the AD attributes.
# The Quest.ActiveRoles.ADManagement snapin can be downloaded from
'PowerShell Commands (CMDLETs) for Active Directory by Quest Software'
(http://www.quest.com/powershell/activeroles-server.aspx)
# Look for ActiveRoles Management Shell for Active Directory (both
32-bit or 64-bit versions available)
# Also available in P:\Software\Microsoft\Windows Powershell snap-in.
#
# Note: This script needs to be run with administrator priviledges.
# If script is not run with administrator priviledges,
# Get-QADUser function will not return PasswordExpires and PwdLastSet
attributes correctly.
#
# You might need to sign the powershell script so that it can run in
batch mode (as opposed to interactive mode).
# To do that, you will need to run elevated command prompt, run
powershell (by typing powershell on the command prompt),
# next, type "set-executionpolicy RemoteSigned" (without the double
quotes) on the powershell prompt.


#####################
# Variables to change
#####################

# Days to Password Expiry
$days_before_expiry = 14

# SMTP Server to be used
$smtp = "INSERT YOUR SMTP MAIL SERVER HERE"

# "From" address of the email
$from = "INSERT THE FROM ADDRESS HERE"

# Administrator email
$admin = "INSERT ADMINISTRATOR ADDRESS HERE"

# Define font and font size
# ` or \ is an escape character in powershell
$font = "<font size=`"3`" face=`"Calibri`">"

##########################################
# Should require no change below this line
# (Except message body)
##########################################

function Send-Mail{
param($smtpServer,$from,$to,$subject,$body)
$smtp = new-object system.net.mail.smtpClient($SmtpServer)
$mail = new-object System.Net.Mail.MailMessage
$mail.from = $from
$mail.to.add($to)
$mail.subject = $subject
$mail.body = $body

# Send email in HTML format
$mail.IsBodyHtml = $true
$smtp.send($mail)
}

# Newline character
#$newline = [char]13+[char]10
$newline = "<br>"

# Get today's day, date and time
$today = (Get-date)

# Loads the Quest.ActiveRoles.ADManagement snapin required for the
script.
# (Will unload once powershell is exited)
add-pssnapin "Quest.ActiveRoles.ADManagement"

# Retrieves list of users whose account is enabled, has a password
expiry date and whose password expiry date within (is less than)
today+$days_before_expiry
$users_to_be_notified = Get-QADUser -Enabled
-passwordNeverExpires:$False | Where {($_.PasswordExpires -lt
$today.AddDays($days_before_expiry))}

# Send email to notify users
foreach ($user in $users_to_be_notified) {

# Calculate the remaining days
# If result is negative, then it means password has already expired.
# If result is positive, then it means password is expiring soon.
$days_remaining = ($user.PasswordExpires - $today).days

# Set font for HTML message
$body = $font


# For users whose password already expired
if ($days_remaining -le 0) {

# Make the days remaining positive (because we are reporting it as
expired)
$days_remaining = [math]::abs($days_remaining)

# Add it in a list (to be sent to admin)
$expired_users += $user.name + " - <font color=blue>" +
$user.LogonName + "</font>'s password has expired <font color=blue>" +
$days_remaining + "</font> day(s) ago." + $newline

# If there is an email attached to profile
if ($user.Email -ne $null) {

# Email notification to user
$to = $user.Email
$subject = "Reminder - Password has expired " + $days_remaining + "
day(s) ago."

# Message body is in HTML font
$body += "Dear " + $user.givenname + "," + $newline + $newline
$body += "This is a friendly reminder that your password for account
'<font color=blue>" + $user.LogonName + "</font>' has already expired "
+ $days_remaining + " day(s) ago."
$body += " Please contact the systems administrator to arrange for
your password to be reset."
}
else {

# Email notification to administrator
$to = $admin
$subject = "Reminder - " + $user.LogonName+ "'s Password has expired
" + $days_remaining + " day(s) ago."

# Message body is in HTML font
$body += "Dear administrator," + $newline + $newline
$body += "<font color=blue>" + $user.LogonName+ "</font>'s password
has expired <font color=blue>" + $days_remaining + " day(s)
ago</font>."
$body += " However, the system has detected that there is no email
address attached to the profile."
$body += " Therefore, no email notifications has been sent to " +
$user.Name + "."
$body += " Kindly reset the password and notify user of the password
change."
$body += " In addition, please add a corresponding email address to
the profile so emails can be sent directly for future notifications."
}

# Put a timestamp on the email
$body += $newline + $newline + $newline + $newline
$body += "<h5>Message generated on: " + $today + ".</h5>"
$body += "</font>"

# Invokes the Send-Mail function to send notification email
Send-Mail -smtpServer $smtp -from $from -to $to -subject $subject
-body $body
}

# For users whose password is expiring
# if ($days_remaining -gt 0) {
else {

# Add it in a list (to be sent to admin)
$expiring_users += $user.name + " - <font color=blue>" +
$user.LogonName + "</font> has <font color=blue>" + $days_remaining +
"</font> day(s) remaing left to change his/her password." + $newline

# If there is an email attached to profile
if ($user.Email -ne $null) {

# Email notification to user
$to = $user.Email
$subject = "Reminder - Password is expiring in " + $days_remaining +
" day(s)."

# Message body is in HTML font
$body += "Dear " + $user.givenname + "," + $newline + $newline
$body += "This is a friendly reminder that your password for account
'<font color=blue>" + $user.LogonName + "</font>' is due to expire in "
+ $days_remaining + " day(s)."
$body += " Please remember to change your password before <font
color=blue>" + $user.PasswordExpires.date.tostring('dd/MM/yyyy') +
"</font>."
}
else {

# Email notification to administrator
$to = $admin
$subject = "Reminder - " + $user.LogonName+ "'s Password is expiring
in " + $days_remaining + " day(s)."

# Message body is in HTML font
$body += "Dear administrator," + $newline + $newline
$body += "<font color=blue>" + $user.LogonName+ "</font>'s password
is expiring in <font color=blue>" + $days_remaining + " day(s)</font>."
$body += " However, the system has detected that there is no email
address attached to the profile."
$body += " Therefore, no email notifications has been sent to " +
$user.Name + "."
$body += " Kindly remind him/her to change the password before <font
color=blue>" + $user.PasswordExpires.date.tostring('dd/MM/yyyy') +
"</font>."
$body += " In addition, please add a corresponding email address to
the profile so emails can be sent directly for future notifications."
}

# Put a timestamp on the email
$body += $newline + $newline + $newline + $newline
$body += "<h5>Message generated on: " + $today + ".</h5>"
$body += "</font>"

# Invokes the Send-Mail function to send notification email
Send-Mail -smtpServer $smtp -from $from -to $to -subject $subject
-body $body
}
}

# If there are users with expired password or users whose password is
expiring soon
if ($expired_users -ne $null -and $expiring_users -ne $null) {

# Email notification to administrator
$to = $admin
$subject = "Reminder - Password reminder for domain users."

# Message body is in HTML font
$body = $font
$body += "Dear administrator," + $newline + $newline
$body += "Please note that the users below have needs to change their
password soon." + $newline + $newline + $newline
$body += "<b>Users with expired password:</b>" + $newline
$body += $expired_users + $newline + $newline
$body += "<b>Users with password expiring soon:</b>" + $newline
$body += $expiring_users

# Put a timestamp on the email
$body += $newline + $newline + $newline + $newline
$body += "<h5>Message generated on: " + $today + ".</h5>"
$body += "</font>"

# Invokes the Send-Mail function to send notification email
Send-Mail -smtpServer $smtp -from $from -to $to -subject $subject
-body $body
}

# End of script


To invoke the script, open a command prompt (with elevation), navigate
to where the script is, and type "powershell Check_password_expiry.ps1"
(if the filename is Check_password_expiry.ps1).

Btw, I've only tested the script on my operating system which is a
32bit Windows 2008 Standard Edition and it is a domain controller. But
hopefully it will work for you too.


--
jemzzz

hogcruzr05

unread,
Jul 23, 2009, 4:49:42 PM7/23/09
to

jemzzz,
I have been working on this script for a while, with no luck...
I saw your code and went WOW! Great job. I haven't tried it yet, but
I will first thing in the morning. It's late and I am tired...
Again, even if it doesn't work, it's very well thought out.
One quick question though- why is your font set to 3 for size?


--
hogcruzr05

jemzzz

unread,
Jul 23, 2009, 7:37:28 PM7/23/09
to

Hi hogcruzr05,

I hope the script works for you :) It does not have the fancy ldap
thing that Shay and Chris mentioned, but hey, it works for me :P

If it doesn't work, I suggest that you debug the variables line by line
and pay particular attention to $users_to_be_notified.. I spent a lot of
time on that because I kept getting no results for that, although I
already had the correct logic (it turns out that I needed to run the
whole thing in elevated command prompt).. so, try to play around with it
(execute the Get-QADUser queries step by step to see where the error
is).. And if you are still stuck or you can't get the script to work, do
let me know.. I'm not an expert in this, but I will try my best to help
you out :)

With regards to the font size.. I'm also no HTML expert, but I think
HTML fonts are a little different than normal fonts... Initially I did
set the font to 10 (which I normally use), but I found out in the mail
that it is too big.. After playing around with it, I sticked to 3
because I think it displays the same size as normal font size 10 on my
screen... you can try playing around with it, it will only change the
display if you change the value (does not have any functional effect on
processing the send mail procedure) ;)

Well, I hope this helps and I also hope that the script works for you,
best of luck to you hogcruzr05 ;)


--
jemzzz

Shay Levy [MVP]

unread,
Jul 26, 2009, 7:29:28 AM7/26/09
to

Here's a modified version of the script, you can exe ute it in PowerShell
v1 or v2. Notice that it requires
Quest cmdlets 1.2.2.1254 and above:


$ReqVersion = [version]"1.2.2.1254"
$QadVersion = (Get-PSSnapin Quest.ActiveRoles.ADManagement).Version

if($QadVersion -lt $ReqVersion)
{
throw "Quest AD cmdlets version $ReqVersion is required. Please download
the latest version"
}


function Send-Mail
{
param($smtpServer,$from,$to,$subject,$body)
$smtp = new-object system.net.mail.smtpClient($SmtpServer)
$mail = new-object System.Net.Mail.MailMessage
$mail.from = $from
$mail.to.add($to)
$mail.subject = $subject
$mail.body = $body

$smtp.send($mail)
}


$maxPassAge = (Get-QADObject (Get-QADRootDSE).defaultNamingContextDN).MaximumPasswordAge.days

if($maxPassAge -le 0)
{
throw "Domain 'MaximumPasswordAge' password policy is not configured."
}

$old = 14
$mailForm = "y...@domain.com"
$PSEmailServer = "exServerName"

Get-QADUser -Enabled -PasswordNeverExpires:$false -SizeLimit 0 -Email * | `
Select-Object Name,email,@{n="Expires";e={ $maxPassAge-$_.passwordAge.days
}} | `
Where-Object {$_.Expires -gt 0 -AND $_.Expires -ge $old} | Foreach-Object {
$subject="Your password will expire in $expireIn days"
Send-Mail -smtpServer $PSEmailServer -From $mailForm -To $_.email -subject
$subject -body $subject
}

---
Shay Levy
Windows PowerShell MVP
http://blogs.microsoft.co.il/blogs/ScriptFanatic
PowerShell Toolbar: http://tinyurl.com/PSToolbar

j> Hi hogcruzr05,
j>
j> I hope the script works for you :) It does not have the fancy ldap
j> thing that Shay and Chris mentioned, but hey, it works for me :P
j>
j> If it doesn't work, I suggest that you debug the variables line by
j> line and pay particular attention to $users_to_be_notified.. I spent
j> a lot of time on that because I kept getting no results for that,
j> although I already had the correct logic (it turns out that I needed
j> to run the whole thing in elevated command prompt).. so, try to play
j> around with it (execute the Get-QADUser queries step by step to see
j> where the error is).. And if you are still stuck or you can't get the
j> script to work, do let me know.. I'm not an expert in this, but I
j> will try my best to help you out :)
j>
j> With regards to the font size.. I'm also no HTML expert, but I think
j> HTML fonts are a little different than normal fonts... Initially I
j> did set the font to 10 (which I normally use), but I found out in the
j> mail that it is too big.. After playing around with it, I sticked to
j> 3 because I think it displays the same size as normal font size 10 on
j> my screen... you can try playing around with it, it will only change
j> the display if you change the value (does not have any functional
j> effect on processing the send mail procedure) ;)
j>
j> Well, I hope this helps and I also hope that the script works for
j> you, best of luck to you hogcruzr05 ;)
j>


zb4

unread,
Jul 31, 2009, 2:09:01 PM7/31/09
to
Hi Jemzz,

I've tried running your script on my 2008 DC but had no luck with it and get
the following error message when trying to invoke the script;

PS C:\scripts> C:\Scripts\Check_password_expiry.ps1
The operation '[$null] - [System.DateTime]' is not defined.
At C:\Scripts\Check_password_expiry.ps1:82 char:43
+ $days_remaining = ($user.PasswordExpires - <<<< $today).days
Exception calling "Send" with "1" argument(s): "Failure sending mail."
At C:\Scripts\Check_password_expiry.ps1:60 char:11
+ $smtp.send( <<<< $mail)
Exception calling "Send" with "1" argument(s): "Failure sending mail."
At C:\Scripts\Check_password_expiry.ps1:60 char:11
+ $smtp.send( <<<< $mail)

before i invoked it, i installed powershell and the
Quest.ActiveRoles.ADManagement Snapin version 1.2.2 and i set the execution
policy to unrestricted. I modified the values for smtp server, e-mail address
for administrator and the from address. I invoked the above script with
elevated privileges.

Any suggestions?

Thanks.

Shay Levy [MVP]

unread,
Aug 3, 2009, 7:44:31 AM8/3/09
to

Hi zb4,


I've published the latest version of the script, see if it helps:
http://blogs.microsoft.co.il/blogs/scriptfanatic/archive/2009/08/02/sending-expiry-password-notifications-to-users.aspx


---
Shay Levy
Windows PowerShell MVP
http://blogs.microsoft.co.il/blogs/ScriptFanatic
PowerShell Toolbar: http://tinyurl.com/PSToolbar

z> Hi Jemzz,
z>
z> I've tried running your script on my 2008 DC but had no luck with it
z> and get the following error message when trying to invoke the script;
z>
z> PS C:\scripts> C:\Scripts\Check_password_expiry.ps1
z> The operation '[$null] - [System.DateTime]' is not defined.
z> At C:\Scripts\Check_password_expiry.ps1:82 char:43
z> + $days_remaining = ($user.PasswordExpires - <<<< $today).days
z> Exception calling "Send" with "1" argument(s): "Failure sending
z> mail."
z> At C:\Scripts\Check_password_expiry.ps1:60 char:11
z> + $smtp.send( <<<< $mail)
z> Exception calling "Send" with "1" argument(s): "Failure sending
z> mail."
z> At C:\Scripts\Check_password_expiry.ps1:60 char:11
z> + $smtp.send( <<<< $mail)
z> before i invoked it, i installed powershell and the
z> Quest.ActiveRoles.ADManagement Snapin version 1.2.2 and i set the
z> execution policy to unrestricted. I modified the values for smtp
z> server, e-mail address for administrator and the from address. I
z> invoked the above script with elevated privileges.
z>
z> Any suggestions?
z>
z> Thanks.
z>
z> "jemzzz" wrote:
z>

hogcruzr05

unread,
Aug 13, 2009, 11:30:26 AM8/13/09
to

Hey zb4 and the rest of this thread. I would like to say thanks to Shay
and JEMZZZ. I took a little from each of them and got the script to
work...
zb4- I was getting the same error. I found that the get-qaduser
statement would throw a $null if "User must change pw at next logon is
set". It may have been the case that their password was expiring within
3 days, but if that check box was checked, it hosed the script by
throwing a $null and halted script execution...
I found a property in the get-qaduser cmdlet that made it easy to
filter those people out:
$users_to_be_notified = *Get-QADUser* --Enabled-
--passwordNeverExpires-:$False | *Where* {($_.PasswordExpires -lt
$today.AddDays($days_before_expiration) -and $_.usermustchangepassword
-eq $false)}
This will filter out all users who have change pw at next logon set.
It's that simple...
As far as the email function goes, I have an Exchange 2007 environment.
Be sure to allow relaying from the IP of the box you run the script
from on your HT server. If you are in a 2003 Exchange environment, put
the ip of the box running the script in the allow relaying from this
host area.
I hope this helps! The script works great. Thanks again for all the
help!!


--
hogcruzr05

alpibaba

unread,
Oct 9, 2009, 5:12:57 PM10/9/09
to

First, thanks for all who wrote ideas and code samples for this subject.Actually I am interested in this subject very much but has not tried any code yet because we have a large environment and hesitated to try.I would like to ask you for sending me email about the working code which is able to send notifier to users who have mail attribute and password never expire uncheck attributes if it is possible.(actually filter out users who has no email with password never expire checks)Because we have a lot of service accounts which have no mail attribute and password never expire checks.
Thanks for your help by now...
Best Regards...


hogcruzr05 wrote:

Re: script to determine password expire date and send email notificati
13-Agu-09


--
hogcruzr05

EggHeadCafe - Software Developer Portal of Choice
BOOK REVIEW: Professional Silverlight 2 for ASP.NET Developers [WROX]
http://www.eggheadcafe.com/tutorials/aspnet/3573070a-b0b0-49e5-99c8-cddc274ec7f8/book-revew-professional.aspx

0 new messages