首页 > 解决方案 > 在第一封电子邮件之后,Send-MailMessage 充满了“System.Object[]”

问题描述

我编写了一段 powershell 代码,用于根据从表中提取的信息(以及某些条件)向不同的用户发送电子邮件。

#extraction skipped

foreach($row in $result) {

    Clear-Variable template* -Scope Global
    
    $template = (Get-Content "C:\template.html")

    #user definition skipped

        $message = "Hello..."      

        $html = $template |
            ForEach-Object { if($_.Trim() -eq "<p>$[CONTENT]</p>") {
              -join(($_).ToString().Replace("$[CONTENT]", $message),$html)
              } else { -join($_, $html) }
            }

        Send-MailMessage -From $fromAddr -To $mail -Bcc $maintainer -Subject $sub -Body ($html | Out-String) -BodyAsHtml -SmtpServer $smtpserver -Encoding UTF8
}


如果您需要其他任何内容,请随时提出,我觉得这是代码的相关部分,但我不是 100% 确定。

问题:基本上,如果我只有一个用户,电子邮件文本看起来不错。如果有超过一封$row,第二封电子邮件充满了System.Object[].

错误生成的电子邮件示例

我不确定我做错了什么。我的猜测是ForEach-Object,但为什么要为第一个而不是以下工作?

提前感谢您的帮助。

标签: powershell

解决方案


第二次迭代中代码中的问题是它基本上是这样做的:

$html = $template | ... -join($_, $html) ...

where$html仍然包含第一次迭代的值,因此您将新$message的内容与第一封电子邮件文本的全部内容结合在一起,并且有点麻烦。

如果您添加以下内容,则可以避免这种情况:

$html = $null
$html = $template | ... -join($_, $html)

所以每次迭代都有一个干净的开始。

话虽如此,您可以按照@Mathias R. Jessen 的建议进行操作,并将整个模板逻辑替换为:

$body = -join @((Get-Content .\template.html) -replace '\$\[CONTENT\]', $message)

或更简洁地说,这是:

$body = (Get-Content .\template.html -Raw).Replace("`$[CONTENT]", $message)

推荐阅读