Get-ADUser Question

I am new to Powershell and am trying to use the following script to send out an email to notify users that their password will expire in a specific OU. But it keeps getting errors (see below script).

#Get Users From AD who are enabled
Import-Module ActiveDirectory
$users = get-aduser -filter * -SearchBase “OU=Users,DC=Test,DC=local” -properties * | where {$.Enabled -eq “True”} | where { $.PasswordNeverExpires -eq $false } | where { $_.passwordexpired -eq $false }

foreach ($user in $users)
$Name = (Get-ADUser $user | foreach { $.Name})
$emailaddress = $user.emailaddress
$passwordSetDate = (Get-ADuser $user -properties * | foreach { $
.PasswordLastSet })
$maxPasswordAge = (Get-ADDefaultDomainPasswordPolicy).MaxPasswordAge
$expireson = $passwordsetdate + $maxPasswordAge
$today = (get-date)
$daystoexpire = (New-TimeSpan -Start $today -End $Expireson).Days
$subject=“Your password will expire in $daystoExpire days” }


Get-ADUser : Cannot validate argument on parameter ‘Identity’. The argument is null. Supply a non-null argument and try the command again.
At C:\Users\jradin\Desktop\Password Change Notification.ps1:14 char:22

  • $Name = (Get-ADUser <<<< $user | foreach { $_.Name})
    • CategoryInfo : InvalidData: (:slight_smile: [Get-ADUser], ParameterBindingValidationException
    • FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.ActiveDirectory.Management.Commands.GetADUser

Any help would be greatly appreciated.

$user already refers to an object returned by the Get-ADUser cmdlet; why call Get-ADUser again inside the loop? You should be able to just do $Name = $user.Name

Edit: On a side note, you’ll get much better performance by using the -Filter parameter instead of pulling all users and then piping it to Where-Object. For example:

$users = get-aduser -filter 'Enabled -eq $true -and PasswordNeverExpires -eq $false -and PasswordExpired -eq $false' -SearchBase 'OU=Users,DC=Test,DC=local' -properties *

You can also speed things up by only pulling back the properties you need, rather than using “-Properties *”.

I don’t see a statement for

Send-MailMessage ...message here...

In testing out the ability of Power Shell to send mail I threw together something similar to the following and it seems to work

Send-MailMessage –From –To –Subject “Message from God” –Body “Stop playing with yourself.” -SmtpServer

Great, now I have to go watch Real Genius again. Thanks a lot, notarat. :stuck_out_tongue:

Thanks for the help (there is a Send-MailMessage, just didn’t include it in the original post). So now getting a few new errors:

New-TimeSpan : Cannot bind parameter ‘End’. Cannot convert the “00:00:00” value of type “System.TimeSpan” to type “System.DateTime”.
At C:\Users\jradin\Desktop\Password Change Notification.ps1:20 char:51

  • $daystoexpire = (New-TimeSpan -Start $today -End <<<< $Expireson).Days
    • CategoryInfo : InvalidArgument: (:slight_smile: [New-TimeSpan], ParameterBindingException
    • FullyQualifiedErrorId : CannotConvertArgumentNoMessage,Microsoft.PowerShell.Commands.NewTimeSpanCommand

Send-MailMessage : Cannot validate argument on parameter ‘To’. The argument is null or empty. Supply an argument that is not null or empty and then try the command again.
At C:\Users\jradin\Desktop\Password Change Notification.ps1:34 char:61

  • Send-Mailmessage -smtpServer $smtpServer -from $from -to &lt;&lt;&lt;&lt;  $emailaddress -subject $subject -body $body -bodyasHTML -priority High
    • CategoryInfo : InvalidData: (:slight_smile: [Send-MailMessage], ParameterBindingValidationException
    • FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.SendMailMessage

Updated code below:
#Get Users From AD who are enabled
Import-Module ActiveDirectory
$users = get-aduser -filter ‘Enabled -eq $true -and PasswordNeverExpires -eq $false -and PasswordExpired -eq $false’ -SearchBase ‘OU=Users,DC=Test,DC=local’ -properties *

foreach ($user in $users)
$Name = $user.Name
$emailaddress = $user.emailaddress
$passwordSetDate = (Get-ADuser $user -properties * | foreach { $_.PasswordLastSet })
$maxPasswordAge = (Get-ADDefaultDomainPasswordPolicy).MaxPasswordAge
$expireson = $passwordsetdate + $maxPasswordAge
$today = (get-date)
$daystoexpire = (New-TimeSpan -Start $today -End $Expireson).Days
$subject=“Your password will expire in $daystoExpire days”
$body ="
Dear $name,
<p> Your Windows/Email Password will expire in $daystoexpire days.<br>
To change your password on a PC press CTRL ALT Delete and chose Change Password<br>
If you are not on a PC, please login to webmail (, click on Options, then See all options, then Change your password<br>
NOTE: If you change your Windows/Email Password, you must also change it on your Mobile Device (iPhone, iPad, Android).<br>
<p>If you need assitance, please email<br>
<p>Thank You!<br>

if ($daystoexpire -lt $expireindays)
Send-Mailmessage -smtpServer $smtpServer -from $from -to $emailaddress -subject $subject -body $body -bodyasHTML -priority High



Your $emailaddress variable is empty. You need to validate that $user.emailaddress actually contains something. Try using Write-Verbose or Write-Host to output your variables’ contents before you use those variables - that will help catch the problem. $Expireson is also empty. I suspect you can’t simply add $passwordsetdate - it is very likely not a DateTime.

Lol! I’m half watching it right now in the test lab on my Asus Transformer while I’m coding scripts to search my network shares for JPG files over 400KB and run them through irfanview to convert them to reduce file sizes…

Thanks God furlough is over (for this week)