PowerShell: Get Failed Scheduled Tasks on a Windows Machine

The following function will query the local Windows Tasks Scheduler for custom schedules and output any failed task objects. This is to be incorporated with a more comprehensive Windows monitoring script.

function getFailedScheduledTasks{
  $windowsVersion=[Environment]::OSVersion.Version
  if($windowsVersion -ge [version]'6.2'){
    # This function requires Windows 8 / Server 2012 (build 9200) or higher
    # Get-ScheduledTask : The term 'Get-ScheduledTask' is not recognized as the name of a cmdlet, function, script file, or
    # operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try
    # again.
    # At line:1 char:14
    # + $customTasks=Get-ScheduledTask|?{ $_.State -ne "Disabled" -and $_.Tas ...
    # +              ~~~~~~~~~~~~~~~~~
    #     + CategoryInfo          : ObjectNotFound: (Get-ScheduledTask:String) [], CommandNotFoundException
    #     + FullyQualifiedErrorId : CommandNotFoundException
    # $knownStates=@('Unknown','Disabled','Queued','Ready','Running')
    # Task status codes: https://docs.microsoft.com/en-us/windows/win32/taskschd/task-scheduler-error-and-success-constants
    
    # Common Task Result Codes (int32):
    # 0 - The operation completed successfully.
    # 1 - Incorrect function called or unknown function called.
    # 10 - The environment is incorrect.
    # 267008 - Task is ready to run at its next scheduled time.
    # 267009 - Task is currently running.
    # 267010 - The task will not run at the scheduled times because it has been disabled.
    # 267011 - Task has not yet run.
    # 267012 - There are no more runs scheduled for this task.
    # 267013 - One or more of the properties that are needed to run this task on a schedule have not been set.
    # 267014 - The last run of the task was terminated by the user.
    # 267015 - Either the task has no triggers or the existing triggers are disabled or not set.
    # 2147750671 - Credentials became corrupted.
    # 2147750687 - An instance of this task is already running.
    # 2147943645 - The service is not available (is "Run only when an user is logged on" checked?).
    # 3221225786 - The application terminated as a result of a CTRL+C.
    # 3228369022 - Unknown software exception.

    $excludedStates=@('Disabled','Running')    
    $excludedTaskResults=@(
      0, # success
      267009, # running
      267010, # disabled
      267011, # not yet ran
      267012, # There are no more runs scheduled for this task
      267014, # The last run of the task was terminated by the user
      267015, # Either the task has no triggers or the existing triggers are disabled or not set
      2147750687, # An instance of this task is already running
      3221225786, # The application terminated as a result of a CTRL+C
      1073807364, # 40010004 (hex). The system cannot open a file. This can safely be ignored as it normally pertains to CreateExplorerShellUnelevatedTask
      2147943517 # Firefox Default Browser Agent
      )
    $excludedPaths='^\\Microsoft|Mozilla\\'
    $customTasks=Get-ScheduledTask|?{ $_.State -notin $excludedStates -and $_.TaskPath -notmatch $excludedPaths}
    $failedTasks=$customTasks|Get-ScheduledTaskInfo|?{$_.LastTaskResult -notin $excludedTaskResults}
    if($failedTasks){
      return $failedTasks|Select-Object -Property * -ExcludeProperty PSComputerName,CimClass,CimInstanceProperties,CimSystemProperties
    }
  }
}
getFailedScheduledTasks
# Consideration for legacy Windows:
# https://serverfault.com/questions/604673/how-to-print-out-information-about-task-scheduler-in-powershell-script
# $sched = New-Object -Com "Schedule.Service"
# $sched.Connect()
# $out = @()

# $sched.GetFolder("\").GetTasks(0) | % {
#     $xml = [xml]$_.xml
#     $out += New-Object psobject -Property @{
#         "Name" = $_.Name
#         "Status" = switch($_.State) {0 {"Unknown"} 1 {"Disabled"} 2 {"Queued"} 3 {"Ready"} 4 {"Running"}}
#         "NextRunTime" = $_.NextRunTime
#         "LastRunTime" = $_.LastRunTime
#         "LastRunResult" = $_.LastTaskResult
#         "Author" = $xml.Task.Principals.Principal.UserId
#         "Created" = $xml.Task.RegistrationInfo.Date
#     }
# }
# $out | fl Name,Status,NextRuNTime,LastRunTime,LastRunResult,Author,Created

Leave a Reply

Your email address will not be published. Required fields are marked *