如何将PowerShell脚本执行错误传递给Windows任务计划程序
解决任务计划程序未捕获PowerShell脚本错误的问题
核心问题在于:任务计划程序仅通过脚本的退出码判断任务是否失败。默认情况下,PowerShell即使内部执行出错(比如Send-MailMessage失败),只要没有显式返回非零退出码,任务就会被标记为「成功」,自然不会触发重试。
一、让脚本在出错时返回非零退出码
要让任务计划程序识别到错误,必须让脚本在Send-MailMessage失败时返回非零值(通常用exit 1)。具体实现可以用try/catch结合错误终止设置:
# 开启终止错误模式,任何错误都会中断脚本执行 $ErrorActionPreference = 'Stop' try { # 替换成你的邮件参数 Send-MailMessage ` -From "你的邮箱@example.com" ` -To "接收邮箱@example.com" ` -Subject "系统重启通知" ` -Body "电脑已完成重启" ` -SmtpServer "smtp.example.com" ` -Port 587 ` -UseSsl ` -Credential (Get-StoredCredential -Target "SMTP_Cred") # 建议用存储凭据避免明文密码 } catch { # 记录错误信息(可选,可写入日志) Write-Error "发送邮件失败: $($_.Exception.Message)" # 返回非零退出码,告知任务计划程序任务失败 exit 1 }
关键说明:
$ErrorActionPreference = 'Stop':将所有非终止错误转为终止错误,确保Send-MailMessage失败时进入catch块。exit 1:返回非零退出码,这是任务计划程序识别「任务失败」的核心依据。
二、配置任务计划程序的重试规则
确保任务的重试设置正确生效:
- 打开任务计划程序,找到你的任务,右键选择「属性」。
- 切换到「设置」选项卡。
- 勾选「如果任务失败,每隔[X]分钟重试」,设置重试间隔(比如5分钟)和重试次数(比如3次)。
- 确认「尝试重新启动任务」的相关选项配置正确。
三、额外优化:提前检测网络连通性
为了避免因网络未就绪直接触发错误,可以在发送邮件前先测试SMTP服务器的连通性:
$smtpServer = "smtp.example.com" $smtpPort = 587 # 测试SMTP端口是否可连通 $connectionTest = Test-NetConnection -ComputerName $smtpServer -Port $smtpPort if (-not $connectionTest.TcpTestSucceeded) { Write-Error "无法连接到SMTP服务器端口$smtpPort,网络可能未就绪" exit 1 } # 后续的发送邮件逻辑同上...
四、为什么之前的重试没生效?
你之前模拟错误时脚本输出失败信息,但任务计划程序仍标记为成功,原因是:
- 默认
$ErrorActionPreference = 'Continue',Send-MailMessage的错误属于非终止错误,脚本会继续执行到末尾,返回默认的0退出码。 - 任务计划程序只认退出码,
0代表成功,所以不会触发重试。
内容的提问来源于stack exchange,提问作者ChrisHD
相关产品推荐
相关产品推荐

