diff --git a/public/Restore-DbaDatabase.ps1 b/public/Restore-DbaDatabase.ps1 index c8b0286da45..59e9030cf9b 100644 --- a/public/Restore-DbaDatabase.ps1 +++ b/public/Restore-DbaDatabase.ps1 @@ -676,7 +676,12 @@ function Restore-DbaDatabase { if ($RestoreInstance.VersionMajor -eq 8 -and $true -ne $TrustDbBackupHistory) { foreach ($file in $Path) { - $bh = Get-DbaBackupInformation -SqlInstance $RestoreInstance -Path $file + $splatBackupInformation = @{ + SqlInstance = $RestoreInstance + Path = $file + EnableException = $EnableException + } + $bh = Get-DbaBackupInformation @splatBackupInformation $bound = $PSBoundParameters $bound['TrustDbBackupHistory'] = $true $bound['Path'] = $bh @@ -752,6 +757,7 @@ function Restore-DbaDatabase { IgnoreLogBackup = $IgnoreLogBackup StorageCredential = $StorageCredential NoXpDirRecurse = $NoXpDirRecurse + EnableException = $EnableException } $BackupHistory += Get-DbaBackupInformation @parms } @@ -815,7 +821,7 @@ function Restore-DbaDatabase { } if ($PSCmdlet.ParameterSetName -like "Restore*") { if ($BackupHistory.Count -eq 0 -and $RestoreInstance.VersionMajor -ne 8) { - Write-Message -Level Warning -Message "No backups passed through. `n This could mean the SQL instance cannot see the referenced files, the file's headers could not be read or some other issue" + Stop-Function -Message "No backups passed through. `n This could mean the SQL instance cannot see the referenced files, the file's headers could not be read or some other issue" return } Write-Message -message "Processing DatabaseName - $DatabaseName" -Level Verbose @@ -859,6 +865,7 @@ function Restore-DbaDatabase { ContinuePoints = $ContinuePoints LastRestoreType = $LastRestoreType DatabaseName = $DatabaseName + EnableException = $EnableException } $FilteredBackupHistory = $BackupHistory | Select-DbaBackupInformation @parms } diff --git a/tests/Restore-DbaDatabase.Tests.ps1 b/tests/Restore-DbaDatabase.Tests.ps1 index 35dd31ae76f..a9f705400f9 100644 --- a/tests/Restore-DbaDatabase.Tests.ps1 +++ b/tests/Restore-DbaDatabase.Tests.ps1 @@ -172,6 +172,76 @@ Describe $CommandName -Tag IntegrationTests { } + Context "Honors EnableException when no full backup anchors the chain #10621" { + BeforeAll { + $PSDefaultParameterValues["*-Dba*:EnableException"] = $true + + # Build a full/diff/log chain with one file per backup, so the diff and log never share a + # file with the full (the default backup file name has minute resolution and would hide + # the missing full by accident). + $chainDbName = "dbatoolsci_chaintest_$(Get-Random)" + $null = New-DbaDatabase -SqlInstance $TestConfig.InstanceSingle -Name $chainDbName + $splatChainBackup = @{ + SqlInstance = $TestConfig.InstanceSingle + Database = $chainDbName + Path = $backupPath + } + $null = Backup-DbaDatabase @splatChainBackup -Type Full -FilePath "chaintest_full.bak" + $chainDiff = Backup-DbaDatabase @splatChainBackup -Type Diff -FilePath "chaintest_diff.bak" + $chainLog = Backup-DbaDatabase @splatChainBackup -Type Log -FilePath "chaintest_log.trn" + + # An existing directory without any backup files, to hit the "No backups passed through" path. + $emptyBackupDir = "$backupPath\emptydir" + $null = New-Item -Path $emptyBackupDir -ItemType Directory + + $PSDefaultParameterValues.Remove("*-Dba*:EnableException") + } + + AfterAll { + $PSDefaultParameterValues["*-Dba*:EnableException"] = $true + + $null = Get-DbaDatabase -SqlInstance $TestConfig.InstanceSingle -Database $chainDbName | Remove-DbaDatabase + + $PSDefaultParameterValues.Remove("*-Dba*:EnableException") + } + + It "Throws when only diff and log are passed with EnableException" { + $splatRestore = @{ + SqlInstance = $TestConfig.InstanceSingle + Path = $chainDiff.BackupPath, $chainLog.BackupPath + DatabaseName = $chainDbName + WithReplace = $true + EnableException = $true + } + { Restore-DbaDatabase @splatRestore } | Should -Throw "*Fullname property not found*" + } + + It "Still warns and returns nothing without EnableException" { + $splatRestore = @{ + SqlInstance = $TestConfig.InstanceSingle + Path = $chainDiff.BackupPath, $chainLog.BackupPath + DatabaseName = $chainDbName + WithReplace = $true + WarningAction = "SilentlyContinue" + } + $results = Restore-DbaDatabase @splatRestore + $WarnVar | Should -BeLike "*Fullname property not found*" + $results | Should -BeNullOrEmpty + } + + It "Throws when the path holds no backups at all with EnableException" { + $splatRestore = @{ + SqlInstance = $TestConfig.InstanceSingle + Path = $emptyBackupDir + DatabaseName = $chainDbName + WithReplace = $true + EnableException = $true + } + { Restore-DbaDatabase @splatRestore } | Should -Throw "*No backups passed through*" + } + } + + Context "Database is restored with correct renamings" { BeforeAll { $null = Get-DbaDatabase -SqlInstance $TestConfig.InstanceSingle -ExcludeSystem -EnableException | Remove-DbaDatabase -EnableException