【问题标题】:Powershell send-mailmessage to read 17k emails from csv & send to 100 users in each emailPowershell send-mailmessage 从 csv 读取 17k 封电子邮件并在每封电子邮件中发送给 100 个用户
【发布时间】:2019-09-28 13:35:27
【问题描述】:

我正在创建一个 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"

【问题讨论】:

  • 您可能想添加一条说明,说明您为什么不使用为此类事情设计的服务之一。 [grin] ///// 这就是说,您可以通过按索引抓取它们来从数组中创建一批项目 - 有点像数组中的“切片”。 0..99,然后是100..199,等等……
  • 您正在阅读 CSV 文件,就好像它只是单独一行的电子邮件地址列表一样。是这样的话,那很好,但如果它真的 IS 是 CSV,请显示前 3 或 4 行。正确的 CSV 具有标题并且可以包含多个字段。为此,请使用 Import-Csv cmdlet。这样,没有人知道你的 $recipients 数组中有什么。另外,我建议你使用 Splatting 来保持代码的可读性和可维护性。

标签: powershell


【解决方案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
}

说明:

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

Send-MailMessage-bcc 参数支持字符串数组(string[])。在-To 参数上使用它可以保护收件人的隐私。然后,您可以轻松地将电子邮件发送给多个收件人,前提是您将其传递给数组。 但是,-To 需要 Send-Mailmessage 才能工作。建议将传递到-To 的电子邮件地址设置为可以发送垃圾邮件或具有处理这些类型电子邮件的方法。我已经为您设置了$To 变量来提供该电子邮件地址。如果隐私无关紧要,-Bcc 可以直接替换为 -To

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

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

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

【讨论】:

  • 不错! [grin] 我有一个评论,你可以用.GetUpperBound(0) 直接推导出集合的上限,我认为零是你想要上限的轴。跨度>
  • 我改用那个方法了。
  • neato!逻辑似乎更清晰......谢谢! [咧嘴一笑]
  • 使用 bcc 参数更新。安息吧朋友
  • 太棒了!我可能错了,但我认为-To 中至少需要一个收件人。通常这是一个没人能读到的地址。
猜你喜欢
  • 2012-05-01
  • 2011-02-08
  • 2017-06-05
  • 1970-01-01
  • 1970-01-01
  • 2015-10-13
  • 1970-01-01
  • 2016-07-17
  • 2012-08-20
相关资源
最近更新 更多