Powershell send-mailmessage从csv读取17,000封电子邮件,每封电子邮件发送给100个用户

时间:2019-09-28 13:35:27

标签: powershell

我正在创建一个PS脚本,以自动向1.7万用户发送电子邮件。我们的交换安全性基准设置为每分钟仅接受60个请求。由于我要逐行循环浏览电子邮件列表(CSV)(休眠1秒),因此脚本需要花费几个小时才能完成。我现在想要实现的目标是,每个请求将电子邮件发送给100个用户。我正在弄清楚如何将电子邮件存储在100个数组中,并在发送下一个100个之前发送邮件。有什么建议吗?

$recipients = Get-Content "mailinglist.csv"

foreach($rcpt in $recipients)
{
    Write-Host "Attempt sending email to $rcpt ..."  
    Send-MailMessage -ErrorAction SilentlyContinue -ErrorVariable SendError -From $From -to $rcpt -Subject $Subject -SmtpServer $SMTPServer -port $SMTPPort -UseSsl -Credential $Cred -BodyAsHtml ($Body -f $Subject, $Date, $Venue, $Description, $Image)
    $ErrorMessage = $SendError.exception.message
                If($ErrorMessage)
            {
                Write-Host "Failure - $ErrorMessage" -ForegroundColor Red
                Start-Sleep -Seconds 60
                Send-MailMessage -ErrorAction SilentlyContinue -ErrorVariable SendError -From $From -to $rcpt -Subject $Subject -SmtpServer $SMTPServer -port $SMTPPort -UseSsl -Credential $Cred -BodyAsHtml ($Body -f $Subject, $Date, $Venue, $Description, $Image)
                }
                ElseIf($SendError.exception.message -eq $null)
                {
                    Write-Host "Email has been sent to $rcpt" -ForegroundColor Green
                    Start-Sleep -Seconds 1
                    $n++
                }

}

Write-Host "Total sent = $n"

1 个答案:

答案 0 :(得分:1)

您可以使用传统的for循环并按索引访问数组元素。

$recipients = Get-Content "mailinglist.csv"
$To = <SomeValidEmailAddress>
$LastIndex = $recipients.GetUpperBound(0)
for ($i = 0; $i -le $LastIndex; $i+=100) {
    $upperRange = [Math]::Min(($i+99),$LastIndex)
    $Params = @{
       ErrorAction = 'SilentlyContinue'
       ErrorVariable = 'SendError'
       Bcc = $recipients[$i..$upperRange]
       To = $To
       From = $From
       Subject = $Subject
       SmtpServer = $SMTPServer
       Port  = $SMTPPort
       Credential $Cred
       Body = $Body -f $Subject, $Date, $Venue, $Description, $Image
       BodyAsHTML = $true
       UseSsl = $true
   }
    "Attempt sending email to $($recipients[$i..$upperRange]) ..."  # You may want to alter this to be more readable
    Send-MailMessage @Params
    # Other code
}

说明:

出于对$Params哈希表的可读性和可管理性,我选择在此处使用Splatting。这完全是可选的。

Send-MailMessage-bcc参数支持字符串数组(string[])。在-To参数上使用此参数将保留收件人的隐私。然后,如果您将电子邮件传递给数组,则可以轻松地将电子邮件发送给多个收件人。 但是,-To才需要Send-Mailmessage 。建议将电子邮件地址传递到-To中,该地址可以是垃圾邮件,或者可以处理这些类型的电子邮件。我已经设置了$To变量供您提供该电子邮件地址。如果根本不关心隐私,可以将-Bcc替换为-To

由于$recipients是一个数组,因此可以按索引访问其元素,该索引支持范围运算符..$recipients[0..99]将是列表中的前100个项目。

$LastIndex存储列表的最后一个索引,该索引是Array.GetUpperBound(Int32)方法以维度0返回的值。由于数组是一维的,因此0是唯一的维。

$upperRange是起始索引($i)加99。如果$upperRange大于$LastIndex,它将被设置为$LastIndex。根据您的PowerShell版本,可能不需要进行$i+99$LastIndex比较。访问超出数组大小的上限范围,将仅返回数组的所有其余元素,而不会引发错误。这可能只是出于完整性。