Send-MailMessage每10分钟返回4.4.1连接超时



我有一个PowerShell脚本,它从CSV文件导入的联系人列表中生成电子邮件:

# Get Credential
$Credential = & "C:Powershell ScriptsWindowsGet-CredentialFromWindowsCredentialManager.ps1" ms.outlook.15:my.email@domain.com
# Get Contacts
$contacts = Import-Csv -Path "C:Powershell ScriptsEmailContacts.csv"
# Compose Email for each contact
foreach( $contact in $contacts )
{
Write-Output "Creating email for: $($contact.FirstName) $($contact.LastName)"
$To = "$($contact.FirstName) $($contact.LastName) <$($contact.Email)>"
$From = "My Email <my.email@domain.com>"
$Subject = "$($contact.FirstName), I have a suggestion for you!"
$Body = "<html></html>"
$SMTPServer = "smtp.office365.com"
$Port = 587
Send-MailMessage -To $To -From $From -Subject $Subject -SmtpServer $SMTPServer -Credential $Credential -UseSsl -Body $Body -BodyAsHtml -Port $Port
# Due to the Message Send rate limit (30 per minute) I added this to slow the rate down
Start-Sleep -Seconds 10
}

每10分钟我就会收到以下SMTP异常:

发送邮件消息:服务不可用,正在关闭传输通道。这个服务器响应为:4.4.1连接超时。会话总持续时间:00:10:08.3716645在C:\Powershell Scripts\Email\SendEmail.ps1:17 char:2+发送MailMessage-收件人$To-发件人$From-主题$Subject-SmtpServer$SmtpServer。。。+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+类别信息:无效操作:(System.Net.Mail.SmtpClient:SmtpClient)[Send MailMessage],SmtpException+FullyQualifiedErrorId:SmtpException,Microsoft.PowerShell.Commands.SendMailMessage

是否有任何设置可以修改或更改代码以防止此情况发生?

不要把这当成是针对个人的,这只是一个普通的咆哮,但你有一个脚本可以对你无法控制的资源执行操作。因此,您不能只是期望SMTP连接成功,然后想知道应该做些什么来防止它失败。深呼吸。答案是考虑边缘情况,并在代码中实际满足它们。诚然,你有一个睡眠来尝试不违反速率限制,但这不是一个稳健的解决方案。在这种情况下,围绕SendMailMessage调用使用一个简单的异常处理程序就足够了。您可以包括多次重试和少量睡眠延迟。

"可接受故障的最大数量"阈值可用于突破重试循环并引起某种内部警报,例如

长话短说,不要闭着眼睛往墙上扔意大利面条。

<咆哮>

一个例子,但不一定是最整洁的解决方案:

[Int32]   $maxAttempts       = 5;
[Int32]   $failureDelay      = 2;
[Int32]   $interMessageDelay = 10;
[Int32]   $numAttempts       = 0;  
[Boolean] $messageSent       = $false;
:CONTACT foreach ( $contact in $contacts ) {
$numAttempts = 1;
$messageSent = $false;
while ( ($numAttempts -le $maxAttempts) -and (! $messageSent) ) {
try {
Write-Host -Object ( 'Sending message, attempt #{0} of #{1}...' -f $numAttempts, $maxAttempts );
Send-MailMessage <blah>;
Write-Host -Object "Ok.`n";
$messageSent = $true;
} #try
catch [System.Exception] {
# ^^^^^ This exception type needs changing, but I don't know the full
# type of your failure.
Write-Host -Object 'Failed.';
if ( $numAttempts -ge $maxAttempts ) {
Write-Host -Object "ERROR : Maximum attempts reached - aborting.`n";
continue CONTACT;
} else {
Write-Host -Object ( 'Sleeping for {0} second(s)...' -f $failureDelay );
Start-Sleep -Seconds $failureDelay;
$numAttempts++;
} #else-if
} #catch
} #while
Write-Host -Object ( 'Sleeping for {0} second(s)...' -f $interMessageDelay );
Start-Sleep -Seconds $interMessageDelay;
} #foreach

最新更新