You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PowerShell发送SMTP邮件至多收件人时遇收件人指定错误

Fix: "A recipient must be specified" Error in PowerShell Password Reminder Script

The error you're seeing is almost certainly because some users in your $ExpiredUsers collection don't have an email address set in Active Directory. When your script tries to add $User.EmailAddress to the email's recipient list, it's passing an empty or null value—so the SMTP client throws an error because there's no valid recipient to send to.

Here's how to fix this, step by step:

1. Filter Out Users Without Email Addresses Upfront

First, update your Get-ADUser command to only include users who have a non-empty Mail property in AD. This avoids pulling in users you can't email anyway:

$ExpiredUsers = Get-ADUser -Filter {(PasswordLastSet -lt $emailDate) -and (PasswordLastSet -gt $expiredDate) -and (PasswordNeverExpires -eq $false) -and (Enabled -eq $true) -and (Mail -ne "$null")} -Properties PasswordNeverExpires, PasswordLastSet, Mail | select samaccountname, PasswordLastSet, @{name = "DaysUntilExpired"; Expression = {$_.PasswordLastSet - $ExpiredDate | select -ExpandProperty Days}}, @{name = "EmailAddress"; Expression = {$_.mail}} | Sort-Object PasswordLastSet

The key addition here is -and (Mail -ne "$null") in the filter.

2. Add a Safety Check in the Loop

Even with the upfront filter, it's good practice to add a check for empty email addresses in your loop. This will catch any edge cases and let you log which users are being skipped:

# Reuse the SMTP client outside the loop for better performance
$smtpServer = "smtpserver.domain.com"
$smtp = New-Object Net.Mail.SmtpClient($smtpServer)

Foreach ($User in $ExpiredUsers) {
    # Skip users with no email address
    if ([string]::IsNullOrEmpty($User.EmailAddress)) {
        Write-Warning "Skipping user $($User.samaccountname) - no email address found in Active Directory"
        continue
    }

    # Build the email
    $msg = New-Object Net.Mail.MailMessage
    $msg.From = "noreply@hdomain.com"
    $msg.To.Add($User.EmailAddress)
    $msg.Subject = "Your Password Will Expire Soon"
    $msg.Body = @"
Hi $($User.samaccountname),

Your password will expire in $($User.DaysUntilExpired) days. Please reset it at your earliest convenience to avoid service disruption.

Thanks,
The IT Team
"@

    # Send with error handling
    try {
        $smtp.Send($msg)
        Write-Host "Successfully sent reminder to $($User.EmailAddress)"
    }
    catch {
        Write-Error "Failed to send email to $($User.EmailAddress): $_"
    }
    finally {
        # Clean up the mail message object to free memory
        $msg.Dispose()
    }
}

# Clean up the SMTP client when done
$smtp.Dispose()

3. Verify the Issue (Optional)

To confirm which users are missing email addresses, run this before your loop:

$ExpiredUsers | Where-Object { [string]::IsNullOrEmpty($_.EmailAddress) } | Select-Object samaccountname, PasswordLastSet

This will list all users in your filtered set who don't have an email configured in AD.

Bonus Optimization

By moving the $smtp client creation outside the loop, you avoid reinitializing a new SMTP connection for every email—this makes the script faster and more efficient, especially if you have a lot of users to email.

内容的提问来源于stack exchange,提问作者xs0u1x

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 17:12:58