英文:
How to use Powershell to determine the difference in time between two specific Windows Event IDs
问题
我正在寻找一种计算两个特定事件ID之间的时间差的方法,针对特定任务计划程序作业名称,在过去的24小时内。然后,如果时间太短(表示某些事情没有正常工作),或者如果运行了适当的时间,就可以触发某些操作来结束脚本。
我有一个脚本,仅提取了过去24小时内仅为一个作业的事件(代码如下)。
我无法弄清楚如何解析$events(仅包含过去24小时内的事件子集和该作业名称)以获取我的“开始”和“结束”时间,以便进行计算。
以下是我的输出示例,对于一个运行“成功”,但实际上发生了错误的作业 - 通常需要3-4分钟才能运行:
截止到08/03/2023 09:00:01:
MachineName TimeCreated Id TaskDisplayName
----------- ----------- -- ---------------
Servername 8/3/2023 3:00:03 AM 102 Task completed
Servername 8/3/2023 3:00:03 AM 201 Action completed
Servername 8/3/2023 3:00:00 AM 200 Action started
Servername 8/3/2023 3:00:00 AM 100 Task Started
Servername 8/3/2023 3:00:00 AM 129 Created Task Process
Servername 8/3/2023 3:00:00 AM 107 Task triggered on scheduler
有人能提供一些想法吗?我已经看了各种帖子,但没有得到任何思路。
我有一个Powershell脚本,我用它来每天提取特定任务计划程序作业的事件ID,然后将其附加到文本文件中。然后我有一个已知的良好ID列表,我会将其筛选出来,如果有一个不是“好”的事件ID列出来,那么它会给我发送一封电子邮件,表示发生了不寻常的事情。
以下是我用于指定任务名称、我的文本文件路径等的代码,但我希望重用$events变量,该变量应该包含所有内容:
英文:
I am looking to find a way to calculate the time difference between two specific event IDs, for a specific task scheduler job name, in the past 24 hours. Then I can trigger something if the time is too short (meaning something didn't work right), or if it ran for an appropriate amount of time, end the script.
I have a script that pulls just the events for just the one job, in just the last 24 hours (code is below).
I cannot figure out how to parse the $events (subset of events just for the last 24 hours and just for that job name) to get my "start" and "stop" time in order to make a calculation.
Example of my output for a job that ran "successfully" but something happened and it actually failed - it usually takes 3-4 minutes to run:
As of 08/03/2023 09:00:01 :
MachineName TimeCreated Id TaskDisplayName
----------- ----------- -- ---------------
Servername 8/3/2023 3:00:03 AM 102 Task completed
Servername 8/3/2023 3:00:03 AM 201 Action completed
Servername 8/3/2023 3:00:00 AM 200 Action started
Servername 8/3/2023 3:00:00 AM 100 Task Started
Servername 8/3/2023 3:00:00 AM 129 Created Task Process
Servername 8/3/2023 3:00:00 AM 107 Task triggered on scheduler
Can anyone provide some ideas? I've been through all sorts of posts and cannot get an idea.
I have a Powershell script that I use to pull the event IDs for a specific Task Scheduler job every day and then append that to a text file. I end up with a running history of those results.
I then have a list of known-good IDs that I filter out and if there is an event ID listed that is not "good" then it sends me an email that something out of the ordinary has happened.
Here is what I use as code to specify the task name, my text file path and such, but I was hoping to reuse the $events variable which should have everything in there:
Start-Transcript -Path "C:\Path\TextFile.txt"
$jobName = "TestJob";
$Date = Get-Date;
$file = "C:\Path$jobName.txt"
$file_path = Test-Path $file
$pc = $_
#If file hasn't been created, create it
If ($file_path -ne $true){
New-Item C:\Path$jobName.txt
}
#Filter xml to pull task scheduler events
#Task scheduler common event IDs to ignore (treat as good/success)
$notin = 100, 102, 107, 110, 129, 140, 200, 201;
try {
#Command to connect to remote Server (if needed)
#$events = Invoke-Command -ComputerName "servername.domain" -ScriptBlock {
#Command to execute locally
$events = Invoke-Command -ScriptBlock {
#Pulls task scheduler, only events with the job (task's) name for events in the last 24 hours
$events = @(
Get-WinEvent -FilterXml @"
<QueryList>
<Query Id="0" Path="Microsoft-Windows-TaskScheduler">
<Select Path="Microsoft-Windows-TaskScheduler/Operational">
*[EventData/Data[@Name='TaskName']='$($args[0])'] and *[System[TimeCreated[timediff(@SystemTime) &lt;= 86400000]]]
</Select>
</Query>
</QueryList>
"@ -ErrorAction Stop
);
Return $events;
} -ArgumentList $jobName;
}
catch {
Write-Warning -Message "Failed to query $($env:computername) because $($_.Exception.Message)" *> "C:\Path\errors.txt"
#If events exist from last 24 hours for this task, append the text (log) file with those events
}
if ($events) {
Add-Content C:\Path$jobName.txt "As of $Date :" -Encoding UTF8
$events | Select MachineName,TimeCreated,Id,TaskDisplayName | Out-File -Append C:\Path$jobName.txt -Encoding UTF8
}else {
Add-Content C:\Path$jobName.txt "No files found for last 24 hours as of $Date `r" -Encoding UTF8
}
#Email function to email us but only email if there are tasks with codes other than the common success ones - only send an email if something is out of the ordinary
Function email (){
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12;
$EmailTo = "recipient@whatever.com";
$EmailFrom = "sender@wherever.com";
$Subject = "$jobName Failure";
$Body = $ebody | Out-String;
$SMTPServer = "smtp.office365.com"
$SMTPMessage = New-Object System.Net.Mail.MailMessage($EmailFrom,$EmailTo,$Subject,$Body)
$SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, 587)
$SMTPClient.EnableSsl = $true
$SMTPClient.Credentials = New-Object System.Net.NetworkCredential("emailaddress", "password");
$SMTPClient.Send($SMTPMessage)
};
$ebody = @();
$ebody = $events | % { If ($_.id -notin $notin) {$_ | FL } }
If($ebody){email};
Stop-Transcript
答案1
得分: 0
这应该可以解决问题:
$LatestStart = $events | Where-Object Id -eq '100' | Sort-Object TimeCreated -Descending | Select-Object -First 1
$LatestEnd = $events | Where-Object {($_.ActivityId -eq $LatestStart.ActivityId) -and ($_.Id -eq 102)}
$TimeTaken = New-TimeSpan -Start $LatestStart.TimeCreated -End $LatestEnd.TimeCreated
$TimeTaken 现在是最新事件所花费时间的时间跨度。
最好的解决方案不是检查任务实际在做什么,以确定它是否成功,或者修复导致任务在显示已完成时实际上没有完成的问题吗?
英文:
This should do the trick:
$LatestStart = $events | Where-Object Id -eq '100' | Sort-Object TimeCreated -Descending | Select-Object -First 1
$LatestEnd = $events | Where-Object {($_.ActivityId -eq $LatestStart.ActivityId) -and ($_.Id -eq 102)}
$TimeTaken = New-TimeSpan -Start $LatestStart.TimeCreated -End $LatestEnd.TimeCreated
$TimeTaken is now the timespan for how long that latest event took.
Would the best solution not be to check whatever the task is actually doing though, to determine whether it was successful, or fixing the issue that is causing the task to show it completed fine when it didnt.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论