首页 > 解决方案 > Powershell send-mailmessage 从 csv 读取 17k 电子邮件并在每封电子邮件中发送给 100 个用户

问题描述

我正在创建一个 PS 脚本来自动向 17k 用户发送电子邮件。我们的交易所安全基线设置为每分钟仅接受 60 个请求。因为我逐行(睡眠 1 秒)循环浏览电子邮件列表 (CSV),所以我的脚本需要几个小时才能完成。我现在想要实现的是将电子邮件发送给每个请求的 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"

标签: powershell

解决方案


您可以使用传统的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
}

解释:

我选择在这里使用Splatting$Params来提高哈希表的可读性和可管理性。它完全是可选的。

Send-MailMessage-bcc参数支持字符串数组()。在参数上使用它将保护收件人的隐私。然后,您可以轻松地将电子邮件发送给多个收件人,前提是您将其传递给数组。但是,工作是必需的。建议将电子邮件地址设置为可以发送垃圾邮件或具有处理这些类型电子邮件的方法的电子邮件地址。我已经为您设置了变量以提供该电子邮件地址。如果隐私无关紧要,可以用.string[]-To-ToSend-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访问超出数组大小的上限范围,只会返回数组的所有剩余元素,而不会引发错误。这可能只是为了完整性。


推荐阅读