Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get informations on Windows Scheduled Task duration (execution time)

We have a couple of servers with hundred of scheduled tasks on them... and it is becoming problematic to find a right maintenance window. Is there some tool which allows for a graphical representation (like in a Gantt graph) of the Windows Task scheduler events?

Barring this, I've been fiddling with Powershell to implement the tool myself, using get-scheduledtask and get-scheduledtaskinfo, but while they do provide the properties LastRunTime and NextRunTime , I cannot find info about the duration of a task. I mean, If I started a task at 9AM, and the thread returned at 9.10, I do see in the history gui it ran for 10 minutes.., but I cannot get the same info using Powershell. Any hint? Thanks!

like image 297
Aldo Avatar asked Jan 27 '23 05:01

Aldo


2 Answers

The information you're looking for is not persisted as a property of a task. You need to extract it from the task history. Beginning and end of an action are logged with ID 200 and 201 respectively.

Get-WinEvent -FilterHashtable @{
    'LogName' = 'Microsoft-Windows-TaskScheduler/Operational'
    'ID'      = 200, 201
} | Group-Object ActivityID | ForEach-Object {
    $start = $_.Group |
             Where-Object { $_.Id -eq 200 } |
             Select-Object -Expand TimeCreated -First 1
    $end   = $_.Group |
             Where-Object { $_.Id -eq 201 } |
             Select-Object -Expand TimeCreated -First 1

    New-Object -Type PSObject -Property @{
        'TaskName'  = $_.Group[0].Properties[0].Value
        'StartTime' = $start
        'Duration'  = ($end - $start).TotalSeconds
    }
}
like image 70
Ansgar Wiechers Avatar answered Jan 29 '23 18:01

Ansgar Wiechers


Here are some tips to use with querying the events with Get-WinEvent comandlet. To search for desired Task name, construct a XPath xml and pass it via -FilterXml param To limit the Event count use -MaxEvents

    #Timeframe to look 
# Last 24H -> 24*60*60*1000 = 86400000
$TimeInterval = 24 * 60 * 60 * 1000

# paths for scheduled tasks in Task Scheduler namespace:
$TaskName = '\Microsoft\Windows\.NET Framework\.NET Framework NGEN v4.0.30319'

# must be even as we need a minimum of two events - 200 + 201
$EventsToGet = 2

$XMLQuery_TaskScheduler = @"
<QueryList>
  <Query Id="0" Path="Microsoft-Windows-TaskScheduler/Operational">
    <Select Path="Microsoft-Windows-TaskScheduler/Operational">*[System[(EventID=200 or EventID=201) and TimeCreated[timediff(@SystemTime) &lt;= $($TimeInterval)]] and EventData/Data[@Name='TaskName']='$($TaskName)']</Select>
  </Query>
</QueryList>
"@


$TestEvents = Get-WinEvent -FilterXml $XMLQuery_TaskScheduler -MaxEvents $EventsToGet -ErrorAction Stop
$TestEvents.Count

$TestEvents | Group-Object 'ActivityID' | ForEach-Object {
# use the great code above by Ansgar Wiechers
...

}
like image 36
386DX Avatar answered Jan 29 '23 18:01

386DX