# Last Updated: 2022/04/07 # NOTES: # - This script checks the last successful backup date using the Windows Server Backup PowerShell module # https://docs.microsoft.com/en-us/powershell/module/windowsserverbackup/?view=windowsserver2022-ps # - It also counts the number of warning and error events in the "Microsoft/Windows/Backup" Event Logs # that are within the period specified in the $rpoHours variable # # - Your check matching condition should be: # Subject - Is Exactly - Windows Server Backup Summary: COMPUTERNAME # # - The activity that gets created in CheckCentral will contain a summary line similar to this: "Recent: True, Errors: 0, Warnings: 0" # - Your check success condition should be: # Body Text - Contains - Recent: True, Errors: 0, Warnings: 0 # - Your check warning conditions should be: # Body Text - Contains - Recent: True, Errors: 0 # Body Text - Does Not Contain - Warnings: 0 ################### # Script Settings # ################### # CheckCentral API key ("createActivities Only" token type is recommended) $apiToken = "" # Set the recovery point objective time to check here (in hours) # If your job runs daily, set this to 24 hours to make sure # the last successful backup is less than 24 hours old. # If your job runs more frequently, e.g. hourly, then set this to # 1 so that the script confirms the latest backup is less than 1 hour old $rpoHours = 24 #################################################### # Script Processing (Don't modify below this line) # #################################################### $ErrorActionPreference = 'Stop' function New-CCActivity { Param([string]$apiToken,[string]$subject,[string]$body) Write-Output "`n[INFO] Creating the activity in CheckCentral...`n" # Create the object to store the activity data $ccActivity = [PSCustomObject]@{ sendNotifications = $true sendTicketingSystems = $true activities = @( [PSCustomObject]@{ subject = $subject body = $body } ) } # Create the activity via the createActivities endpoint $ccCreateActivitiesRequest = Invoke-WebRequest -Uri "https://api.checkcentral.cc/createActivities/?apiToken=$apiToken" -Method "POST" -ContentType "text/json" -Body $(($ccActivity | ConvertTo-Json)) -UseBasicParsing # Get the number of activities sent and successfully saved $ccActivitiesSent = ($ccCreateActivitiesRequest.Content | ConvertFrom-Json).activities_received $ccActivitiesSaved = ($ccCreateActivitiesRequest.Content | ConvertFrom-Json).activities_saved # Verify that the number of activities saved matches the number of activities sent if ($ccActivitiesSaved -lt $ccActivitiesSent) { Write-Output "[FAIL] Failed to create $($ccActivitiesSent - $ccActivitiesSaved) activities in CheckCentral" } elseif ($ccActivitiesSaved -eq $ccActivitiesSent) { Write-Output "[INFO] Successfully created $($ccActivitiesSaved) activities" } } # Bail out if $apiToken has an empty value if ($apiToken -eq "") { Write-Output "[FAIL] API token is not set in the script settings" exit } # Build the activity title $title = "Windows Server Backup Summary: " + $env:COMPUTERNAME # Get the summary from Windows Server Backup try { Write-Output "[INFO] Getting the Windows Server Backup summary..." $wbSummary = Get-WBSummary } catch { # Write the error to the console $errorMessage = "[FAIL] Get-WBSummary failed to run with the following error: $($Error[0])" Write-Output $errorMessage # Create the activity in CheckCentral New-CCActivity -apiToken $apiToken -subject $title -body $errorMessage # Exit the script Write-Output "[INFO] Exiting the script..." exit } # Check whether the last successful backup is within the RPO window $lastBackupRecent = ($wbSummary.LastSuccessfulBackupTime -gt (Get-Date).AddHours(-$rpoHours)) # Get the number of errors in the $rpoHours time window try { $wbErrors = (Get-WinEvent Microsoft-Windows-Backup | Where-Object {($_.TimeCreated -gt (Get-Date).AddHours(-$rpoHours)) -and ($_.LevelDisplayName -eq "Error")}).Count } catch { if ($Error[0].ToString() -eq "No events were found that match the specified selection criteria.") { $wbErrors = 0 } else { $errorMessage = "[FAIL] Get-WinEvent failed to run with the following error: $($Error[0])" Write-Output $errorMessage # Create the activity in CheckCentral New-CCActivity -apiToken $apiToken -subject $title -body $errorMessage # Exit the script Write-Output "[INFO] Exiting the script..." exit } } # Get the number of warnings in the $rpoHours time window try { $wbWarnings = (Get-WinEvent Microsoft-Windows-Backup | Where-Object {($_.TimeCreated -gt (Get-Date).AddHours(-$rpoHours)) -and ($_.LevelDisplayName -eq "Warning")}).Count } catch { if ($Error[0].ToString() -eq "No events were found that match the specified selection criteria.") { $wbWarnings = 0 } else { $errorMessage = "[FAIL] Get-WinEvent failed to run with the following error: $($Error[0])" Write-Output $errorMessage # Create the activity in CheckCentral New-CCActivity -apiToken $apiToken -subject $title -body $errorMessage # Exit the script Write-Output "[INFO] Exiting the script..." exit } } # Build the results $wbResults = @" Last successful backup newer than specified RPO time: $(($lastBackupRecent | Out-String).Trim()) ($rpoHours hours set in script) Number of errors in the RPO time window: $wbErrors (Checked the last $rpoHours hours as set in script) Number of warnings in the RPO time window: $wbWarnings (Checked the last $rpoHours hours as set in script) Summary: Recent: $(($lastBackupRecent | Out-String).Trim()), Errors: $wbErrors, Warnings: $wbWarnings $(($WBSummary | Out-String).Trim()) Sent from $($MyInvocation.MyCommand) on $env:COMPUTERNAME "@ # Create the activity in CheckCentral New-CCActivity -apiToken $apiToken -subject $title -body $wbResults