From 4ee6b239d7da517a6e9c867e0523f029307adeee Mon Sep 17 00:00:00 2001 From: "claude[bot]" <41898282+claude[bot]@users.noreply.github.com> Date: Sat, 14 Mar 2026 20:52:08 +0000 Subject: [PATCH 1/3] Install-DbaMaintenanceSolution: change Compress/Verify/CheckSum to ValidateSet string params Fixes #10183. The -Compress, -Verify and -CheckSum parameters were switches, which caused documentation/behaviour mismatches: - Switch default ($false) would set @Compress = 'N' even when not specified - Switch default ($false) would override Ola's @Verify = 'Y' default Changed all three to [string] with [ValidateSet('Default', 'ForceOn', 'ForceOff', 'Remove')]: - Default: leaves job text unchanged (Ola's defaults: Verify='Y', Checksum='Y', no Compress) - ForceOn: explicitly sets parameter to 'Y' - ForceOff: explicitly sets parameter to 'N' - Remove: strips the parameter from job text entirely Updated NUL+Verify validation to check for ForceOff/Remove instead of boolean false. Updated all integration tests to use the new string values. (do *MaintenanceSolution*) Co-authored-by: Andreas Jordan --- public/Install-DbaMaintenanceSolution.ps1 | 90 +++++++++++++------ .../Install-DbaMaintenanceSolution.Tests.ps1 | 44 ++++----- 2 files changed, 84 insertions(+), 50 deletions(-) diff --git a/public/Install-DbaMaintenanceSolution.ps1 b/public/Install-DbaMaintenanceSolution.ps1 index 3f1e1102d90b..675e8bff8620 100644 --- a/public/Install-DbaMaintenanceSolution.ps1 +++ b/public/Install-DbaMaintenanceSolution.ps1 @@ -82,8 +82,11 @@ function Install-DbaMaintenanceSolution { This ensures backup chains remain valid even if scheduled full backups fail or are missed. .PARAMETER Compress - Controls backup compression for all backup operations. When not specified, uses the SQL Server instance's default compression setting. - Set to enable compression (recommended for reducing backup size and network transfer time) or disable for compatibility with older restore targets. + Controls backup compression in job commands. Valid values: Default, ForceOn, ForceOff, Remove. + Default: does not include @Compress in job text, so the SQL Server instance's compression setting applies. + ForceOn: explicitly sets @Compress = 'Y' in job commands. + ForceOff: explicitly sets @Compress = 'N' in job commands. + Remove: removes @Compress from job commands if present. Only applies when InstallJobs is specified. .PARAMETER CopyOnly @@ -92,13 +95,19 @@ function Install-DbaMaintenanceSolution { Only applies when InstallJobs is specified. .PARAMETER Verify - Verifies backup integrity immediately after creation by performing a RESTORE VERIFYONLY operation. - Defaults to enabled (Y) if not specified. Verification adds time to backup operations but ensures backups are restorable. + Controls backup verification in job commands. Valid values: Default, ForceOn, ForceOff, Remove. + Default: uses Ola's default, which includes @Verify = 'Y' in job commands. + ForceOn: explicitly sets @Verify = 'Y' in job commands. + ForceOff: explicitly sets @Verify = 'N' in job commands. + Remove: removes @Verify from job commands, letting the stored procedure's built-in default apply. Only applies when InstallJobs is specified. .PARAMETER CheckSum - Enables checksum validation during backup operations to detect data corruption. - Defaults to enabled (Y) if not specified. Checksums provide additional data integrity verification with minimal performance impact. + Controls checksum validation in job commands. Valid values: Default, ForceOn, ForceOff, Remove. + Default: uses Ola's default, which includes @Checksum = 'Y' in job commands. + ForceOn: explicitly sets @CheckSum = 'Y' in job commands. + ForceOff: explicitly sets @CheckSum = 'N' in job commands. + Remove: removes @CheckSum from job commands, letting the stored procedure's built-in default apply. Only applies when InstallJobs is specified. .PARAMETER ModificationLevel @@ -257,9 +266,9 @@ function Install-DbaMaintenanceSolution { >> BackupLocation = "D:\SQLBackups" >> CleanupTime = 168 >> ChangeBackupType = $true - >> Compress = $true - >> Verify = $true - >> CheckSum = $true + >> Compress = "ForceOn" + >> Verify = "ForceOn" + >> CheckSum = "ForceOn" >> } PS C:\> Install-DbaMaintenanceSolution @params @@ -291,10 +300,13 @@ function Install-DbaMaintenanceSolution { [switch]$Force, [switch]$InstallParallel, [switch]$ChangeBackupType, - [switch]$Compress, + [ValidateSet('Default', 'ForceOn', 'ForceOff', 'Remove')] + [string]$Compress = "Default", [switch]$CopyOnly, - [switch]$Verify, - [switch]$CheckSum, + [ValidateSet('Default', 'ForceOn', 'ForceOff', 'Remove')] + [string]$Verify = "Default", + [ValidateSet('Default', 'ForceOn', 'ForceOff', 'Remove')] + [string]$CheckSum = "Default", [ValidateRange(0, 100)] [int]$ModificationLevel, [switch]$EnableException @@ -312,8 +324,8 @@ function Install-DbaMaintenanceSolution { return } - if ($BackupLocation -eq "NUL" -and $Verify) { - Stop-Function -Message "Verify is not supported when backing up to NUL. Either backup to a different directory or turn off Verify." + if ($BackupLocation -eq "NUL" -and $Verify -notin "ForceOff", "Remove") { + Stop-Function -Message "Verify is not supported when backing up to NUL. Either backup to a different directory or set -Verify to 'ForceOff' or 'Remove'." return } @@ -767,17 +779,21 @@ function Install-DbaMaintenanceSolution { } } - # Add Compress parameter for all backup jobs - if ($Compress) { + # Compress parameter for all backup jobs + # Default: do not include @Compress (instance-level setting applies) + if ($Compress -eq "ForceOn") { $modifiedCommand = $modifiedCommand -replace "@Compress = 'N'", "@Compress = 'Y'" if ($modifiedCommand -notmatch "@Compress") { $modifiedCommand = $modifiedCommand -replace "(@LogToTable = '[YN]')", "`$1,$([System.Environment]::NewLine)@Compress = 'Y'" } - } else { + } elseif ($Compress -eq "ForceOff") { $modifiedCommand = $modifiedCommand -replace "@Compress = 'Y'", "@Compress = 'N'" if ($modifiedCommand -notmatch "@Compress") { $modifiedCommand = $modifiedCommand -replace "(@LogToTable = '[YN]')", "`$1,$([System.Environment]::NewLine)@Compress = 'N'" - } + } + } elseif ($Compress -eq "Remove") { + $modifiedCommand = $modifiedCommand -replace "@Compress = '[YN]',\r?\n", "" + $modifiedCommand = $modifiedCommand -replace ",\r?\n@Compress = '[YN]'", "" } # Add CopyOnly parameter for all backup jobs @@ -787,20 +803,38 @@ function Install-DbaMaintenanceSolution { } } - # Add Verify parameter for all backup jobs - # Ola turns this on by default, so all we have to do is turn it off if asked. - if (-not $Verify) { - if ($modifiedCommand -notmatch "@Verify = 'N'") { - $modifiedCommand = $modifiedCommand -replace "@Verify = 'Y'", "@Verify = 'N'" + # Verify parameter for all backup jobs + # Ola includes @Verify = 'Y' by default. Default: leave unchanged. + if ($Verify -eq "ForceOn") { + $modifiedCommand = $modifiedCommand -replace "@Verify = 'N'", "@Verify = 'Y'" + if ($modifiedCommand -notmatch "@Verify") { + $modifiedCommand = $modifiedCommand -replace "(@LogToTable = '[YN]')", "`$1,$([System.Environment]::NewLine)@Verify = 'Y'" + } + } elseif ($Verify -eq "ForceOff") { + $modifiedCommand = $modifiedCommand -replace "@Verify = 'Y'", "@Verify = 'N'" + if ($modifiedCommand -notmatch "@Verify") { + $modifiedCommand = $modifiedCommand -replace "(@LogToTable = '[YN]')", "`$1,$([System.Environment]::NewLine)@Verify = 'N'" } + } elseif ($Verify -eq "Remove") { + $modifiedCommand = $modifiedCommand -replace "@Verify = '[YN]',\r?\n", "" + $modifiedCommand = $modifiedCommand -replace ",\r?\n@Verify = '[YN]'", "" } - # Add CheckSum parameter for all backup jobs - # Ola turns this on by default, so all we have to do is turn it off if asked. - if (-not $CheckSum) { - if ($modifiedCommand -notmatch "@CheckSum = 'N'") { - $modifiedCommand = $modifiedCommand -replace "@CheckSum = 'Y'", "@CheckSum = 'N'" + # CheckSum parameter for all backup jobs + # Ola includes @Checksum = 'Y' by default. Default: leave unchanged. + if ($CheckSum -eq "ForceOn") { + $modifiedCommand = $modifiedCommand -replace "@CheckSum = 'N'", "@CheckSum = 'Y'" + if ($modifiedCommand -notmatch "@CheckSum") { + $modifiedCommand = $modifiedCommand -replace "(@LogToTable = '[YN]')", "`$1,$([System.Environment]::NewLine)@CheckSum = 'Y'" + } + } elseif ($CheckSum -eq "ForceOff") { + $modifiedCommand = $modifiedCommand -replace "@CheckSum = 'Y'", "@CheckSum = 'N'" + if ($modifiedCommand -notmatch "@CheckSum") { + $modifiedCommand = $modifiedCommand -replace "(@LogToTable = '[YN]')", "`$1,$([System.Environment]::NewLine)@CheckSum = 'N'" } + } elseif ($CheckSum -eq "Remove") { + $modifiedCommand = $modifiedCommand -replace "@CheckSum = '[YN]',\r?\n", "" + $modifiedCommand = $modifiedCommand -replace ",\r?\n@CheckSum = '[YN]'", "" } # Update job step if command was modified diff --git a/tests/Install-DbaMaintenanceSolution.Tests.ps1 b/tests/Install-DbaMaintenanceSolution.Tests.ps1 index fb8dde631b8c..4390bc7a8dd2 100644 --- a/tests/Install-DbaMaintenanceSolution.Tests.ps1 +++ b/tests/Install-DbaMaintenanceSolution.Tests.ps1 @@ -156,10 +156,10 @@ Describe $CommandName -Tag IntegrationTests { ReplaceExisting = $true CleanupTime = 168 ChangeBackupType = $true - Compress = $true + Compress = "ForceOn" CopyOnly = $true - Verify = $true - CheckSum = $true + Verify = "ForceOn" + CheckSum = "ForceOn" ModificationLevel = 12 } $installResult = Install-DbaMaintenanceSolution @splatInstall @@ -387,10 +387,10 @@ Describe $CommandName -Tag IntegrationTests { ReplaceExisting = $true CleanupTime = 168 ChangeBackupType = $false - Compress = $false + Compress = "ForceOff" CopyOnly = $false - Verify = $false - CheckSum = $false + Verify = "ForceOff" + CheckSum = "ForceOff" } $installResult = Install-DbaMaintenanceSolution @splatInstall @@ -613,10 +613,10 @@ Describe $CommandName -Tag IntegrationTests { ReplaceExisting = $true CleanupTime = 168 ChangeBackupType = $false - Compress = $false + Compress = "ForceOff" CopyOnly = $false - Verify = $true - CheckSum = $false + Verify = "ForceOn" + CheckSum = "ForceOff" } $installResult = Install-DbaMaintenanceSolution @splatInstall @@ -781,13 +781,13 @@ Describe $CommandName -Tag IntegrationTests { It "Should error out and tell us our mistake" { $splatInstall = @{ - SqlInstance = $TestConfig.InstanceMulti2 - Database = $testDbName - InstallJobs = $true - ReplaceExisting = $true - Verify = $true - BackupLocation = "NUL" - EnableException = $true + SqlInstance = $TestConfig.InstanceMulti2 + Database = $testDbName + InstallJobs = $true + ReplaceExisting = $true + Verify = "ForceOn" + BackupLocation = "NUL" + EnableException = $true } $installResult = { Install-DbaMaintenanceSolution @splatInstall } | Should -Throw -ExpectedMessage '*NUL*' } @@ -853,10 +853,10 @@ Describe $CommandName -Tag IntegrationTests { ReplaceExisting = $true CleanupTime = 168 ChangeBackupType = $false - Compress = $false + Compress = "ForceOff" CopyOnly = $false - Verify = $false - CheckSum = $false + Verify = "ForceOff" + CheckSum = "ForceOff" } $installResult = Install-DbaMaintenanceSolution @splatInstall @@ -970,10 +970,10 @@ Describe $CommandName -Tag IntegrationTests { ReplaceExisting = $true CleanupTime = 168 ChangeBackupType = $false - Compress = $false + Compress = "ForceOff" CopyOnly = $false - Verify = $false - CheckSum = $true + Verify = "ForceOff" + CheckSum = "ForceOn" } $installResult = Install-DbaMaintenanceSolution @splatInstall From bfef0b6f6788911ec6f8311b3945ac20e428d0ff Mon Sep 17 00:00:00 2001 From: "claude[bot]" <41898282+claude[bot]@users.noreply.github.com> Date: Sun, 22 Mar 2026 17:30:52 +0000 Subject: [PATCH 2/3] Install-DbaMaintenanceSolution: add tests for Default and Remove parameter values Add two new integration test contexts covering the previously untested 'Default' and 'Remove' values for the Compress, Verify, and CheckSum parameters. - Default: Compress absent, Verify='Y' and CheckSum='Y' (Ola's defaults) - Remove: all three parameters stripped from job text (do Install-DbaMaintenanceSolution) Co-authored-by: Andreas Jordan --- .../Install-DbaMaintenanceSolution.Tests.ps1 | 238 ++++++++++++++++++ 1 file changed, 238 insertions(+) diff --git a/tests/Install-DbaMaintenanceSolution.Tests.ps1 b/tests/Install-DbaMaintenanceSolution.Tests.ps1 index 4390bc7a8dd2..199a4ff35f6b 100644 --- a/tests/Install-DbaMaintenanceSolution.Tests.ps1 +++ b/tests/Install-DbaMaintenanceSolution.Tests.ps1 @@ -727,6 +727,244 @@ Describe $CommandName -Tag IntegrationTests { } } + Context "Additional backup parameters with Default values" { + AfterEach { + Invoke-DbaQuery -SqlInstance $TestConfig.InstanceMulti2 -Query $jobStep.Command -NoExec -EnableException + } + + BeforeAll { + $PSDefaultParameterValues["*-Dba*:EnableException"] = $true + + # Clean up any leftover test databases from previous runs + $oldTestDbs = Get-DbaDatabase -SqlInstance $TestConfig.InstanceMulti2 | Where-Object Name -like "dbatoolsci_maintenancesolution_*" + if ($oldTestDbs) { + $null = Remove-DbaDatabase -SqlInstance $TestConfig.InstanceMulti2 -Database $oldTestDbs.Name -Confirm:$false + } + + # Clean up any leftover Hallengren jobs + $oldJobs = Get-DbaAgentJob -SqlInstance $TestConfig.InstanceMulti2 | Where-Object Description -match "hallengren" + if ($oldJobs) { + $null = Remove-DbaAgentJob -SqlInstance $TestConfig.InstanceMulti2 -Job $oldJobs.Name -Confirm:$false + } + + # Clean up any leftover Hallengren procedures in tempdb from the first Context + $cleanupTempdb = " + IF OBJECT_ID('dbo.CommandExecute', 'P') IS NOT NULL DROP PROCEDURE dbo.CommandExecute; + IF OBJECT_ID('dbo.DatabaseBackup', 'P') IS NOT NULL DROP PROCEDURE dbo.DatabaseBackup; + IF OBJECT_ID('dbo.DatabaseIntegrityCheck', 'P') IS NOT NULL DROP PROCEDURE dbo.DatabaseIntegrityCheck; + IF OBJECT_ID('dbo.IndexOptimize', 'P') IS NOT NULL DROP PROCEDURE dbo.IndexOptimize; + IF OBJECT_ID('dbo.CommandLog', 'U') IS NOT NULL DROP TABLE dbo.CommandLog; + IF OBJECT_ID('dbo.Queue', 'U') IS NOT NULL DROP TABLE dbo.Queue; + IF OBJECT_ID('dbo.QueueDatabase', 'U') IS NOT NULL DROP TABLE dbo.QueueDatabase; + " + $splatCleanupTempdb = @{ + SqlInstance = $TestConfig.InstanceMulti2 + Database = "tempdb" + Query = $cleanupTempdb + } + Invoke-DbaQuery @splatCleanupTempdb + + $testDbName = "dbatoolsci_maintenancesolution_$(Get-Random)" + $null = New-DbaDatabase -SqlInstance $TestConfig.InstanceMulti2 -Name $testDbName + + # Do not pass Compress, Verify, or CheckSum - let them all default to 'Default' + $splatInstall = @{ + SqlInstance = $TestConfig.InstanceMulti2 + Database = $testDbName + InstallJobs = $true + ReplaceExisting = $true + CleanupTime = 168 + } + $installResult = Install-DbaMaintenanceSolution @splatInstall + + # Verify installation succeeded before running tests + # Skip tests if installation failed (eg. due to event log limitations on AppVeyor or SQL Agent not running) + $script:installationSucceeded = $false + if ($installResult) { + $splatJobCheck = @{ + SqlInstance = $TestConfig.InstanceMulti2 + } + $fullBackupJob = Get-DbaAgentJob @splatJobCheck | Where-Object Name -eq "DatabaseBackup - USER_DATABASES - FULL" + if ($fullBackupJob) { + $script:installationSucceeded = $true + } + } + + $PSDefaultParameterValues.Remove("*-Dba*:EnableException") + } + + AfterAll { + $PSDefaultParameterValues["*-Dba*:EnableException"] = $true + + $null = Remove-DbaDatabase -SqlInstance $TestConfig.InstanceMulti2 -Database $testDbName -Confirm:$false + $jobs = Get-DbaAgentJob -SqlInstance $TestConfig.InstanceMulti2 | Where-Object Description -match "hallengren" + if ($jobs) { + $null = Remove-DbaAgentJob -SqlInstance $TestConfig.InstanceMulti2 -Job $jobs.Name -Confirm:$false + } + + $PSDefaultParameterValues.Remove("*-Dba*:EnableException") + } + + It "Should NOT add Compress parameter to backup jobs" { + if (-not $script:installationSucceeded) { + Set-ItResult -Skipped -Because "Installation failed" + return + } + $splatJobStep = @{ + SqlInstance = $TestConfig.InstanceMulti2 + Job = "DatabaseBackup - USER_DATABASES - FULL" + } + $jobStep = Get-DbaAgentJobStep @splatJobStep + $jobStep.Command | Should -Not -Match "@Compress" + } + + It "Should have Verify parameter set to Y in backup jobs" { + if (-not $script:installationSucceeded) { + Set-ItResult -Skipped -Because "Installation failed" + return + } + $splatJobStep = @{ + SqlInstance = $TestConfig.InstanceMulti2 + Job = "DatabaseBackup - USER_DATABASES - FULL" + } + $jobStep = Get-DbaAgentJobStep @splatJobStep + $jobStep.Command | Should -Match "@Verify = 'Y'" + } + + It "Should have CheckSum parameter set to Y in backup jobs" { + if (-not $script:installationSucceeded) { + Set-ItResult -Skipped -Because "Installation failed" + return + } + $splatJobStep = @{ + SqlInstance = $TestConfig.InstanceMulti2 + Job = "DatabaseBackup - USER_DATABASES - FULL" + } + $jobStep = Get-DbaAgentJobStep @splatJobStep + $jobStep.Command | Should -Match "@CheckSum = 'Y'" + } + } + + Context "Additional backup parameters all removed" { + AfterEach { + Invoke-DbaQuery -SqlInstance $TestConfig.InstanceMulti2 -Query $jobStep.Command -NoExec -EnableException + } + + BeforeAll { + $PSDefaultParameterValues["*-Dba*:EnableException"] = $true + + # Clean up any leftover test databases from previous runs + $oldTestDbs = Get-DbaDatabase -SqlInstance $TestConfig.InstanceMulti2 | Where-Object Name -like "dbatoolsci_maintenancesolution_*" + if ($oldTestDbs) { + $null = Remove-DbaDatabase -SqlInstance $TestConfig.InstanceMulti2 -Database $oldTestDbs.Name -Confirm:$false + } + + # Clean up any leftover Hallengren jobs + $oldJobs = Get-DbaAgentJob -SqlInstance $TestConfig.InstanceMulti2 | Where-Object Description -match "hallengren" + if ($oldJobs) { + $null = Remove-DbaAgentJob -SqlInstance $TestConfig.InstanceMulti2 -Job $oldJobs.Name -Confirm:$false + } + + # Clean up any leftover Hallengren procedures in tempdb from the first Context + $cleanupTempdb = " + IF OBJECT_ID('dbo.CommandExecute', 'P') IS NOT NULL DROP PROCEDURE dbo.CommandExecute; + IF OBJECT_ID('dbo.DatabaseBackup', 'P') IS NOT NULL DROP PROCEDURE dbo.DatabaseBackup; + IF OBJECT_ID('dbo.DatabaseIntegrityCheck', 'P') IS NOT NULL DROP PROCEDURE dbo.DatabaseIntegrityCheck; + IF OBJECT_ID('dbo.IndexOptimize', 'P') IS NOT NULL DROP PROCEDURE dbo.IndexOptimize; + IF OBJECT_ID('dbo.CommandLog', 'U') IS NOT NULL DROP TABLE dbo.CommandLog; + IF OBJECT_ID('dbo.Queue', 'U') IS NOT NULL DROP TABLE dbo.Queue; + IF OBJECT_ID('dbo.QueueDatabase', 'U') IS NOT NULL DROP TABLE dbo.QueueDatabase; + " + $splatCleanupTempdb = @{ + SqlInstance = $TestConfig.InstanceMulti2 + Database = "tempdb" + Query = $cleanupTempdb + } + Invoke-DbaQuery @splatCleanupTempdb + + $testDbName = "dbatoolsci_maintenancesolution_$(Get-Random)" + $null = New-DbaDatabase -SqlInstance $TestConfig.InstanceMulti2 -Name $testDbName + + $splatInstall = @{ + SqlInstance = $TestConfig.InstanceMulti2 + Database = $testDbName + InstallJobs = $true + ReplaceExisting = $true + CleanupTime = 168 + Compress = "Remove" + Verify = "Remove" + CheckSum = "Remove" + } + $installResult = Install-DbaMaintenanceSolution @splatInstall + + # Verify installation succeeded before running tests + # Skip tests if installation failed (eg. due to event log limitations on AppVeyor or SQL Agent not running) + $script:installationSucceeded = $false + if ($installResult) { + $splatJobCheck = @{ + SqlInstance = $TestConfig.InstanceMulti2 + } + $fullBackupJob = Get-DbaAgentJob @splatJobCheck | Where-Object Name -eq "DatabaseBackup - USER_DATABASES - FULL" + if ($fullBackupJob) { + $script:installationSucceeded = $true + } + } + + $PSDefaultParameterValues.Remove("*-Dba*:EnableException") + } + + AfterAll { + $PSDefaultParameterValues["*-Dba*:EnableException"] = $true + + $null = Remove-DbaDatabase -SqlInstance $TestConfig.InstanceMulti2 -Database $testDbName -Confirm:$false + $jobs = Get-DbaAgentJob -SqlInstance $TestConfig.InstanceMulti2 | Where-Object Description -match "hallengren" + if ($jobs) { + $null = Remove-DbaAgentJob -SqlInstance $TestConfig.InstanceMulti2 -Job $jobs.Name -Confirm:$false + } + + $PSDefaultParameterValues.Remove("*-Dba*:EnableException") + } + + It "Should NOT have Compress parameter in backup jobs" { + if (-not $script:installationSucceeded) { + Set-ItResult -Skipped -Because "Installation failed" + return + } + $splatJobStep = @{ + SqlInstance = $TestConfig.InstanceMulti2 + Job = "DatabaseBackup - USER_DATABASES - FULL" + } + $jobStep = Get-DbaAgentJobStep @splatJobStep + $jobStep.Command | Should -Not -Match "@Compress" + } + + It "Should NOT have Verify parameter in backup jobs" { + if (-not $script:installationSucceeded) { + Set-ItResult -Skipped -Because "Installation failed" + return + } + $splatJobStep = @{ + SqlInstance = $TestConfig.InstanceMulti2 + Job = "DatabaseBackup - USER_DATABASES - FULL" + } + $jobStep = Get-DbaAgentJobStep @splatJobStep + $jobStep.Command | Should -Not -Match "@Verify" + } + + It "Should NOT have CheckSum parameter in backup jobs" { + if (-not $script:installationSucceeded) { + Set-ItResult -Skipped -Because "Installation failed" + return + } + $splatJobStep = @{ + SqlInstance = $TestConfig.InstanceMulti2 + Job = "DatabaseBackup - USER_DATABASES - FULL" + } + $jobStep = Get-DbaAgentJobStep @splatJobStep + $jobStep.Command | Should -Not -Match "@CheckSum" + } + } + # This case is special. We try to make the install fail. Context "Backup to Nul with Verify on" { BeforeAll { From 85ed7cb0a90f4c8b7c4d969939aa5e4b09f8553c Mon Sep 17 00:00:00 2001 From: "claude[bot]" <41898282+claude[bot]@users.noreply.github.com> Date: Sun, 22 Mar 2026 18:52:29 +0000 Subject: [PATCH 3/3] Install-DbaMaintenanceSolution: add tests for Default and Remove parameter values Add 'Defaults for unspecified parameters are as documentation says' context with tests suggested by ReeceGoding covering: - No Compress parameter when not specified - Verify='Y' by default (Ola's default) - CheckSum='Y' by default (Ola's default) - StartTime set to 011500 when using AutoScheduleJobs='WeeklyFull' - BackupLocation defaults to instance default path Co-authored-by: ReeceGoding Co-authored-by: Andreas Jordan --- .../Install-DbaMaintenanceSolution.Tests.ps1 | 143 ++++++++++++++++++ 1 file changed, 143 insertions(+) diff --git a/tests/Install-DbaMaintenanceSolution.Tests.ps1 b/tests/Install-DbaMaintenanceSolution.Tests.ps1 index 199a4ff35f6b..8ab5b2633950 100644 --- a/tests/Install-DbaMaintenanceSolution.Tests.ps1 +++ b/tests/Install-DbaMaintenanceSolution.Tests.ps1 @@ -1265,4 +1265,147 @@ Describe $CommandName -Tag IntegrationTests { $jobStep.Command | Should -Match "@CheckSum = 'Y'" } } + + Context "Defaults for unspecified parameters are as documentation says" { + BeforeAll { + $PSDefaultParameterValues["*-Dba*:EnableException"] = $true + + # Clean up any leftover test databases from previous runs + $oldTestDbs = Get-DbaDatabase -SqlInstance $TestConfig.InstanceMulti2 | Where-Object Name -like "dbatoolsci_maintenancesolution_*" + if ($oldTestDbs) { + $null = Remove-DbaDatabase -SqlInstance $TestConfig.InstanceMulti2 -Database $oldTestDbs.Name -Confirm:$false + } + + # Clean up any leftover Hallengren jobs + $oldJobs = Get-DbaAgentJob -SqlInstance $TestConfig.InstanceMulti2 | Where-Object Description -match "hallengren" + if ($oldJobs) { + $null = Remove-DbaAgentJob -SqlInstance $TestConfig.InstanceMulti2 -Job $oldJobs.Name -Confirm:$false + } + + # Clean up any leftover Hallengren procedures in tempdb from the first Context + $cleanupTempdb = " + IF OBJECT_ID('dbo.CommandExecute', 'P') IS NOT NULL DROP PROCEDURE dbo.CommandExecute; + IF OBJECT_ID('dbo.DatabaseBackup', 'P') IS NOT NULL DROP PROCEDURE dbo.DatabaseBackup; + IF OBJECT_ID('dbo.DatabaseIntegrityCheck', 'P') IS NOT NULL DROP PROCEDURE dbo.DatabaseIntegrityCheck; + IF OBJECT_ID('dbo.IndexOptimize', 'P') IS NOT NULL DROP PROCEDURE dbo.IndexOptimize; + IF OBJECT_ID('dbo.CommandLog', 'U') IS NOT NULL DROP TABLE dbo.CommandLog; + IF OBJECT_ID('dbo.Queue', 'U') IS NOT NULL DROP TABLE dbo.Queue; + IF OBJECT_ID('dbo.QueueDatabase', 'U') IS NOT NULL DROP TABLE dbo.QueueDatabase; + " + $splatCleanupTempdb = @{ + SqlInstance = $TestConfig.InstanceMulti2 + Database = "tempdb" + Query = $cleanupTempdb + } + Invoke-DbaQuery @splatCleanupTempdb + + $testDbName = "dbatoolsci_maintenancesolution_$(Get-Random)" + $null = New-DbaDatabase -SqlInstance $TestConfig.InstanceMulti2 -Name $testDbName + + $splatInstall = @{ + SqlInstance = $TestConfig.InstanceMulti2 + # We could test that the default database is master, + # but that is currently enforced at the PowerShell level + # so it could just be a unit test. + Database = $testDbName + InstallJobs = $true + ReplaceExisting = $true + AutoScheduleJobs = "WeeklyFull" + } + $installResult = Install-DbaMaintenanceSolution @splatInstall + + # Verify installation succeeded before running tests + # Skip tests if installation failed (eg. due to event log limitations on AppVeyor or SQL Agent not running) + $script:installationSucceeded = $false + if ($installResult) { + $splatJobCheck = @{ + SqlInstance = $TestConfig.InstanceMulti2 + } + $fullBackupJob = Get-DbaAgentJob @splatJobCheck | Where-Object Name -eq "DatabaseBackup - USER_DATABASES - FULL" + if ($fullBackupJob) { + $script:installationSucceeded = $true + } + } + + $PSDefaultParameterValues.Remove("*-Dba*:EnableException") + } + + AfterAll { + $PSDefaultParameterValues["*-Dba*:EnableException"] = $true + + $null = Remove-DbaDatabase -SqlInstance $TestConfig.InstanceMulti2 -Database $testDbName -Confirm:$false + $jobs = Get-DbaAgentJob -SqlInstance $TestConfig.InstanceMulti2 | Where-Object Description -match "hallengren" + if ($jobs) { + $null = Remove-DbaAgentJob -SqlInstance $TestConfig.InstanceMulti2 -Job $jobs.Name -Confirm:$false + } + + $PSDefaultParameterValues.Remove("*-Dba*:EnableException") + } + + It "Should NOT have Compress parameter in backup jobs" { + if (-not $script:installationSucceeded) { + Set-ItResult -Skipped -Because "Installation failed" + return + } + $splatJobStep = @{ + SqlInstance = $TestConfig.InstanceMulti2 + Job = "DatabaseBackup - USER_DATABASES - FULL" + } + $jobStep = Get-DbaAgentJobStep @splatJobStep + $jobStep.Command | Should -Not -Match "@Compress" + } + + It "Should have Verify parameter set to Y in backup jobs" { + if (-not $script:installationSucceeded) { + Set-ItResult -Skipped -Because "Installation failed" + return + } + $splatJobStep = @{ + SqlInstance = $TestConfig.InstanceMulti2 + Job = "DatabaseBackup - USER_DATABASES - FULL" + } + $jobStep = Get-DbaAgentJobStep @splatJobStep + $jobStep.Command | Should -Match "@Verify = 'Y'" + } + + It "Should have CheckSum parameter set to Y in backup jobs" { + if (-not $script:installationSucceeded) { + Set-ItResult -Skipped -Because "Installation failed" + return + } + $splatJobStep = @{ + SqlInstance = $TestConfig.InstanceMulti2 + Job = "DatabaseBackup - USER_DATABASES - FULL" + } + $jobStep = Get-DbaAgentJobStep @splatJobStep + $jobStep.Command | Should -Match "@CheckSum = 'Y'" + } + + It "Should have StartTime set to 011500 in backup schedule" { + if (-not $script:installationSucceeded) { + Set-ItResult -Skipped -Because "Installation failed" + return + } + $schedule = Get-DbaAgentSchedule -SqlInstance $TestConfig.InstanceMulti2 + # We do not make any promises about job names, + # so checking for times is all we can do. + $schedule.ActiveStartTimeOfDay | + Where-Object { $_.Hours -eq 1 -and $_.Minutes -eq 15 } | + Should -Not -BeNullOrEmpty + } + + It "Should have BackupLocation parameter set to instance default in backup jobs" { + if (-not $script:installationSucceeded) { + Set-ItResult -Skipped -Because "Installation failed" + return + } + $splatJobStep = @{ + SqlInstance = $TestConfig.InstanceMulti2 + Job = "DatabaseBackup - USER_DATABASES - FULL" + } + $jobStep = Get-DbaAgentJobStep @splatJobStep + $backupLocationSetting = (Get-DbaDefaultPath -SqlInstance $TestConfig.InstanceMulti2).Backup + $jobStep.Command | Should -BeLike "*@Directory = *$backupLocationSetting*" + } + } }