使用附件时,Send-MailMessage会关闭每个第二个连接

时间:2017-04-11 15:06:23

标签: powershell email smtp smtpclient

我正在尝试编写一个powershell脚本,向30个人发送包含一些附件的电子邮件。电子邮件是个性化的,因此必须单独发送。该脚本可以很好地工作,没有附件。但是,使用附件时,Send-MailMessage的每个其他实例都会失败并显示:

  

Send-MailMessage:无法将数据写入传输连接:   远程主机强行关闭现有连接。

在发送消息之间等待/暂停的时间似乎并不重要。即使我等待几分钟,第一个实例将始终成功,下一个将失败,下一个将成功,我甚至注意到在运行脚本之间,偶数或奇数上的ctrl + c确定了Send-MailMessage的第一个实例的成功。如果最后一条消息失败,则第一条消息成功,反之亦然。

我的代码非常简单,我们只有一个包含所有用户的数组,并且

$array | foreach {
  Write-Host "Sending Mail..."
  Send-MailMessage -From 'myemail@domain' -To $_.EmailAddress 
  -SmtpServer 'fqdn' 
  -Attachments "1.pdf", "2.pdf"
  -Subject 'Subject'
  -Body ($html)
  -BodyAsHtml
}

所以输出将是:

  

发送邮件......

     

发送邮件......

     

Send-MailMessage:无法将数据写入传输连接:   远程主机强行关闭现有连接。

     

发送邮件......

     

发送邮件......

     

Send-MailMessage:无法将数据写入传输连接:   远程主机强行关闭现有连接。

在没有错误的情况下,邮件完好无损地到达。

我可以通过以下方式“解决”这个问题:

try { Send-MailMessage ... -EA Stop }
catch { Send-MailMessage }

结果,30/30人将收到邮件(而不是15/30),因为每次尝试(除了#1)都会失败,但catch块中的代码总是能够成功。

当然,这不是一个真正的解决方案,我不愿意这样离开。有没有人对这里发生的事情有什么了解,以及如何解决它?

2 个答案:

答案 0 :(得分:2)

我相信我找到了最好的解决方案。非常感谢@Matt在评论中帮助我。

似乎问题是Send-Mailmessage在完成发送邮件后没有正确处理连接对象。使用现有连接运行Send-Mailmessage会强制它被处理,因此第三次运行它会导致成功。

解决方法是将Send-Mailmessage的每个实例作为单独的作业运行。引用@Matt:

  

PowerShell作业有自己的内存和资源。当工作是   完成了内存应该被删除。

因此,每次我们将Send-Mailmessage作为作业运行时,都会正确创建和处理连接。我也将它汇总到Wait-Job | Receive-Job以自然限速,查看输出,并防止理论上可能出现的任何内存问题。

Start-Job -ScriptBlock {
  Send-MailMessage -From 'mymail' -To 'theirmail' -SmtpServer 'fqdn' -Attachments "$($args[0])\1.pdf", "$($args[0])\2.pdf" -Subject 'subject' -Body ("test")
} -ArgumentList $PSScriptRoot | Wait-Job | Receive-Job

使用此方法不会产生任何错误,并且应该减少SMTP服务器上的负载。

答案 1 :(得分:1)

错误似乎表明传输层问题。在不了解您的网络架构的情况下,确实有点难以理解。试试这个:

也许为你的foreach循环添加一个等待,看看是否有一个服务器限制你的消息(因为没有更好的词)。如果没有访问服务器配置,您的黑客攻击可能是您可以做到的最好的。

就您的尝试/捕获解决方案而言,这将在您的最终取得最快的成功,但它会增加网络流量。你本质上是粗暴的,迫使你的方式超越你所达到的任何限制。