如何让任务调度程序从PowerShell脚本中检测失败的错误代码

eqoofvh9  于 2022-11-10  发布在  Shell
关注(0)|答案(5)|浏览(202)

我有几个PowerShell脚本,当它们内部有故障时,我试图在Windows任务调度程序中将它们触发为失败状态。因此,我在PowerShell脚本中执行类似的操作。我尝试了退出代码1或99,看起来Windows任务调度程序并未将其视为失败状态。这样我的失败代码电子邮件就不会被发送出去通知我。
如何让任务调度程序查看我的PowerShell脚本是否失败?事件代码始终为129(已创建任务流程)、100(任务开始)、200(动作开始)、110(任务触发)、201(动作完成)、102(任务完成)。

$global:ErrorStrings = New-Object System.Collections.Generic.List[System.Object] #I add strings onto the list as I find errors

$errorCodeAsString = ""
foreach ($item in $global:ErrorStrings.Members){
   $errorCodeAsString += (" " + $item + "..")
}
if($errorCodeAsString -ne "")
{
   write-output  "Error: $errorCodeAsString"
   Exit 99 #Exit 1 didn't cause task scheduler to see error at exit either
}
Exit 0

我知道我的列表充满了错误,因为我创建它们是为了测试它。我检查了errorCode as字符串是一个长度,并命中了出口99或1。任务调度程序仍然显示正常的事件代码。
我计划了一个关于失败的电子邮件警报,因为事件代码没有显示失败,所以它永远不会触发发送我的电子邮件。这是Windows10,以防万一。
我一直在查看PowerShell错误SQL、task scheduler success errortips tricks scheduled taskspowershell exit code,但没有帮助。
PowerShell脚本在任务调度程序中设置如下:

**操作:**启动程序
**程序/脚本:**PowerShell
添加参数:-执行策略绕过-文件C:\Users\me\Documents\powershell\disasterBackup.ps1

3df52oht

3df52oht1#

第1部分是让PowerShell将正确的上次退出代码返回给任务计划程序。
这是任务调度器的特点之一。它只是报告说,是的,PowerShell.exe运行成功。问题是PowerShell.exe不报告退出代码,因为,是的,PowerShell.exe运行正确,即使脚本没有正确运行。
我能够解决这个问题的方法是从使用-File参数运行脚本切换到-Command参数,-File参数不返回退出值。这样,我就可以通过显式退出$LASTEXITCODE值来使用正确的退出代码退出PowerShell.exe


# Run Scheduled task with the following command

powershell.exe -Command ". C:\Scripts\RunScript.ps1; exit $LASTEXITCODE"

因此,在您的情况下,它将是:

powershell.exe -ExecutionPolicy Bypass -Command ". C:\Users\me\Documents\powershell\disasterBackup.ps1; exit $LASTEXITCODE"

-编辑
第2部分是让计划任务在无法发送电子邮件或其他内容时触发事件。
任务计划程序的问题与我们退出PowerShell时遇到的问题相同。无论返回什么退出代码,任务都会记录一个事件ID 201-操作已完成...这是正确的..。无论如何,即使运行的作业在内部失败,任务也会完成。
进一步查看记录的事件的详细信息,我们可以看到EventData中的ResultCode确实设置正确。因此,通过图形用户界面对其进行过滤是一项简单的工作,对吗?嗯,不..。除了EventID之外没有任何筛选器。现在,我们必须编写一个基于ResultCode的自定义事件筛选器来触发。我们需要的XML XPath查询如下所示:

<QueryList>
  <Query Id="0" Path="Microsoft-Windows-TaskScheduler/Operational">
    <Select Path="Microsoft-Windows-TaskScheduler/Operational">
      *[System[(Level=4 or Level=0) and (EventID=201)]]
        and
      *[EventData[Data[@Name='ResultCode'] and (Data='2147942401')]]</Select>
  </Query>
</QueryList>

因此,为了将其分解,我们想要:

Event log: Microsoft-Windows-TaskScheduler/Operational
Event Level: 4 or 0 = Information
Event ID: 201
And
Event Data: ResultCode = 2147942401

如果我们将错误的退出代码设置为1,为什么ResultCode = 2147942401是?因为它实际上返回0x1,这是十六进制的0x80070001,等于十进制。因此,您必须查看事件的详细信息才能找到“正确的”ResultCode。

qacovj5a

qacovj5a2#

在查找所有失败的任务时,HAL9256的答案对我不起作用
当我将他的XML转换为搜索所有非零返回代码时,结果是匹配所有返回代码。零和非零都是一样的


* [EventData[Data[@Name='ResultCode'] and (Data!='0')]]

相反,我创建了一个带有“On an Event”触发器和以下定制XML的任务:

<QueryList>
  <Query Id="0" Path="Microsoft-Windows-TaskScheduler/Operational">
    <Select Path="Microsoft-Windows-TaskScheduler/Operational">
      *[System[(Level=4 or Level=0) and (EventID=201)]]
        and
      *[EventData[(Data[@Name="ResultCode"]!=0)]] </Select>
  </Query>
</QueryList>

并运行以下PowerShell脚本
Send-MailMessage-to-Subject“My Subject”-BODY“其中一项任务失败。请登录服务器并查看事件日志详细信息,以找出哪项任务失败”-SmtpServer mail.Company.com-来自server@company.com

xghobddn

xghobddn3#

我知道这是事后才做的,但我最终要做的是,当一个电子邮件脚本出现故障时,我直接从PowerShell脚本中调用它。

3df52oht

3df52oht4#

如果您不想进行位数学运算($tasknum -band -bnot 0x80070000),则Get-Scheduledtaskinfo将返回一个lasttaskResult属性。

Get-ScheduledTaskInfo script.ps1

LastRunTime        : 10/23/2022 10:51:51 AM
LastTaskResult     : 1
NextRunTime        :
NumberOfMissedRuns : 0
TaskName           : script.ps1
TaskPath           :
PSComputerName     :
jv2fixgn

jv2fixgn5#

我要做的是将计划的任务附加到失败的事件,以便在发生这种情况时引发计划的任务。

相关问题