# Check Backup State on Microsoft Exchange 2016 # # This NSCP (former known as NSClient++) plugin checked the LastFullBackup information from an Exchange 2016 environment # and if that isnīt in the given timeframe it will generate an warning inside nagios. # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # Revision History # 2015-09-14 Bastian W. [Bastian@gmx-ist-cool.de] Created 0.4 # 2015-11-26 Bastian W. [Bastian@gmx-ist-cool.de] Created 0.5: # - Fixed an issue if the full backup field is empty # 2016-04-12 Bastian W. [Bastian@gmx-ist-cool.de] Created 1.0: # - Released first offical version # To execute from within NSClient++ # # [NRPE Handlers] # check_exchange_mailqueue=cmd /c echo C:\Scripts\Nagios\NagiosMonitoring_Exchange2010_BackupState.ps1 | PowerShell.exe -Command - # # On the check_nrpe command include the -t 30, since it takes some time to load the Exchange cmdlet's. # # Note: # - This script assume your are running a full backup every week (7 days) # - The script assume the full backup takes 8 hours! # If this isnīt the case you can adjust the values below # ToDos: # - Change the monitoring script so that it checks also the daily incremental backups # - Do Warning, Error, Critical States # Config $BackupFullRunTime = 8 # Hours it takes to perform a full backup; Default=8 $HoursUntilNewFullBackup = 168 # Hours which needs to pass until a new full backup is triggered; Default=168 # ============================================================================================================ # -------------------------------- DO NOT CHANGE ANYTHING BEHIND THIS LINE!!! -------------------------------- # Build with the help from the following URLS: # http://blogs.technet.com/b/timmcmic/archive/2012/05/14/backup-dates-and-times-are-incorrect-even-though-data-has-been-committed-to-backup-media-successfully.aspx # Internal Options $bDebugScript = 0 # Reset / declare variables [STRING]$strServer = "" $ARRAYBackupFullDetails = "" $intNagiosStatus = "" $intHostActive = "" $CalculatedLastBackupFullTime = "" $CountedDBsWithBackupIssues=0 $Now = get-date $strServer = $env:computername $strServerShort = $env:computername if ( (Get-PSSnapin -Name Microsoft.Exchange.Management.PowerShell.E2010 -ErrorAction:SilentlyContinue) -eq $null) { Add-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010 -EA SilentlyContinue } # In order to prevent recovery databases to pollute the open service problems each time a backup is restored #$Status = Get-MailboxDatabase -server $strServer | ? {-not $_.Recovery} | Get-MailboxDatabaseCopyStatus | Where-Object {$_.mailboxserver -match $strServerShort} #$Status = Get-MailboxDatabase -server $strServer | ? {-not $_.Recovery} | Get-MailboxDatabaseCopyStatus | Where-Object {$_.mailboxserver -match $strServer} # Check last backup #$ARRAYBackupFullDetails = @(Get-MailboxDatabase -server $strServer -status | Where-Object {-not $_.recovery -and $_.server -match $strServerShort} | Select-Object name, LastFullBackup ) #Get-MailboxDatabase -server $env:computername -status | Select-Object name, LastFullBackup, ServerName, MountedOnServer, LastIncrementalBackup #Get-MailboxDatabase -server $env:computername -status | Select-Object name, LastFullBackup, MountedOnServer, LastIncrementalBackup #Get-MailboxDatabase -Server $env:computername -Status | fl name,*BACKUP* $ARRAYBackupFullDetails = @(Get-MailboxDatabase -server $strServer -status | Where-Object {-not $_.recovery -and $_.server -match $strServer} | Select-Object name, LastFullBackup) $WarningList = @() $CriticalErrorList = @() #$CountMounted = 0 #$CountHealthy = 0 #$CountUnhealthy = 0 $OutputString = '' # Compare last backup date with current date, only when $ARRAYBackupFullDetails is not empty if ($ARRAYBackupFullDetails.count -gt 0) { if ($bDebugScript -eq 1){ Write-Host " Debug: We found some mounted DBs on server" -foregroundcolor Magenta} $CalculatedLastBackupFullTime = $HoursUntilNewFullBackup + $BackupFullRunTime #$ARRAYBackupFullDetails | Where-Object {$_.LastFullBackup -lt $Now.addhours(-168)} | % { $ARRAYBackupFullDetails | Where-Object {$_.LastFullBackup -lt $Now.addhours(-$CalculatedLastBackupFullTime)} | % { # We found a DB which do not have been backuped in the needed timeframe if ($bDebugScript -eq 1){ Write-Host " Debug: Found missing full backup for DB: $($_.name)" -foregroundcolor Magenta} $CurrentCalculatedTime = $Now.addhours(-$CalculatedLastBackupFullTime) if ($_.LastFullBackup -eq $null) { # The LastFullBackup is empty, so no full backup was performed if ($bDebugScript -eq 1){ Write-Host " Debug: No full backup for DB $($_.name) found!" -foregroundcolor Magenta} if ($CriticalErrorList) { $CriticalErrorList += ", No Backup for DB $($_.name) found" } else { $CriticalErrorList += "No Backup for DB $($_.name) found" } $CountedDBsWithBackupIssues += 1 } #elseif ($_.LastFullBackup -lt $Now.addhours(-168)) elseif ($_.LastFullBackup -lt $CurrentCalculatedTime) { # If last full backup is smaller (lt) as the callculated time $TempHours = $([Math]::floor(($now - $_.LastFullBackup).totalHours)) if ($TempHours -gt 8) { $TempHours = $TempHours / 8 $TempHours = $TempHours.ToString() + " days" } else { $TempHours = $TempHours.ToString() + " hours" } #if ($bDebugScript -eq 1){ Write-Host " Debug: DB $($_.name) hasn't been backed up for $([Math]::floor(($now - $_.LastFullBackup).totalHours)) hours" -foregroundcolor Magenta} if ($bDebugScript -eq 1){ Write-Host " Debug: DB $($_.name) hasn't been fully backed up for $TempHours" -foregroundcolor Magenta} #write-verbose 'error $($_.name)'; #$CriticalErrorList += "DB $($_.name) hasn't been backed up for $([Math]::floor(($now - $_.LastFullBackup).totalHours)) hours" if ($CriticalErrorList) { $CriticalErrorList += ", DB $($_.name) hasn't been backed up for $TempHours" } else { $CriticalErrorList += "DB $($_.name) hasn't been backed up for $TempHours" } $CountedDBsWithBackupIssues += 1 $TempHours = 0 } } #$TotalProblems = $WarningList.count + $CriticalErrorList.count $TotalProblems = $CriticalErrorList.count if ($TotalProblems -eq 0) { $OutputString = 'OK: All databases backups are ok.' $OutputString += " | 'Total DBs with Backup Problems'=0" Write-Host "$OutputString" exit 0 # Nagios Status = OK } else { #$OutputString = "CRITICAL: $CriticalErrorList" + ' - ' + "$WarningList $OutputString = "CRITICAL: $CriticalErrorList" #$OutputString += " | 'Total DBs with Backup Problems'=$TotalProblems" $OutputString += " | 'Total DBs with Backup Problems'=$CountedDBsWithBackupIssues" } if ($CriticalErrorList.count -ne 0) { Write-Host "$OutputString" exit 2 # Nagios Status = Critial } else { Write-Host "$OutputString" exit 1 # Nagios Status = Warning } } elseif ($ARRAYBackupFullDetails.count -eq 0) { if ($bDebugScript -eq 1){ Write-Host " Debug: No DBs mounted on current server" -foregroundcolor Magenta} # if we get a 0 counter here, it might be that no mailbox is mounted on that server! $OutputString = "OK: No mailbox databases mounted on $strServer!" $OutputString += " | 'Total DBs with Backup Problems'=0" Write-Host "$OutputString" exit 0 # Nagios Status = OK } else { if ($bDebugScript -eq 1){ Write-Host " Debug: Unexpected error!" -foregroundcolor Magenta} # if we get something else as a counter here $OutputString = "CRITICAL: Unexpected error occoured" #$OutputString += " | 'Total DBs with Backup Problems'=$TotalProblems" Write-Host "$OutputString" exit 2 # Nagios Status = Critical }