Skip to content

Instantly share code, notes, and snippets.

@micmaher
Last active October 15, 2016 13:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save micmaher/a324be736532f372ef4a5f434fd118b2 to your computer and use it in GitHub Desktop.
Save micmaher/a324be736532f372ef4a5f434fd118b2 to your computer and use it in GitHub Desktop.
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