Send-MailMessage closes every 2nd connection when

2019-05-25 07:41发布

I am attempting to write a powershell script to send email with a few attachments to 30 people. The emails are personalized, so they must be sent individually. The script works just fine without attachments. However, when using attachments, every other instance of Send-MailMessage fails with:

Send-MailMessage : Unable to write data to the transport connection: An existing connection was forcibly closed by the remote host.

It does not seem to matter how long I wait/pause between sending messages. Even if I wait several minutes, the first instance will always succeed, the next will fail, the next will succeed, etc.. I've even noticed between running scripts, that my ctrl+c on even or odd numbers determines the success of the first instance of Send-MailMessage. If the last message fails, the first succeeds, and vice versa.

My code is very simple, we just have a single array with all the users, and

$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
}

So the output will be something along the lines of:

Sending Mail...

Sending Mail...

Send-MailMessage : Unable to write data to the transport connection: An existing connection was forcibly closed by the remote host.

Sending Mail...

Sending Mail...

Send-MailMessage : Unable to write data to the transport connection: An existing connection was forcibly closed by the remote host.

And in the instances where there are no errors, the mail arrives perfectly intact.

I can "fix" this by just doing:

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

And as a result, 30/30 people will receive the mail (rather than 15/30), since every single try (besides #1) fails but the code in the catch block is always able to succeed.

Of course, this isn't a real solution and I would hate to leave it like that. Does anyone have any insight into what is going on here, and how to fix it?

2条回答
SAY GOODBYE
2楼-- · 2019-05-25 08:19

I believe I have found the best available solution to this. Big thanks to @Matt for helping me with this in the comments.

It seems like the issue spawns from Send-Mailmessage not properly disposing the connection object once it finishes sending mail. Running Send-Mailmessage with an existing connection forces it to be disposed, and thus running it for a third time results in success.

The workaround is running each instance of Send-Mailmessage as a separate job. To quote @Matt:

PowerShell jobs have their own memory and resources. When the job is done that memory is supposed to be removed.

As a result, each time we run Send-Mailmessage as a job, the connection is properly created and disposed. I am also piping this to Wait-Job | Receive-Job to naturally rate-limit, view output, and prevent any memory issues that could maybe be theoretically possible.

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

Using this method produces no errors, and should reduce load on the SMTP server.

查看更多
小情绪 Triste *
3楼-- · 2019-05-25 08:40

The error seems to indicate a transport layer issue. Without knowing your network architecture it's a little tough to know for sure. Try this:

Maybe add a wait to your foreach loop to see if there is a server that is throttling (for lack of better word) your messages. Without access to the server config, your hack is likely the best you can do with this.

As far as your try/catch solution, that is going to produce the fastest success on your end, however, it will increase network traffic. You are essentially brute forcing your way past whatever limits you are hitting.

查看更多
登录 后发表回答