Get Scheduled Tasks Status Report
Scenario
Get Scheduled Tasks Status Report
Scheduled tasks help us to run programs, restart of services or run scripts on specific times or intervals. When we have a lot of tasks to run we would like also to know if our tasks are running on the specific intervals and they were successful. Having a lot of task and checking them one by one it is was successful might be time consuming. I came up with a script that will check the status of the scheduled tasks and inform me every day by email. Lets see how we are able to achieve this using a simple PowerShell script.
What is does
In general, we will define the names of our scheduled tasks based on their schedule. The the script will check if the schedule task run in a specified interval and will provide us with a custom email status report. The script is configured to run daily.
[adinserter name=”In Article”]
Define the variables
First we will define few variables that are needed in the script to send the email. As you can see below the first variables will collect the information for our user that will be used to send the email and the recipients of the email. Then we will collect the day of the week which will help us to perform some checks only on specific days. After we have collected the day of the week, we define our arrays that include the names of the scheduled tasks that we would like to check with our script. As you can see the schedules tasks are separated based on their schedule. Then we will combine our arrays in order to make the process easier and we will define our html email structure that will be filled accordingly.
Code:
$File = "C:\Scripts\Password.txt" $Key = (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32) $EmailUser = "Script-User@domain.com" $Password = Get-Content $File | ConvertTo-SecureString -Key $Key $EmailCredentials = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $EmailUser,$Password $To = 'User1@domain.com' $From = 'Script-User@domain.com' $EmailResult = "" [string]$Day = (Get-Date).DayOfWeek $DailyTasks = @("DailyScheduledTask1",` "DailyScheduledTask2",` "DailyScheduledTask3",` "DailyScheduledTask4", "DailyScheduledTask5") $FridayTasks = @("FridayScheduledTask1") $5MinutesTasks = @("5minsScheduledTask1") $Tasks = $DailyTasks + $FridayTasks + $5MinutesTasks $EmailUp = @" <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cstyle%3E%0D%0A%0D%0Abody%20%7B%20font-family%3ASegoe%2C%20%22Segoe%20UI%22%2C%20%22DejaVu%20Sans%22%2C%20%22Trebuchet%20MS%22%2C%20Verdana%2C%20sans-serif%20!important%3B%20color%3A%23434242%3B%7D%0D%0ATABLE%20%7B%20font-family%3ASegoe%2C%20%22Segoe%20UI%22%2C%20%22DejaVu%20Sans%22%2C%20%22Trebuchet%20MS%22%2C%20Verdana%2C%20sans-serif%20!important%3B%20border-width%3A%201px%3Bborder-style%3A%20solid%3Bborder-color%3A%20black%3Bborder-collapse%3A%20collapse%3B%7D%0D%0ATR%20%7Bborder-width%3A%201px%3Bpadding%3A%2010px%3Bborder-style%3A%20solid%3Bborder-color%3A%20white%3B%20%7D%0D%0ATD%20%7Bfont-family%3ASegoe%2C%20%22Segoe%20UI%22%2C%20%22DejaVu%20Sans%22%2C%20%22Trebuchet%20MS%22%2C%20Verdana%2C%20sans-serif%20!important%3B%20border-width%3A%201px%3Bpadding%3A%2010px%3Bborder-style%3A%20solid%3Bborder-color%3A%20white%3B%20background-color%3A%23C3DDDB%3B%7D%0D%0A.colorm%20%7Bbackground-color%3A%2358A09E%3B%20color%3Awhite%3B%7D%0D%0A.colort%7Bbackground-color%3A%2358A09E%3B%20padding%3A20px%3B%20color%3Awhite%3B%20font-weight%3Abold%3B%7D%0D%0A.colorr%7Bcolor%3Ared%3B%20font-weight%3Abold%3B%7D%0D%0A.colorn%7Bbackground-color%3Atransparent%3B%7D%0D%0A%3C%2Fstyle%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="<style>" title="<style>" /> <body> <h3>Scheduled Tasks Report has been completed successfully</h3> <h4>Task Status Report:</h4> <table> <tr> <td class="colort">Task</td> <td class="colort">Status</td> </tr> "@ $EmailDown = @" </table> </body> "@
[adinserter name=”In Article”]
Perform the check
Now that we have everything ready, it is time to get the information from each of the scheduled tasks and process the data. In order to achieve this we are using a foreach loop to go though each of the tasks in the list. Inside the loop we have a switch statement based on our schedule times and on what we want to check. First case is for the scheduled tasks that are running once per day. The second case is for the tasks that are running only on Friday and the check is performed only if the day that the script is running is Saturday. The third case is for tasks that are running every five minutes.
The check is performed once per day so even if the tasks are running more that once within the day, the script will check only the last run of the script. As you can see the $IntervalCheck
variable is different for each of the cases. On the first two of our cases the interval check is compared against the $Difference
variable which is in hours. The third case is number of minutes. Each of the cases fills a part of the HTML code for the email in order to be ready to combine it with the rest of the parts that we have defined above and complete.
Code:
foreach ($Task in $Tasks){ switch -Regex ($Task){ {$DailyTasks -contains $Task}{ $TaskRunTime = (Get-ScheduledTaskInfo "$Task").LastRunTime $Difference = (New-TimeSpan -Start $TaskRunTime).TotalHours $IntervalCheck = 12 switch -Regex ($Difference){ {($Difference -gt "$IntervalCheck")}{ $Status = "BAD" $EmailTemp = @" <tr> <td class="colorm">$Task</td> <td class="colorr">$Status</td> </tr> "@ } {$Difference -lt "$IntervalCheck"}{ $Status = "OK" $EmailTemp = @" <tr> <td class="colorm">$Task</td> <td>$Status</td> </tr> "@ } } $EmailResult = $EmailResult + $EmailTemp $EmailTemp = "" } {($FridayTasks -contains $Task) -and ($Day -eq "Saturday")}{ $TaskRunTime = (Get-ScheduledTaskInfo "$Task").LastRunTime $Difference = (New-TimeSpan -Start $TaskRunTime).TotalHours $IntervalCheck = 12 ......... } {$5MinutesTasks -contains $Task}{ $TaskRunTime = (Get-ScheduledTaskInfo "$Task").LastRunTime $Difference = (New-TimeSpan -Start $TaskRunTime).TotalMinutes $IntervalCheck = 5 .......... } } }
[adinserter name=”In Article”]
Send the report
After everything is ready and the loop has passed from all scheduled tasks in the list, our email report is ready to be sent. The script now is configured to use Exchange Online in order to send the email. You can change the method according to your system setup.
Code:
$Email = $EmailUp + $EmailResult + $EmailDown $EmailParameters = @{ To = $To Subject = "Scheduled Tasks Report $(Get-Date -format dd/MM/yyyy)" Body = $Email BodyAsHtml = $True Priority = "High" UseSsl = $True Port = "587" SmtpServer = "smtp.office365.com" Credential = $EmailCredentials From = $From} send-mailmessage @EmailParameters
You can download the script here or copy it from below. (Note that code within the script might not be copied correctly due to syntax highlighting.)
Hope you like it.
You feedback is appreciated.
If you have any questions or anything else please let me know in the comments below.
[adinserter name=”In Article”]
Related Links
- PowerShell Scripts
- PowerShell Tutorials
- about_Foreach | Microsoft Docs
- about_Switch | Microsoft Docs
- about_Splatting | Microsoft Docs
- PowerShell Arithmetic Operators
- PowerShell Quotes
- Get-ScheduledTaskInfo – Microsoft Docs
- Get-Content – Microsoft Docs
- ConvertTo-SecureString – Microsoft Docs
- New-Object – Microsoft Docs
- Get-Date – Microsoft Docs
- New-TimeSpan – Microsoft Docs
- Send-MailMessage – Microsoft Docs
[adinserter name=”In Article”]
Solution / Script
$File = "C:\Scripts\Password.txt" $Key = (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32) $EmailUser = "Script-User@domain.com" $Password = Get-Content $File | ConvertTo-SecureString -Key $Key $EmailCredentials = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $EmailUser,$Password $To = 'User1@domain.com' $From = 'Script-User@domain.com' $EmailResult = "" [string]$Day = (Get-Date).DayOfWeek $DailyTasks = @("DailyScheduledTask1",` "DailyScheduledTask2",` "DailyScheduledTask3",` "DailyScheduledTask4", "DailyScheduledTask5") $FridayTasks = @("FridayScheduledTask1") $5MinutesTasks = @("5minsScheduledTask1") $Tasks = $DailyTasks + $FridayTasks + $5MinutesTasks $EmailUp = @" <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cstyle%3E%0D%0A%0D%0Abody%20%7B%20font-family%3ASegoe%2C%20%22Segoe%20UI%22%2C%20%22DejaVu%20Sans%22%2C%20%22Trebuchet%20MS%22%2C%20Verdana%2C%20sans-serif%20!important%3B%20color%3A%23434242%3B%7D%0D%0ATABLE%20%7B%20font-family%3ASegoe%2C%20%22Segoe%20UI%22%2C%20%22DejaVu%20Sans%22%2C%20%22Trebuchet%20MS%22%2C%20Verdana%2C%20sans-serif%20!important%3B%20border-width%3A%201px%3Bborder-style%3A%20solid%3Bborder-color%3A%20black%3Bborder-collapse%3A%20collapse%3B%7D%0D%0ATR%20%7Bborder-width%3A%201px%3Bpadding%3A%2010px%3Bborder-style%3A%20solid%3Bborder-color%3A%20white%3B%20%7D%0D%0ATD%20%7Bfont-family%3ASegoe%2C%20%22Segoe%20UI%22%2C%20%22DejaVu%20Sans%22%2C%20%22Trebuchet%20MS%22%2C%20Verdana%2C%20sans-serif%20!important%3B%20border-width%3A%201px%3Bpadding%3A%2010px%3Bborder-style%3A%20solid%3Bborder-color%3A%20white%3B%20background-color%3A%23C3DDDB%3B%7D%0D%0A.colorm%20%7Bbackground-color%3A%2358A09E%3B%20color%3Awhite%3B%7D%0D%0A.colort%7Bbackground-color%3A%2358A09E%3B%20padding%3A20px%3B%20color%3Awhite%3B%20font-weight%3Abold%3B%7D%0D%0A.colorr%7Bcolor%3Ared%3B%20font-weight%3Abold%3B%7D%0D%0A.colorn%7Bbackground-color%3Atransparent%3B%7D%0D%0A%3C%2Fstyle%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="<style>" title="<style>" /> <body> <h3>Scheduled Tasks Report has been completed successfully</h3> <h4>Task Status Report:</h4> <table> <tr> <td class="colort">Task</td> <td class="colort">Status</td> </tr> "@ $EmailDown = @" </table> </body> "@ foreach ($Task in $Tasks){ switch -Regex ($Task){ {$DailyTasks -contains $Task}{ $TaskRunTime = (Get-ScheduledTaskInfo "$Task").LastRunTime $Difference = (New-TimeSpan -Start $TaskRunTime).TotalHours $IntervalCheck = 12 switch -Regex ($Difference){ {($Difference -gt "$IntervalCheck")}{ $Status = "BAD" $EmailTemp = @" <tr> <td class="colorm">$Task</td> <td class="colorr">$Status</td> </tr> "@ } {$Difference -lt "$IntervalCheck"}{ $Status = "OK" $EmailTemp = @" <tr> <td class="colorm">$Task</td> <td>$Status</td> </tr> "@ } } $EmailResult = $EmailResult + $EmailTemp $EmailTemp = "" } {($FridayTasks -contains $Task) -and ($Day -eq "Saturday")}{ $TaskRunTime = (Get-ScheduledTaskInfo "$Task").LastRunTime $Difference = (New-TimeSpan -Start $TaskRunTime).TotalHours $IntervalCheck = 12 switch -Regex ($Difference){ {($Difference -gt "$IntervalCheck")}{ $Status = "BAD" $EmailTemp = @" <tr> <td class="colorm">$Task</td> <td class="colorr">$Status</td> </tr> "@ } {$Difference -lt "$IntervalCheck"}{ $Status = "OK" $EmailTemp = @" <tr> <td class="colorm">$Task</td> <td>$Status</td> </tr> "@ } } $EmailResult = $EmailResult + $EmailTemp $EmailTemp = "" } {$5MinutesTasks -contains $Task}{ $TaskRunTime = (Get-ScheduledTaskInfo "$Task").LastRunTime $Difference = (New-TimeSpan -Start $TaskRunTime).TotalMinutes $IntervalCheck = 5 switch -Regex ($Difference){ {($Difference -gt "$IntervalCheck")}{ $Status = "BAD" $EmailTemp = @" <tr> <td class="colorm">$Task</td> <td class="colorr">$Status</td> </tr> "@ } {$Difference -lt "$IntervalCheck"}{ $Status = "OK" $EmailTemp = @" <tr> <td class="colorm">$Task</td> <td>$Status</td> </tr> "@ } } $EmailResult = $EmailResult + $EmailTemp $EmailTemp = "" } } } $Email = $EmailUp + $EmailResult + $EmailDown $EmailParameters = @{ To = $To Subject = "Scheduled Tasks Report $(Get-Date -format dd/MM/yyyy)" Body = $Email BodyAsHtml = $True Priority = "High" UseSsl = $True Port = "587" SmtpServer = "smtp.office365.com" Credential = $EmailCredentials From = $From} send-mailmessage @EmailParameters
[adinserter name=”Matched-Content”]


Hello,
I keep receiving the below error – any ideas? If I make $Difference = 0 then it works.
New-TimeSpan : Cannot bind parameter ‘Start’ to the target. Exception setting “Start”: “Object reference not set to an instance of an object.”
At C:\Users\sofcotech\Desktop\Get-ScheduledTaskStatusReport.ps1:50 char:48
+ $Difference = (New-TimeSpan -Start $TaskRunTime).TotalHours
Regards,
Michael