You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PowerShell中Send-Mailmessage结合Try-Catch-Finally执行异常问题

问题:PowerShell脚本中Try-Catch-Finally的Finally块条件未生效

在账户过期通知邮件脚本中,finally块内的if ($error.Count -eq 0)条件始终不触发,导致$countsent0无法递增,也无法设置对应$sent值。目前catch块(发送失败时递增$countfailed、设置$sent = "Send fail")和else块(无邮箱时递增$countnotsent、设置$sent = "No")均正常工作。

原因分析

$error是PowerShell的全局错误集合,脚本执行过程中之前的操作可能已经产生了错误,即使当前try块内的Send-Mailmessage执行成功,$error.Count也可能不为0,导致条件判断失效。用全局错误集合判断当前try块的执行结果并不可靠。

解决方案

改用局部变量标记当前try块的执行状态,替代对全局$error集合的判断。

修改后的代码示例1(保留finally块)

Write-Host $sName " : Selected to receive email: password will expire in "$days
if (($emailaddress) -ne $null) {
    $sendSuccess = $false  # 初始化发送成功标记
    try {
        Send-Mailmessage -smtpServer $SMTPServer -from $MailSender -to $emailaddress -subject $subject2 -body $EmailBody -bodyasHTML -priority High -Encoding $textEncoding -ErrorAction Stop 
        $sendSuccess = $true  # 发送成功时更新标记
        $sent = "Sent"
    } 
    catch {
        write-host "Error: Could not send email to $recipient via $smtpServer"
        $sent = "Send fail"
        $countfailed++
    } 
    finally {
        if ($sendSuccess) {
            write-host "Sent email for $sName to $emailaddress"
            $countsent0++
        }
    }
} else {
    Write-Host "$dName ($sName) has no email address."
    $sent = "No"
    $countnotsent++
}

修改后的代码示例2(省略finally块,更简洁)

如果不需要在finally中执行清理操作,可以直接将成功逻辑放在try块内,无需依赖finally:

Write-Host $sName " : Selected to receive email: password will expire in "$days
if (($emailaddress) -ne $null) {
    try {
        Send-Mailmessage -smtpServer $SMTPServer -from $MailSender -to $emailaddress -subject $subject2 -body $EmailBody -bodyasHTML -priority High -Encoding $textEncoding -ErrorAction Stop 
        write-host "Sent email for $sName to $emailaddress"
        $countsent0++
        $sent = "Sent"
    } 
    catch {
        write-host "Error: Could not send email to $recipient via $smtpServer"
        $sent = "Send fail"
        $countfailed++
    }
} else {
    Write-Host "$dName ($sName) has no email address."
    $sent = "No"
    $countnotsent++
}

关键修改点

  1. 用局部变量$sendSuccess标记当前发送操作的结果,避免受全局错误集合干扰。
  2. 将发送成功后的逻辑(更新计数器、设置$sent值)直接放在try块内,确保只有发送成功时才执行。

内容的提问来源于stack exchange,提问作者Felix

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 12:10:29