2017-04-11 4 views
2

私はpowershellスクリプトを作成して、30人の添付ファイルを含むメールを送信しようとしています。電子メールはパーソナライズされているため、個別に送信する必要があります。このスクリプトは、添付ファイルなしでうまく動作します。添付ファイルを使用するとSend-MailMessageは2回目の接続をすべて終了します

送信-はMailMessage:トランスポート接続にデータを書き込むことができません:添付ファイルを使用している場合しかし、送信-はMailMessageの他のすべてのインスタンスが失敗したと 既存の接続はリモートホストに強制的に切断されました。

メッセージを送信する間にどれくらい待っているか/休止しているかは関係ありません。数分待っても、最初のインスタンスは常に成功し、次は失敗し、次は成功します。スクリプトを実行している間に気付きました。偶数または奇数のctrl + cが成功を決定しますSend-MailMessageの最初のインスタンスの最後のメッセージが失敗すると、最初のメッセージは成功し、その逆もあります。

私のコードは非常に簡単です、私たちは、すべてのユーザーを持つ単一の配列を持っている、と

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

ので、出力はの線に沿って何かになります:

メールを送信

.. 。

メール送信...

送信-はMailMessage:トランスポート接続にデータを書き込むことができません: 既存の接続はリモートホストによって強制的に閉じられました。

メール送信...

メール送信...

送信-はMailMessage: 既存の接続はリモートホストに強制的に切断されました:トランスポート接続にデータを書き込むことができません。

エラーがない場合、メールは完全に完全に届きます。ひとつひとつ試して以来(#1以外にも、

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

をし、その結果として、30/30人々は(というより15/30)メールを受信します:

私はこれだけで行うことで、「修正」することができます)は失敗しますが、catchブロック内のコードは常に成功することができます。

もちろん、これは実際の解決策ではありません。私はそれをそのまま残すのは嫌です。誰がここで何が起こっているのか、どのようにそれを修正するための洞察を持っていますか?

+0

アウトバウンドメールサーバーのように、単一の送信元IPからのアクティブな接続数に厳しい制限がありますか?私はあなたの回避策がひどい解決策ではないと思っています。私は素早くGoogleを行いました。手動で強制的に接続を閉じる強制的な方法はありません。 –

+1

https://www.reddit.com/r/PowerShell/comments/4fhm8z/close_smtp_connection_between_sendmailmessage/ –

+0

添付ファイルを使用すると問題が発生するのはなぜですか?私はこのサーバの制限を認識していないので、添付ファイルを取り除き、何百もの電子メールを数秒で送って何の問題もない。私はこの同じサーバーがちょうど1つのIPから50k +メールを昨日送り出したと思う。 –

答えて

2

私はこれに最も適した解決策を見つけたと思います。コメントでこれを手伝ってくれた@Mattに大変感謝しています。

Send-Mailmessageから問題が発生して、メールの送信が完了したら接続オブジェクトを適切に廃棄していないようです。既存の接続を持つSend-Mailmessageを実行すると、その接続が強制的に破棄され、3回目の実行で成功します。

回避策は、別のジョブとして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サーバーの負荷を軽減する必要があります。

+0

あなたたちは私を救った。完了:ログファイルを送信したいが、 'Send-Mailmessage'がエラー(すなわち、サーバからのsmtpエラー)であった場合、ログファイルはアクセス不可能であった。 – Boop

1

エラーは、トランスポート層の問題を示しているようです。ネットワークアーキテクチャが分からなければ、確かに知るのは少し難しいでしょう。これを試してみてください:

あなたのメッセージを抑制しているサーバーがあるかどうかをforeachループに確認してください。サーバーの設定にアクセスできない場合、あなたのハックはおそらくこれで可能です。

あなたのtry/catchソリューションでは、それはあなたの目的で最も速い成功を収めていますが、ネットワークトラフィックが増加します。あなたは、本質的にはブルートゥースで、あなたが叩いている限界を過ぎてあなたの道を過ぎ去らせている。

+0

返信いただきありがとうございます。私が言及したように、待ち時間はこれをまったく修正していないようです。しかし、サーバーに負荷をかけることについてあまり心配しているわけではないので、接続試行回数を最大2倍にする無理な力は大きな問題ではありません。私はそれを行うことの怠慢を嫌い、その接続試行の約50%が失敗することが保証されたスクリプトをプロダクションに入れます... –

+0

完全に取得してください。私もそこに残してくつろいだが、その日の終わりに、あなたは何かを見つけた。 SMTPはそれ自身の動物です。うまくいけば、SMTPネックひげがチャイムに入ります。 – primohacker

関連する問題