PowerShell中Send-MailMessage异常无法被Try/Catch捕获的问询
解决PowerShell中Send-MailMessage异常无法捕获的问题
问题根源
Send-MailMessage抛出的SmtpException默认是非终止错误,PowerShell默认错误行为是继续执行后续代码,不会触发try/catch块,只会将错误信息写入$Error集合。这就是你的catch块未执行、错误信息直接输出到控制台的原因。
解决方案
要捕获这类错误,需强制将非终止错误转为终止错误,以下是两种常用方式:
方式1:给Send-MailMessage添加-ErrorAction Stop参数
这是最精准的处理方式,仅针对当前命令修改错误行为:
$SMTPServer = "IAmDown" $FromAddress = "someone@somewhere.com" $subject = "I was here" $Subject = "$($env:COMPUTERNAME): $($Subject)" $Recipients = "email@test.com" $Message = "I won't be sent" $errorMessage = "" try { # 添加-ErrorAction Stop,强制将非终止错误转为终止错误 Send-MailMessage -SmtpServer $SMTPServer -To $Recipients -From $FromAddress -Subject $Subject -Body $Message -ErrorAction Stop } catch [System.Net.Mail.SmtpException] { $errorMessage = "In catch: $($_.Exception.Message)" } catch { # 捕获其他类型异常(如DNS解析失败可能抛出WebException) $errorMessage = "In general catch: $($_.Exception.Message)" } return $errorMessage
方式2:临时修改全局错误偏好
如果需要让脚本内所有命令都将错误转为终止错误,可修改全局错误偏好,注意使用后恢复原有设置:
# 保存原有错误偏好 $originalErrorAction = $ErrorActionPreference $ErrorActionPreference = "Stop" try { Send-MailMessage -SmtpServer $SMTPServer -To $Recipients -From $FromAddress -Subject $Subject -Body $Message } catch [System.Net.Mail.SmtpException] { $errorMessage = "In catch: $($_.Exception.Message)" } finally { # 恢复原有错误偏好 $ErrorActionPreference = $originalErrorAction }
补充说明
LASTEXITCODE仅用于存储外部可执行程序的退出码,PowerShell内置cmdlet的错误不会更新该变量,因此它为空是正常现象。- 捕获异常时,优先使用
$_.Exception.Message获取错误信息,比直接访问$Error[0]更可靠——$Error集合会累积所有错误,而$_指向当前捕获的异常对象。
内容的提问来源于stack exchange,提问作者Erica Ackerman
相关产品推荐
相关产品推荐

