From 0a2047b6665f51409f01c19ae8638b3d85adaecd Mon Sep 17 00:00:00 2001 From: "claude[bot]" <41898282+claude[bot]@users.noreply.github.com> Date: Sat, 14 Mar 2026 16:18:11 +0000 Subject: [PATCH] Get-DbaLastBackup - Add -ExcludeReplica switch for AlwaysOn preferred backup replica filtering When running against AG members, secondary replicas appear to have no backups because backups are taken on the preferred replica. The new -ExcludeReplica switch uses sys.fn_hadr_backup_is_preferred_replica to skip databases where the current instance is not the preferred backup replica, eliminating false positives in multi-replica environments. Fixes #6525 (do Get-DbaLastBackup) Co-authored-by: Andreas Jordan --- public/Get-DbaLastBackup.ps1 | 24 ++++++++++++++++++++++++ tests/Get-DbaLastBackup.Tests.ps1 | 1 + 2 files changed, 25 insertions(+) diff --git a/public/Get-DbaLastBackup.ps1 b/public/Get-DbaLastBackup.ps1 index 898958350ba7..0f12c6e55880 100644 --- a/public/Get-DbaLastBackup.ps1 +++ b/public/Get-DbaLastBackup.ps1 @@ -25,6 +25,12 @@ function Get-DbaLastBackup { Excludes specific databases from the backup history check. Commonly used to skip system databases or test databases. Use this when you want to check most databases but exclude certain ones like tempdb, development databases, or databases with known backup exemptions. + .PARAMETER ExcludeReplica + When this switch is enabled, databases in an AlwaysOn Availability Group where the current SQL Server instance + is not the preferred backup replica are excluded from the results. + This is useful when running Get-DbaLastBackup against multiple servers in an availability group to avoid + false positives where secondary replicas appear to have missing backups because backups are taken on the preferred replica only. + .PARAMETER EnableException By default, when something goes wrong we try to catch it, interpret it and give you a friendly warning message. This avoids overwhelming you with "sea of red" exceptions, but is inconvenient because it basically disables advanced scripting. @@ -94,6 +100,13 @@ function Get-DbaLastBackup { PS C:\> Get-DbaLastBackup -SqlInstance ServerA\sql987 | Where-Object { $_.LastFullBackupIsCopyOnly -eq $true } Filters for the databases that had a copy_only full backup done as the last backup. + + .EXAMPLE + PS C:\> Get-DbaLastBackup -SqlInstance sql2019, sql2019b -ExcludeReplica + + Returns last backup information for all databases on both instances, excluding availability group databases + where the current instance is not the preferred backup replica. This prevents false alerts when secondary + replicas appear to have no recent backups because backups are only performed on the preferred replica. #> [CmdletBinding()] param ( @@ -103,6 +116,7 @@ function Get-DbaLastBackup { $SqlCredential, [object[]]$Database, [object[]]$ExcludeDatabase, + [switch]$ExcludeReplica, [switch]$EnableException ) begin { @@ -131,6 +145,16 @@ function Get-DbaLastBackup { if ($ExcludeDatabase) { $dbs = $dbs | Where-Object Name -NotIn $ExcludeDatabase } + + if ($ExcludeReplica -and $server.IsHadrEnabled) { + Write-Message -Level Verbose -Message "Excluding non-preferred backup replicas for $instance" + $notPreferredQuery = "SELECT DB_NAME(database_id) AS DatabaseName FROM sys.databases WHERE sys.fn_hadr_backup_is_preferred_replica(DB_NAME(database_id)) = 0" + $notPreferredDbs = ($server.Query($notPreferredQuery)).DatabaseName + if ($notPreferredDbs) { + $dbs = $dbs | Where-Object { $_.Name -notin $notPreferredDbs } + } + } + # Get-DbaDbBackupHistory -Last would make the job in one query but SMO's (and this) report the last backup of this type regardless of the chain $FullHistory = Get-DbaDbBackupHistory -SqlInstance $server -Database $dbs.Name -LastFull -IncludeCopyOnly -Raw $DiffHistory = Get-DbaDbBackupHistory -SqlInstance $server -Database $dbs.Name -LastDiff -IncludeCopyOnly -Raw diff --git a/tests/Get-DbaLastBackup.Tests.ps1 b/tests/Get-DbaLastBackup.Tests.ps1 index 817cea37a6d6..be0913a3c3b9 100644 --- a/tests/Get-DbaLastBackup.Tests.ps1 +++ b/tests/Get-DbaLastBackup.Tests.ps1 @@ -15,6 +15,7 @@ Describe $CommandName -Tag UnitTests { "SqlCredential", "Database", "ExcludeDatabase", + "ExcludeReplica", "EnableException" ) Compare-Object -ReferenceObject $expectedParameters -DifferenceObject $hasParameters | Should -BeNullOrEmpty