Last active
October 15, 2016 13:19
-
-
Save micmaher/a324be736532f372ef4a5f434fd118b2 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Function Get-TaskDuration { | |
<# | |
.SYNOPSIS | |
Returns the duration (execution time) of the most recent run of the specified scheduled task. | |
Michael Klement did a great deal of this | |
.DESCRIPTION | |
Returns the execution time of the most recent completed run of the specified scheduled tasks as [timespan] instances. | |
Note that a TaskUri property is added to the output [timespan] instances, which identifies the originating task by path (location) and name. | |
Note that this property is not output by default. | |
.PARAMETER TaskName | |
The task name (without path), as it appears in Task Scheduler. | |
Note that in the absence of scheduler-path information multiple tasks may match. | |
This parameter can be bound via the pipeline, either as a collection of names (strings), or as scheduled-task objects returned by Get-ScheduledTask. | |
Using Get-ScheduledTask with the -TaskPath parameter added allows you to unambiguously specify a task. | |
.PARAMETER ExcludeMicrosoft | |
Filters out Tasks authored by Microsoft | |
.OUTPUTS | |
System.TimeSpan The originating task's TaskUri value is added as a note property. | |
.EXAMPLE | |
> Get-TaskDuration 'trim logs' | |
#> | |
[cmdletbinding()] | |
[OutputType([timespan])] | |
param | |
( | |
[Parameter(ValueFromPipeline,ValueFromPipelineByPropertyName)] | |
[string[]] $TaskName, | |
[Parameter()] | |
[switch] $ExcludeMicrosoft | |
) | |
process { | |
foreach($name in $TaskName) { | |
Write-Verbose "Getting last execution time for task '$name'..." | |
# Note that since we only match by *name*, Get-ScheduledTask may return | |
# *multiple* tasks. | |
If ($ExcludeMicrosoft){ | |
$getCMD = Get-ScheduledTask -TaskName $name | where {$_.TaskPath -NotLike "*Microsoft*"} | |
} | |
Else{ | |
$getCMD = Get-ScheduledTask -TaskName $name | |
} | |
foreach($task in ($getCMD)) { | |
# You may get the following non-terminating errors: | |
# - task by that name doesn't exist: | |
# "Get-ScheduledTask : No MSFT_ScheduledTask objects found with property 'TaskName' equal to 'write-host test1'." | |
# - task exists, but was never run / the log has been cleared: | |
# "Get-WinEvent : No events were found that match the specified selection criteria." | |
# Note that, normally, ID 201 (end) is returned before 200 (start). | |
$taskEnd, $taskStart = Get-WinEvent -MaxEvents 2 -ErrorAction SilentlyContinue -FilterHashtable @{Logname='Microsoft-Windows-TaskScheduler/Operational'; Data="$($task.taskpath)$($task.taskname)"; ID=201, 200} | | |
% TimeCreated | |
if ($?) { # At least 1 event was found. | |
if ($null -eq $taskStart -or $taskStart -gt $taskEnd) { | |
# Only 1 event was found, or the most recent event is a *start* event | |
# rather than an end event; the most likely explanation is that | |
# the task is currently running. | |
Write-Warning "Task '$($task.taskpath)$($task.taskname)' is presumably still running." | |
} else { | |
# Output the duration as a [timespan] instance. | |
# (Subtracting two [datetime] instances implicilty creates a [timespan]). | |
$taskEnd - $taskStart | Add-Member -PassThru -NotePropertyMembers @{ TaskUri = "$($task.taskpath)$($task.taskname)" } | Select -Property * | |
} | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment