Home > Microsoft, SCOM 2007, SQL Server > Check your SQL backup automatically

Check your SQL backup automatically

Ever thought you had a good backup and it turned out it was missing when you needed a restore? Although a regular restore test is the least you can do, there is more. SQL Server stores backupinformation for all databases in msdb.dbo.backupset. A simple query shows you all databases that have no backup in the last two days:
SELECT DatabaseName = d.name
,LatetstBackUpDate = ISNULL(CONVERT(VARCHAR(30),MAX(b.backup_finish_date),120),’No backup’)
,’Days’ = MIN(DATEDIFF(hh,b.backup_finish_date,getdate())) / 24
,’Hours’ = MIN(DATEDIFF(hh,b.backup_finish_date,getdate())) % 24
FROM master.sys.databases d
LEFT OUTER JOIN msdb.dbo.backupset b ON d.name = b.database_name
WHERE d.name NOT IN (‘tempdb’,'model’)
GROUP BY d.name
HAVING ISNULL(MIN(DATEDIFF(hh,b.backup_finish_date,getdate())),999) >= 24 * 2 — change the 2 when you want to use a different amount of days
ORDER BY d.name

Wait, there is more! You don’t want to run this query every day by hand is it? Of course you can run it as a scheduled job on your database server, but even that can be a time-consuming task if you have a lot of servers. It would be better to run this query from System Center Operations Manager.


You can add the query in a System Center Opeations Management Monitor to deploy your backup check automatically to *all* SQL Servers within your organization. I’ll show you how to do it:
Create a “Timed Script Two State Monitor” (don’t forget to select an appropriate management pack to save your monitor).
Set the Monitor target to “SQL 2005 DB engine:
Create SQL Backup Monitor Step 2
In the next step, choose your schedule (once a day would be appropriate in most cases).
In the script page, name your script (don’t forget to add .vbs extension).
Paste the following script in the script box:


Dim i, oAPI, propertyBag, objShell
Dim strStatus
Dim objParameters, sConnectionString

' define constants
Const EVENT_TYPE_ERROR = 1
Const EVENT_TYPE_WARNING = 2
Const EVENT_TYPE_INFORMATION = 4

' check parameters
Set objParameters = WScript.Arguments
If objParameters.Count <> 1 Then
' Set objShell = Wscript.CreateObject("Wscript.Shell")
' objShell.LogEvent EVENT_TYPE_ERROR, "This Script requires exactly 1 parameter: ConnectionString"
WScript.Quit -1
End If

' map arguments to friendly names
sConnectionString= objParameters(0)

' initialize SQL statement
SCRIPT_SQL = "SELECT DatabaseName = d.name " & _
" ,LatetstBackUpDate = ISNULL(CONVERT(VARCHAR(30),MAX(b.backup_finish_date),120),'No backup') " & _
" ,(MIN(DATEDIFF(dd,d.create_date,getdate()))) 'age in days' " & _
" ,'Days' = MIN(DATEDIFF(hh,b.backup_finish_date,getdate())) / 24 " & _
" ,'Hours' = MIN(DATEDIFF(hh,b.backup_finish_date,getdate())) % 24 " & _
" FROM master.sys.databases d " & _
" LEFT OUTER JOIN msdb.dbo.backupset b ON d.name = b.database_name " & _
" WHERE d.name NOT IN ('tempdb','model') " & _
" GROUP BY d.name " & _
" HAVING (ISNULL(MIN(DATEDIFF(hh,b.backup_finish_date,getdate())),999) >= 24 * 2 " & _
" AND ((MIN(DATEDIFF(hh,d.create_date,getdate())) ) >= 1)) " & _
" ORDER BY d.name "

On Error resume next

' Setup Database connection
Set cnADOConnection = CreateObject("ADODB.Connection")
cnADOConnection.Provider = "sqloledb"
cnADOConnection.ConnectionTimeout = 30
strProv = "Server=" & sConnectionString & ";Database=master;Trusted_Connection=yes"

' open connection and execute query
cnADOConnection.Open strProv
Set rsLastBackup = cnADOConnection.Execute(SCRIPT_SQL)

i = 0

' check recordset for datbases without backup in last 48 hours
do until rsLastbackup.EOF
strDatabase = CStr(rsLastbackup("DatabaseName").Value)
strList = strList & strDatabase & ", "
Err.Clear
rsLastbackup.MoveNext
if 0 <> Err.number then Exit Do
i = i + 1
loop

' clean up connection
rsLastBackup.close
cnADOConnection.close

' Set SCOM parameters
Set oAPI = CreateObject("MOM.ScriptAPI")

' set state depending on databases without backup
If i > 0 Then
' wscript.echo strList
Call oAPI.LogScriptEvent("SQLBackupCheck", 2000, EVENT_TYPE_WARNING, "There are databases not in backup last 48 hours:" & strList)
strStatus = "Warning"
Else
' wscript.echo "healthy"
Call oAPI.LogScriptEvent("SQLBackupCheck", 2001, EVENT_TYPE_INFORMATION, "All databases in Backup correctly")
strStatus = "Healthy"
End If

' Return values to SCOM to set state and generate Alert
Set propertyBag = oAPI.CreatePropertyBag ()
Call propertyBag.AddValue ("Status", strStatus)
Call propertyBag.AddValue ("DBList", strList)
Call oAPI.Return(propertyBag)

Click on the Button “Paramaters…” at the bottom of this step.
Use the following code here, or select “Connection String (SQL DB Engine)” from the Target button.

$Target/Property[Type="MicrosoftSQLServerLibrary6064600!Microsoft.SQLServer.DBEngine"]/ConnectionString$

In the Unhealthy Expression step, add the following:Property[@Name='Status] Equals Warning
Create SQL Backup Monitor Step 5

For the healthy expression add: Property[@Name='Status'] Equals Healthy
In the next steps configure Health and Alerts according to your needs.

In the alert description you can use a text like this:
No SQL backup in last 48 hours on $Target/Host/Property[Type="Windows!Microsoft.Windows.Computer"]/NetbiosComputerName$ in instance $Target/Property[Type="MicrosoftSQLServerLibrary6064600!Microsoft.SQLServer.ServerRole"]/InstanceName$, list of databases: $Data/Context/Property[@Name='DBList']$

You are all done. The monitor will automatically run on all SQL Server instances to check when the last backup is made and warn you if that’s more than 2 days ago.

  1. November 6th, 2009 at 12:00 | #1
  2. December 13th, 2010 at 16:05 | #2

    Hi,
    thank you very much for description. If I try to create a monitor described in your blog, I receive the error message:
    Date: 13.12.2010 15:32:24
    Application: System Center Operations Manager 2007 R2
    Application Version: 6.1.7221.0
    Severity: Error
    Message:

    : Verification failed with [1] errors:
    ——————————————————-
    Error 1:
    : Failed to verify Unit monitor with ID: UIGeneratedMonitor8ed008bca1734da1874e7f49fe10f2ff
    Invalid AlertParameter [$Target/Host/Property[Type="Windows!Microsoft.Windows.Computer"]/NetbiosComputerName$] specified.Cannot resolve identifier [Windows!Microsoft.Windows.Computer] in the context of ManagementPack [Merck.SQL.Management.Pack]. Unknown alias [Windows]
    ——————————————————-

    Failed to verify Unit monitor with ID: UIGeneratedMonitor8ed008bca1734da1874e7f49fe10f2ffInvalid AlertParameter [$Target/Host/Property[Type="Windows!Microsoft.Windows.Computer"]/NetbiosComputerName$] specified.Cannot resolve identifier [Windows!Microsoft.Windows.Computer] in the context of ManagementPack [Merck.SQL.Management.Pack]. Unknown alias [Windows]
    : Failed to verify Unit monitor with ID: UIGeneratedMonitor8ed008bca1734da1874e7f49fe10f2ff
    Invalid AlertParameter [$Target/Host/Property[Type="Windows!Microsoft.Windows.Computer"]/NetbiosComputerName$] specified.Cannot resolve identifier [Windows!Microsoft.Windows.Computer] in the context of ManagementPack [Merck.SQL.Management.Pack]. Unknown alias [Windows]
    : Invalid AlertParameter [$Target/Host/Property[Type="Windows!Microsoft.Windows.Computer"]/NetbiosComputerName$] specified.
    Cannot resolve identifier [Windows!Microsoft.Windows.Computer] in the context of ManagementPack [Merck.SQL.Management.Pack]. Unknown alias [Windows]
    : Cannot resolve identifier [Windows!Microsoft.Windows.Computer] in the context of ManagementPack [Merck.SQL.Management.Pack]. Unknown alias [Windows]

    What is wrong in the configuration?

  3. Jan Jacob
    December 13th, 2010 at 21:51 | #3

    @Jozef Bineyti
    Hi Josef,

    This usually means your referring to a pointer that does not exist. Remove the reference to the NetBIOS name: $Target/Host/Property[Type="Windows!Microsoft.Windows.Computer"]/NetbiosComputerName$. You can manually add the parameter, click on the small arrow button next to the alert page field. You can select the NetBIOS computer name.

    Hope this helps

    Jan Jacob

  1. October 30th, 2009 at 10:25 | #1
  2. March 3rd, 2010 at 22:42 | #2