PowerShell发送带附件邮件:单收件人正常,多收件人延迟/失败
PowerShell批量发送带附件邮件延迟/失败问题排查与解决
问题现象
发送单个收件人时,邮件及附件可在1分钟内正常送达;但发送8个收件人时,邮件需30分钟以上才能送达,甚至直接发送失败。执行代码如下:
# Send the email $rec1 = "someone1@someone.com" $recipients = @( "someone1@someone.com" "someone2@someone.comm" "someone3@someone.com" "someone4@someone.com" "someone5@someone.comm" "someone6@someone.com" "someone7@someone.com" "someone8@someone.com" ) # Set email parameters $smtpServer = "myaddress" $smtpFrom = $rec1 $smtpTo = $recipients $messageSubject = "Subject Placeholder" $messageBody = "Hi, forecast is attached." # Get the latest file in the folder $folderPath = "C:\Users\Forecast" $latestFile = Get-ChildItem $folderPath | Sort-Object LastWriteTime -Descending | Select-Object -First 1 # Set attachment parameters $attachmentPath = $latestFile.FullName $attachmentName = $latestFile.Name # Create and send the email $mailmessage = New-Object system.net.mail.mailmessage $mailmessage.from = ($smtpFrom) $mailmessage.To.add($smtpTo) $mailmessage.Subject = $attachmentName $mailmessage.Body = $messageBody # Attach the latest file $attachment = New-Object Net.Mail.Attachment($attachmentPath) $mailmessage.Attachments.Add($attachment) # Set email client $smtp = New-Object Net.Mail.SmtpClient($smtpServer) # Send email $smtp.Send($mailmessage) # Dispose of the attachment $attachment.Dispose()
问题原因
- 收件人地址拼写错误:代码中
someone2@someone.comm和someone5@someone.comm的域名后缀为.comm(正确应为.com),SMTP服务器会反复尝试投递错误地址,引发重试延迟,甚至触发服务器限流机制。 - 收件人添加方式不当:直接将数组传入
$mailmessage.To.add(),部分SMTP服务器无法正确解析批量地址,导致投递流程异常。 - 无超时设置与错误捕获:默认SMTP客户端超时时间过长,若服务器处理缓慢会持续等待,最终可能超时失败且无法定位问题。
- 服务器批量发送限制:部分SMTP服务器对单次发送的收件人数量、频率有管控,超过阈值会被限流或延迟处理。
解决方案
- 修正所有错误的收件人邮箱地址,确保格式合规。
- 循环遍历收件人列表,逐个添加到邮件对象,避免批量解析问题。
- 为SMTP客户端设置合理超时时间,并添加错误捕获逻辑,便于排查投递问题。
- 若服务器有批量发送限制,可拆分收件人列表分批次发送。
- 完整释放邮件对象和附件资源,避免资源占用引发异常。
修正后的代码示例
# 定义收件人列表(修正错误域名) $recipients = @( "someone1@someone.com", "someone2@someone.com", "someone3@someone.com", "someone4@someone.com", "someone5@someone.com", "someone6@someone.com", "someone7@someone.com", "someone8@someone.com" ) # 邮件参数配置 $smtpServer = "myaddress" $smtpFrom = "someone1@someone.com" $messageSubject = "Subject Placeholder" $messageBody = "Hi, forecast is attached." # 获取文件夹中最新文件 $folderPath = "C:\Users\Forecast" $latestFile = Get-ChildItem $folderPath | Sort-Object LastWriteTime -Descending | Select-Object -First 1 $attachmentPath = $latestFile.FullName # 创建并发送邮件 try { $mailmessage = New-Object System.Net.Mail.MailMessage $mailmessage.From = $smtpFrom # 循环添加收件人 foreach ($recipient in $recipients) { $mailmessage.To.Add($recipient) } $mailmessage.Subject = $latestFile.Name $mailmessage.Body = $messageBody # 添加附件 $attachment = New-Object Net.Mail.Attachment($attachmentPath) $mailmessage.Attachments.Add($attachment) # 配置SMTP客户端,设置30秒超时 $smtp = New-Object Net.Mail.SmtpClient($smtpServer) $smtp.Timeout = 30000 # 发送邮件 $smtp.Send($mailmessage) Write-Host "邮件发送成功" } catch { Write-Error "邮件发送失败: $_" } finally { # 释放所有资源 if ($attachment) { $attachment.Dispose() } if ($mailmessage) { $mailmessage.Dispose() } if ($smtp) { $smtp.Dispose() } }
内容的提问来源于stack exchange,提问作者Knockoutpie
相关产品推荐
相关产品推荐

