Monitoring Windows Server Backup in VSA
Here’s how to monitor Windows Server Backup in Kaseya VSA using something a little “stronger” than looking for a failed backup event log. This solution uses a script to detect the presence of a configured backup job on a server, and then update a custom field which we will use to include the servers in a view.
Step 1- Create a new custom field under Audit > Machine Summary > New Custom Field

Step 2- Import the following agent procedure (save it as a .xml file) in System > Import Center > New Import. This agent procedure will detect the presence of a configured windows server backup job on an endpoint and will update the custom field we created to ‘true’ if it finds one. This procedure should be scheduled to run once after the agent is installed, or weekly. It’s purpose is to add endpoints with windows server backup to a view.
<?xml version="1.0" encoding="utf-8"?>
<ScriptExport xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.kaseya.com/vsa/2008/12/Scripting">
<Procedure name="Detect Windows Server Backup" treePres="3" id="1878874152" folderId="275513994775486" treeFullPath="MSP.Onboarding.Detect">
<Body description="Checks to see if Windows Server Backup is installed with a configured backup job. 

Custom Field: CF-Role-WSB">
<Statement name="Execute Powershell Command (64-bit, Run As System)" continueOnFail="false">
<Parameter xsi:type="StringParameter" name="Parameter1" value="" />
<Parameter xsi:type="StringParameter" name="Parameter2" value="get-wbpolicy | select schedule" />
<Parameter xsi:type="StringParameter" name="Parameter3" value="True" />
</Statement>
<If description="">
<Condition name="CheckVariable">
<Parameter xsi:type="StringParameter" name="VariableName" value="#global:psresult#" />
<Parameter xsi:type="EnumParameter" name="Condition" value="Contains" />
<Parameter xsi:type="StringParameter" name="Value" value="{" />
</Condition>
<Then>
<Statement name="WriteScriptLogEntry" continueOnFail="false">
<Parameter xsi:type="StringParameter" name="Comment" value="WSB Is Configured" />
</Statement>
<Statement name="UpdateSystemInfo" continueOnFail="false">
<Parameter xsi:type="StringParameter" name="ColumnName" value="CF-Roles-WSB" />
<Parameter xsi:type="StringParameter" name="Value" value="true" />
</Statement>
</Then>
<Else>
<Statement name="WriteScriptLogEntry" continueOnFail="false">
<Parameter xsi:type="StringParameter" name="Comment" value="WSB Not Configured" />
</Statement>
<Statement name="UpdateSystemInfo" continueOnFail="false">
<Parameter xsi:type="StringParameter" name="ColumnName" value="CF-Roles-WSB" />
<Parameter xsi:type="StringParameter" name="Value" value="" />
</Statement>
</Else>
</If>
</Body>
</Procedure>
</ScriptExport>
Step 3- Add a new View called Backup – Windows Server Backup under views. Check the advanced agent data filter and then add ‘true’ under your custom field name.

Step 4- Now we will schedule another Agent Procedure which runs daily to check the backups. This should be done using a policy and applied to the view we just created.

Here’s the procedure:
<ScriptExport>
<Procedure name="Backup - Check WSB" treePres="3" id="429439652" folderId="871880402589167" treeFullPath="MSP.Monitoring">
<Body description="Checks for a successful Windows Server Backup in the last 24 hours. Raises an alarm and opens a ticket if not. This script should be applied to a view containing only endpoints using Windows Server Backup.">
<Statement description="Daily Windows Server Backup Check Powershell command returns a decimal number representing the number of days since the last successful backup. The monitor passes if the number returned is less than 1 (day)" name="Execute Powershell Command (64-bit, Run As System)" continueOnFail="false">
<Parameter xsi:type="StringParameter" name="Parameter1" value=""/>
<Parameter xsi:type="StringParameter" name="Parameter2" value="& {$ErrorActionPreference = 'SilentlyContinue';$ukCulture = [Globalization.cultureinfo]::GetCultureInfo('en-GB');add-pssnapin windows.serverbackup;$wbs = Get-Wbsummary;$lastsuccessfulbackuptime = $wbs.lastsuccessfulbackuptime;$TimeSpan = $(Get-Date) - [DateTime]$($wbs.lastsuccessfulbackuptime);write-output $($timespan.TotalDays)}"/>
<Parameter xsi:type="StringParameter" name="Parameter3" value="True"/>
</Statement>
<If description="">
<Condition name="CheckVariable">
<Parameter xsi:type="StringParameter" name="VariableName" value="#global:psresult#"/>
<Parameter xsi:type="EnumParameter" name="Condition" value="LessThan"/>
<Parameter xsi:type="StringParameter" name="Value" value="1"/>
</Condition>
<Then>
<Statement name="WriteScriptLogEntry" continueOnFail="false">
<Parameter xsi:type="StringParameter" name="Comment" value="Successful Backup in the last 24 hours"/>
</Statement>
<Statement name="WriteScriptLogEntry" continueOnFail="false">
<Parameter xsi:type="StringParameter" name="Comment" value="PS OUTPUT: #global:psresult#"/>
</Statement>
</Then>
<Else>
<Statement name="WriteScriptLogEntry" continueOnFail="false">
<Parameter xsi:type="StringParameter" name="Comment" value="Failed or no backup in the last 24 hours"/>
</Statement>
<Statement name="WriteScriptLogEntry" continueOnFail="false">
<Parameter xsi:type="StringParameter" name="Comment" value="PS OUTPUT: #global:psresult#"/>
</Statement>
<Statement name="GetVariable" continueOnFail="false">
<Parameter xsi:type="EnumParameter" name="VariableType" value="ConstantValue"/>
<Parameter xsi:type="StringParameter" name="SourceContent" value="Backup Failed"/>
<Parameter xsi:type="StringParameter" name="VariableName" value="alertSubject"/>
</Statement>
<Statement name="GetVariable" continueOnFail="false">
<Parameter xsi:type="EnumParameter" name="VariableType" value="ConstantValue"/>
<Parameter xsi:type="StringParameter" name="SourceContent" value="The windows server backup on <<id>> in group <<gr>> has failed and needs immediate attention."/>
<Parameter xsi:type="StringParameter" name="VariableName" value="alertBody"/>
</Statement>
<Statement description="If you only want an alarm without a ticket, delete the next line. " name="GetVariable" continueOnFail="false">
<Parameter xsi:type="EnumParameter" name="VariableType" value="ConstantValue"/>
<Parameter xsi:type="StringParameter" name="SourceContent" value="yes"/>
<Parameter xsi:type="StringParameter" name="VariableName" value="alertGenerateTicket"/>
</Statement>
<Statement name="SendAlert" continueOnFail="false"/>
</Else>
</If>
</Body>
</Procedure>
</ScriptExport>
This procedure runs a powershell command that returns the number of days since last successful backup in decimal format. If the number of days is greater than or equal to ‘1’ it raises an alarm and creates a ticket which will appear in BMS if you have the integration set up.
Did it work?
If you found this useful, let me know!
-Chris