我有几个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
我知道我的列表填充了错误,因为我创建了它们来测试它。我检查了错误代码作为字符串是否是一个长度并点击出口 99 或 1。 任务计划程序仍显示正常事件代码。
我计划了有关失败的电子邮件警报,由于事件代码未显示失败,因此永远不会触发发送我的电子邮件。这是窗口10,以防万一。
我一直在查看powershell错误sql,任务计划程序成功错误,提示技巧计划任务,powershell退出代码,但它没有帮助。
Powershell 脚本在任务计划程序中设置,如下所示:
操作:启动程序
程序/脚本:PowerShell
添加参数: -ExecutionPolicy Bypass -File C:\Users\me\Documents\powershell\disasterBackup.ps1
第1 部分是让 PowerShell 将正确的上次退出代码返回到任务计划程序。
这是任务计划程序的特点之一。它只是报告,是的,PowerShell.exe
成功运行。问题是PowerShell.exe
不会报告退出代码,因为,是的,即使脚本没有正确运行,PowerShell.exe
也运行正确。
我能够解决此问题的方法是从运行不返回退出值的-File
参数运行脚本切换到-Command
参数。这样,我就可以通过使用$LASTEXITCODE
值显式退出,使用正确的退出代码退出PowerShell.exe
:
#Run Scheduled task with the following command
powershell.exe -Command ". C:ScriptsRunScript.ps1; exit $LASTEXITCODE"
所以在你的情况下,它会是:
powershell.exe -ExecutionPolicy Bypass -Command ". C:UsersmeDocumentspowershelldisasterBackup.ps1; exit $LASTEXITCODE"
---编辑----
第 2 部分是在事件无法发送电子邮件或其他内容时触发计划任务。
任务计划程序的问题与PowerShell退出时遇到的问题相同。无论返回什么退出代码,任务始终记录事件 ID 201 - 操作已完成...这是正确的...无论如何,即使运行在内部失败的作业,任务也已完成。
进一步查看记录的事件的详细信息,我们可以看到EventData
中的ResultCode
确实设置正确。因此,通过GUI进行过滤是一项简单的工作?....嗯不...除了事件 ID 之外,没有筛选器。现在我们必须编写一个自定义事件过滤器,以根据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
等于十进制2147942401
。因此,您必须查看事件的详细信息才能找到"正确"的结果代码。
在寻找所有失败的任务时,HAL9256的答案对我不起作用
当我转换他的XML以搜索所有非零返回代码时,它最终匹配了所有返回代码。 零和非零都一样
*[EventData[Data[@Name='ResultCode'] and (Data!='0')]]
相反,我创建了一个具有"事件"触发器和以下自定义 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 脚本
发送邮件消息 -收件人 -主题"我的主题" -正文 "其中一个任务失败。 请登录到服务器并查看事件日志详细信息,以找出哪个任务失败" -SmtpServer mail.company.com -From server@company.com
我知道这是事后的事情,但我最终为此所做的是,当电子邮件脚本出现故障时,我直接从我的 powershell 脚本调用了它。
如果你不想做位数学($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 :
我要做的是将计划任务附加到失败事件,以便在发生这种情况时引发计划任务。