PowerShell Send-MailMessage 在发送失败后不会处理附件

问题描述 投票:0回答:2

我的自动 Powershell Hyper-V 备份脚本遇到了一些问题。该脚本运行完美,但我的问题是,当我尝试发送带有日志文件作为附件的电子邮件时,它在发送失败后不会解锁该文件。 (当它成功发送邮件时,我不可能检查它的行为,但说实话,即使它发送失败,它也应该处理它。)

我在整个网络上进行了搜索,我所能找到的就是:

1.) Send-MailMessage 在发送邮件后自动处理附件。

2.) 将 Powershell v1 中的方法与 new-object system.net.mail.mailmessage 和 new-object system.net.mail.attachment 结合使用。

这是我的代码部分(我已将其缩短为仅所需代码的要点):

[String]$ComputerName = Get-Content Env:ComputerName
[String]$LogFile = "Hyper-V Backup Logs\$ComputerName.Hyper-V Backup." + (Get-Date).Day + "-" +(Get-Date).Month + "-" +(Get-Date).Year + "-" +(Get-Date).Hour + "." +(Get-Date).Minute + "." +(Get-Date).Second + ".log"

"# $(Get-Date) :: Attempting to send log file to '[email protected]'..." | Out-File $LogFile -Append
Try
{
    $EmailTo = "[email protected]"
    $EmailFrom = "[email protected]"
    $EmailServer = "server.example.dk"
    $EmailSubject = "An error occurred during Hyper-V Backup on $ComputerName!"
    $EmailBody = "Hello,

    An error occured during Hyper-V Backup on $ComputerName.
        
    I have attached the log file, $LogFile, to this mail.

    Kind Regards,<br></p>
    Hyper-V Backup.
    "
        
    Send-MailMessage -From $EmailFrom -To $EmailTo -Subject $EmailSubject -Body $EmailBody -Attachments $LogFile -SmtpServer $EmailServer
    "# $(Get-Date) :: Successfully send log file to '[email protected]" | Out-File $LogFile -Append

}
Catch
{
    "# $(Get-Date) :: Failed to send log file to '[email protected]" | Out-File $LogFile -Append
    "                      :: Error Command: Send-MailMessage -From $EmailFrom -To $EmailTo -Subject $EmailSubject -Body $EmailBody -Attachments $LogFile -SmtpServer $EmailServer" | Out-File $LogFile -Append
    "                      :: Error Message: $($_.Exception.Message)" | Out-File $LogFile -Append
}

这会引发以下错误:

Out-File : The process cannot access the file 'C:\Hyper-V Backup\Hyper-V Backup
Logs\example.Hyper-V Backup.22-8-2013-13.48.16.log' because it is being used by
another process.
At C:\Hyper-V Backup\Hyper-V Backup.ps1:310 char:163
+ ... [email protected]" | Out-File $LogFile -Append
+                    ~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : OpenError: (:) [Out-File], IOException
    + FullyQualifiedErrorId : FileOpenFailure,Microsoft.PowerShell.Commands.OutFileCommand

如何让 Send-MailMessage 在发送电子邮件失败后处理附件,以便我的脚本可以继续写入日志文件?

email powershell dispose
2个回答
1
投票

这就是我的处理方式,它似乎对我有用:

 try {
    $ErrorActionPreference = 'Stop'
    $SmtpSettings = @{
        To = $Recipients.Split(',')
        From = $Sender
        SmtpServer = $SmtpServer
        Subject = "Email test"
        Body = "Please check attached file"
        Attachment = $Attachment
    }
    Send-MailMessage @SmtpSettings -BodyAsHtml
 } catch {
    $ErrorActionPreference = 'Continue'
    [gc]::collect()
    $CustomError = ($_ -replace "`r`n","")
    $ScriptLine = "$($_.InvocationInfo.ScriptLineNumber)" +','+ "$($_.InvocationInfo.OffsetInLine)"
    Write-Verbose "Error sending email: $CustomError (script line $ScriptLine)"
}

我基本上使用了垃圾收集器 - [gc]::collect(),尽管发送电子邮件时出现错误,但它还是解锁了附件文件。 我还在 try 中设置了 $ErrorActionPreference = 'Stop',这样它就能正确捕获错误,并在 catch 中设置 $ErrorActionPreference = 'Continue',这样脚本就不会完全停止。


0
投票

尝试这种旧风格。对我来说效果很好。

#Send Email
$smtpServer = "10.10.10.10"
$file = "C:\Temp\TEST.zip"
$att = new-object Net.Mail.Attachment($file)
$msg = new-object Net.Mail.MailMessage
$smtp = new-object Net.Mail.SmtpClient($smtpServer)
$msg.From = "[email protected]"
$msg.To.Add("[email protected]")
$msg.CC.Add("[email protected]")
$msg.Subject = "Subject here"
$msg.Body = "Body here"
$msg.Attachments.Add($att)
$smtp.Send($msg)
$att.Dispose()
© www.soinside.com 2019 - 2024. All rights reserved.