diff --git a/CLAUDE.md b/CLAUDE.md index 139660776641..7e63413d89fa 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -13,9 +13,9 @@ This style guide provides coding standards for dbatools PowerShell development t **MODERN RULE**: Do NOT use `Mandatory = $true` or similar boolean attribute assignments. Boolean attributes do not require explicit value assignment in modern PowerShell. ```powershell -# CORRECT - Modern attribute syntax (no = $true) +# CORRECT - Modern attribute syntax (no = $true), Position preserved param( - [Parameter(Mandatory)] + [Parameter(Mandatory, Position = 0)] [string]$SqlInstance, [Parameter(ValueFromPipeline)] @@ -26,18 +26,28 @@ param( # WRONG - Outdated PSv2 syntax (no longer needed) param( - [Parameter(Mandatory = $true)] + [Parameter(Mandatory = $true, Position = 0)] [string]$SqlInstance, [Parameter(ValueFromPipeline = $true)] [object[]]$InputObject ) + +# ALSO WRONG - Removing Position when it existed in original +param( + [Parameter(Mandatory)] # Missing Position = 0 (breaking change!) + [string]$SqlInstance +) ``` **Guidelines:** - Use `[Parameter(Mandatory)]` not `[Parameter(Mandatory = $true)]` - Use `[switch]` for boolean flags, not `[bool]` parameters - Keep non-boolean attributes with values: `[Parameter(ValueFromPipelineByPropertyName = "Name")]` +- **CRITICAL**: Always preserve `Position` attributes when modernizing - removing them is a breaking change + - `[Parameter(Mandatory, Position = 0)]` NOT `[Parameter(Mandatory)]` if Position was present + - Positional parameters allow users to call commands without parameter names + - Example: `Test-DbaAvailabilityGroup $instance` instead of `Test-DbaAvailabilityGroup -SqlInstance $instance` ### POWERSHELL v3 COMPATIBILITY @@ -325,6 +335,27 @@ function Set-DbaLogins { } function New-DbaAgents { } ``` +### Microsoft SMO Property Name Typos + +**CRITICAL KNOWLEDGE**: Some Microsoft SMO (SQL Server Management Objects) properties contain typos in their official names. These are NOT errors - they are the actual property names you must use. + +**Known typos that MUST be preserved:** + +1. **`AvailabilityDateabaseId`** (with typo: "Dateabase" instead of "Database") + - Used in: Availability Group DatabaseReplicaStates + - Correct usage: `Where-Object AvailabilityDateabaseId -eq $db.UniqueId` + - DO NOT "fix" this to `AvailabilityDatabaseId` - it will break the code + +```powershell +# CORRECT - Uses Microsoft's typo +$databaseReplicaState = $replicaStates | Where-Object AvailabilityDateabaseId -eq $db.UniqueId + +# WRONG - "Fixed" spelling will not work +$databaseReplicaState = $replicaStates | Where-Object AvailabilityDatabaseId -eq $db.UniqueId +``` + +**Important:** When reviewing or modifying code that uses SMO objects, verify the actual property names in Microsoft's documentation or SMO metadata before "correcting" apparent typos. The typo might be intentional (or at least unchangeable) in the SMO library. + ### Command Registration **CRITICAL RULE**: When adding a new command, you MUST register it in TWO places: @@ -418,6 +449,7 @@ AfterAll { ### Test Management Guidelines +The dbatools test suite must remain manageable in size while ensuring adequate coverage for important functionality. Follow these guidelines: The dbatools test suite must remain manageable in size while ensuring adequate coverage for important functionality. Follow these guidelines: **When to Update Tests:** @@ -425,6 +457,9 @@ The dbatools test suite must remain manageable in size while ensuring adequate c - **ADD tests for new functionality** - When adding new parameters or features, include tests that verify the new functionality works correctly - **ADD regression tests** when fixing a specific bug that needs to be prevented from recurring - **AVOID bloat** - Don't add generic coverage tests for basic operations unless they test a specific fix or new feature +- **ADD tests for new functionality** - When adding new parameters or features, include tests that verify the new functionality works correctly +- **ADD regression tests** when fixing a specific bug that needs to be prevented from recurring +- **AVOID bloat** - Don't add generic coverage tests for basic operations unless they test a specific fix or new feature **Parameter Validation Updates:** @@ -478,12 +513,46 @@ Context "Force parameter" { } ``` +**Tests for New Features:** + +When adding new parameters or functionality, include tests that verify the new feature works: + +```powershell +# GOOD - Test for a new parameter that filters results +Context "Filter by recovery model" { + It "Should return only databases with Full recovery model" { + $splatFilter = @{ + SqlInstance = $instance + RecoveryModel = "Full" + } + $result = Get-DbaDatabase @splatFilter + $result.RecoveryModel | Should -All -Be "Full" + } +} + +# GOOD - Test for a new switch parameter +Context "Force parameter" { + It "Should skip confirmation when -Force is used" { + $splatForce = @{ + SqlInstance = $instance + Database = $testDb + Force = $true + Confirm = $false + } + { Remove-DbaDatabase @splatForce } | Should -Not -Throw + } +} +``` + **Regression Tests:** +Add regression tests when fixing bugs: +- Fixing a specific, reproducible bug that should be prevented from recurring Add regression tests when fixing bugs: - Fixing a specific, reproducible bug that should be prevented from recurring - The bug is significant enough to warrant long-term protection - The test demonstrates the bug is fixed and prevents regression +- The test demonstrates the bug is fixed and prevents regression Example of when to add a regression test: @@ -508,15 +577,21 @@ Context "Regression tests" { ```powershell # WRONG - Adding general coverage tests for existing functionality without a fix +# WRONG - Adding general coverage tests for existing functionality without a fix It "Should return correct number of databases" { } It "Should handle empty result sets" { } It "Should work with pipeline input" { } +# WRONG - Generic edge case tests unrelated to changes +It "Should handle null parameters gracefully" { } +It "Should work with special characters in names" { } + # WRONG - Generic edge case tests unrelated to changes It "Should handle null parameters gracefully" { } It "Should work with special characters in names" { } ``` +Don't add tests for existing functionality unless you're fixing a bug or adding a new feature that needs verification. Don't add tests for existing functionality unless you're fixing a bug or adding a new feature that needs verification. ## VERIFICATION CHECKLIST @@ -526,6 +601,7 @@ Don't add tests for existing functionality unless you're fixing a bug or adding - [ ] Parameter names match original exactly without modification - [ ] No backticks used for line continuation - [ ] No `= $true` used in parameter attributes (use modern syntax) +- [ ] Position attributes preserved when modernizing parameters (critical for backward compatibility) - [ ] Splats used only for 3+ parameters **Version Compatibility:** @@ -547,11 +623,15 @@ Don't add tests for existing functionality unless you're fixing a bug or adding - [ ] Where-Object conversions applied appropriately - [ ] Temporary resource cleanup implemented properly - [ ] Splat usage follows 3+ parameter rule strictly +- [ ] Microsoft SMO property typos preserved (e.g., AvailabilityDateabaseId) **Command Registration (if adding new commands):** - [ ] Command name uses singular nouns (not plural) - [ ] Command uses approved PowerShell verb - [ ] Command follows `-Dba` naming pattern +- [ ] Command name uses singular nouns (not plural) +- [ ] Command uses approved PowerShell verb +- [ ] Command follows `-Dba` naming pattern - [ ] Command added to `FunctionsToExport` in dbatools.psd1 - [ ] Command added to `Export-ModuleMember` in dbatools.psm1 @@ -561,6 +641,10 @@ Don't add tests for existing functionality unless you're fixing a bug or adding - [ ] Regression tests added for significant bug fixes - [ ] Generic coverage tests avoided unless testing a specific fix or new feature - [ ] Test suite remains manageable and focused +- [ ] Tests added for new functionality and parameters (not just bloat) +- [ ] Regression tests added for significant bug fixes +- [ ] Generic coverage tests avoided unless testing a specific fix or new feature +- [ ] Test suite remains manageable and focused ## SUMMARY @@ -568,10 +652,13 @@ The golden rules for dbatools code: 1. **NEVER use backticks** - Use splats for 3+ parameters, direct syntax for 1-2 2. **NEVER use `= $true` in parameter attributes** - Use modern syntax: `[Parameter(Mandatory)]` not `[Parameter(Mandatory = $true)]` -3. **NEVER use `::new()` syntax** - Use `New-Object` for PowerShell v3 compatibility -4. **ALWAYS align hashtables** - Equals signs must line up vertically -5. **ALWAYS preserve comments** - Every comment stays exactly as written -6. **ALWAYS use double quotes** - SQL Server module standard -7. **ALWAYS use unique variable names** - Prevent scope collisions -8. **ALWAYS use descriptive splatnames** - `$splatConnection`, not `$splat` -9. **ALWAYS register new commands** - Add to both dbatools.psd1 and dbatools.psm1 +3. **NEVER remove Position attributes** - Preserve `Position = 0` when modernizing parameters to avoid breaking changes +4. **NEVER use `::new()` syntax** - Use `New-Object` for PowerShell v3 compatibility +5. **NEVER "fix" Microsoft SMO typos** - Properties like `AvailabilityDateabaseId` are correct as-is +6. **ALWAYS align hashtables** - Equals signs must line up vertically +7. **ALWAYS preserve comments** - Every comment stays exactly as written +8. **ALWAYS use double quotes** - SQL Server module standard +9. **ALWAYS use unique variable names** - Prevent scope collisions +10. **ALWAYS use descriptive splatnames** - `$splatConnection`, not `$splat` +11. **ALWAYS register new commands** - Add to both dbatools.psd1 and dbatools.psm1 +12. **ALWAYS use singular nouns** - Command names use singular, not plural diff --git a/public/Test-DbaAvailabilityGroup.ps1 b/public/Test-DbaAvailabilityGroup.ps1 index fc62cbba1799..1f19b1870296 100644 --- a/public/Test-DbaAvailabilityGroup.ps1 +++ b/public/Test-DbaAvailabilityGroup.ps1 @@ -48,6 +48,10 @@ function Test-DbaAvailabilityGroup { Validates that the most recent database backup chain can be used for AG database addition. Enables validation using existing backups instead of creating new ones, but requires the last backup to be a transaction log backup. Use this to test AG readiness with your current backup strategy. + .PARAMETER HealthCheck + Performs comprehensive health monitoring of the Availability Group similar to SSMS AG Dashboard. + Returns detailed replica and database synchronization status including queue sizes, LSN information, and performance metrics. Use this to monitor AG health, identify synchronization issues, or troubleshoot failover readiness. + .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. @@ -73,21 +77,27 @@ function Test-DbaAvailabilityGroup { PS C:\> Test-DbaAvailabilityGroup -SqlInstance SQL2016 -AvailabilityGroup TestAG1 -AddDatabase AdventureWorks -SeedingMode Automatic Test if database AdventureWorks can be added to the Availability Group TestAG1 with automatic seeding. + + .EXAMPLE + PS C:\> Test-DbaAvailabilityGroup -SqlInstance SQL2016 -AvailabilityGroup TestAG1 -HealthCheck + + Performs comprehensive health monitoring of TestAG1, returning detailed synchronization status for all replicas and databases similar to SSMS AG Dashboard. #> [CmdletBinding()] param ( - [Parameter(Mandatory = $true, Position = 0)] + [Parameter(Mandatory)] [DbaInstanceParameter]$SqlInstance, [PSCredential]$SqlCredential, - [Parameter(Mandatory = $true)] + [Parameter(Mandatory)] [string]$AvailabilityGroup, [DbaInstanceParameter[]]$Secondary, [PSCredential]$SecondarySqlCredential, [string[]]$AddDatabase, - [ValidateSet('Automatic', 'Manual')] + [ValidateSet("Automatic", "Manual")] [string]$SeedingMode, [string]$SharedPath, [switch]$UseLastBackup, + [switch]$HealthCheck, [switch]$EnableException ) process { @@ -110,22 +120,74 @@ function Test-DbaAvailabilityGroup { return } - if ($ag.LocalReplicaRole -ne 'Primary') { + if (-not $HealthCheck -and $ag.LocalReplicaRole -ne 'Primary') { Stop-Function -Message "LocalReplicaRole of replica $server is not Primary, but $($ag.LocalReplicaRole). Please connect to the current primary replica $($ag.PrimaryReplica)." return } # Test for health of Availability Group - # Later: Get replica and database states like in SSMS dashboard - # Now: Just test for ConnectionState -eq 'Connected' + if ($HealthCheck) { + # Comprehensive health monitoring similar to SSMS AG Dashboard + # Returns detailed database replica state information for all replicas + + foreach ($replica in $ag.AvailabilityReplicas) { + $replicaId = $replica.UniqueId + $replicaStates = $ag.DatabaseReplicaStates | Where-Object AvailabilityReplicaId -eq $replicaId - # Note on further development: - # As long as there are no databases in the Availability Group, test for RollupSynchronizationState is not useful + foreach ($db in $ag.AvailabilityDatabases) { + $databaseReplicaState = $replicaStates | Where-Object AvailabilityDateabaseId -eq $db.UniqueId + if ($null -eq $databaseReplicaState) { + continue + } - # The primary replica always has the best information about all the replicas. - # We can maybe also connect to the secondary replicas and test their view of the situation, but then only test the local replica. + [PSCustomObject]@{ + ComputerName = $ag.ComputerName + InstanceName = $ag.InstanceName + SqlInstance = $ag.SqlInstance + AvailabilityGroup = $ag.Name + PrimaryReplica = $ag.PrimaryReplica + ReplicaServerName = $databaseReplicaState.AvailabilityReplicaServerName + ReplicaRole = $databaseReplicaState.ReplicaRole + ReplicaAvailabilityMode = $replica.AvailabilityMode + ReplicaFailoverMode = $replica.FailoverMode + ReplicaConnectionState = $replica.ConnectionState + ReplicaJoinState = $replica.JoinState + ReplicaSynchronizationState = $replica.RollupSynchronizationState + DatabaseName = $databaseReplicaState.AvailabilityDatabaseName + SynchronizationState = $databaseReplicaState.SynchronizationState + IsFailoverReady = $databaseReplicaState.IsFailoverReady + IsJoined = $databaseReplicaState.IsJoined + IsSuspended = $databaseReplicaState.IsSuspended + SuspendReason = $databaseReplicaState.SuspendReason + EstimatedRecoveryTime = $databaseReplicaState.EstimatedRecoveryTime + EstimatedDataLoss = $databaseReplicaState.EstimatedDataLoss + SynchronizationPerformance = $databaseReplicaState.SynchronizationPerformance + LogSendQueueSize = $databaseReplicaState.LogSendQueueSize + LogSendRate = $databaseReplicaState.LogSendRate + RedoQueueSize = $databaseReplicaState.RedoQueueSize + RedoRate = $databaseReplicaState.RedoRate + FileStreamSendRate = $databaseReplicaState.FileStreamSendRate + EndOfLogLSN = $databaseReplicaState.EndOfLogLSN + RecoveryLSN = $databaseReplicaState.RecoveryLSN + TruncationLSN = $databaseReplicaState.TruncationLSN + LastCommitLSN = $databaseReplicaState.LastCommitLSN + LastCommitTime = $databaseReplicaState.LastCommitTime + LastHardenedLSN = $databaseReplicaState.LastHardenedLSN + LastHardenedTime = $databaseReplicaState.LastHardenedTime + LastReceivedLSN = $databaseReplicaState.LastReceivedLSN + LastReceivedTime = $databaseReplicaState.LastReceivedTime + LastRedoneLSN = $databaseReplicaState.LastRedoneLSN + LastRedoneTime = $databaseReplicaState.LastRedoneTime + LastSentLSN = $databaseReplicaState.LastSentLSN + LastSentTime = $databaseReplicaState.LastSentTime + } + } + } + return + } + # Basic connectivity test for non-HealthCheck scenarios $failure = $false foreach ($replica in $ag.AvailabilityReplicas) { if ($replica.ConnectionState -ne 'Connected') { @@ -138,7 +200,6 @@ function Test-DbaAvailabilityGroup { return } - # For now, just output the base information. if (-not $AddDatabase) { diff --git a/tests/Test-DbaAvailabilityGroup.Tests.ps1 b/tests/Test-DbaAvailabilityGroup.Tests.ps1 index 45d5efdd0241..52ff5227e1b9 100644 --- a/tests/Test-DbaAvailabilityGroup.Tests.ps1 +++ b/tests/Test-DbaAvailabilityGroup.Tests.ps1 @@ -20,9 +20,185 @@ Describe $CommandName -Tag UnitTests { "SeedingMode", "SharedPath", "UseLastBackup", + "HealthCheck", "EnableException" ) Compare-Object -ReferenceObject $expectedParameters -DifferenceObject $hasParameters | Should -BeNullOrEmpty } } +} + +Describe $CommandName -Tag IntegrationTests { + BeforeAll { + $PSDefaultParameterValues["*-Dba*:EnableException"] = $true + + $agName = "dbatoolsci_agroup_healthcheck" + $dbName = "dbatoolsci_agdb_$(Get-Random)" + + $splatPrimary = @{ + Primary = $TestConfig.instance3 + Name = $agName + ClusterType = "None" + FailoverMode = "Manual" + Certificate = "dbatoolsci_AGCert" + } + $null = New-DbaAvailabilityGroup @splatPrimary + + $splatDatabase = @{ + SqlInstance = $TestConfig.instance3 + Name = $dbName + Owner = "sa" + } + $null = New-DbaDatabase @splatDatabase + + $splatAddDatabase = @{ + SqlInstance = $TestConfig.instance3 + AvailabilityGroup = $agName + Database = $dbName + SeedingMode = "Automatic" + } + $null = Add-DbaAgDatabase @splatAddDatabase + + $PSDefaultParameterValues.Remove("*-Dba*:EnableException") + } + + AfterAll { + $PSDefaultParameterValues["*-Dba*:EnableException"] = $true + + $null = Remove-DbaAvailabilityGroup -SqlInstance $TestConfig.instance3 -AvailabilityGroup $agName + $null = Remove-DbaDatabase -SqlInstance $TestConfig.instance3 -Database $dbName + $null = Get-DbaEndpoint -SqlInstance $TestConfig.instance3 -Type DatabaseMirroring | Remove-DbaEndpoint + + $PSDefaultParameterValues.Remove("*-Dba*:EnableException") + } + + Context "When using -HealthCheck parameter" -Skip:$env:AppVeyor { + It "Returns health check results with expected properties" { + $results = Test-DbaAvailabilityGroup -SqlInstance $TestConfig.instance3 -AvailabilityGroup $agName -HealthCheck + $results | Should -Not -BeNullOrEmpty + $results.Count | Should -BeGreaterThan 0 + + $firstResult = $results | Select-Object -First 1 + $firstResult.ComputerName | Should -Not -BeNullOrEmpty + $firstResult.InstanceName | Should -Not -BeNullOrEmpty + $firstResult.SqlInstance | Should -Not -BeNullOrEmpty + $firstResult.AvailabilityGroup | Should -Be $agName + $firstResult.PrimaryReplica | Should -Not -BeNullOrEmpty + } + + It "Returns replica-level health information" { + $results = Test-DbaAvailabilityGroup -SqlInstance $TestConfig.instance3 -AvailabilityGroup $agName -HealthCheck + $firstResult = $results | Select-Object -First 1 + + $firstResult.ReplicaServerName | Should -Not -BeNullOrEmpty + $firstResult.ReplicaRole | Should -BeIn @("Primary", "Secondary") + $firstResult.ReplicaAvailabilityMode | Should -BeIn @("SynchronousCommit", "AsynchronousCommit") + $firstResult.ReplicaFailoverMode | Should -BeIn @("Manual", "Automatic") + $firstResult.ReplicaConnectionState | Should -BeIn @("Connected", "Disconnected") + $firstResult.ReplicaJoinState | Should -BeIn @("Joined", "NotJoined") + $firstResult.ReplicaSynchronizationState | Should -BeIn @("Synchronized", "Synchronizing", "NotSynchronizing", "PartiallyHealthy", "Healthy") + } + + It "Returns database-level synchronization information" { + $results = Test-DbaAvailabilityGroup -SqlInstance $TestConfig.instance3 -AvailabilityGroup $agName -HealthCheck + $dbResult = $results | Where-Object DatabaseName -eq $dbName + + $dbResult | Should -Not -BeNullOrEmpty + $dbResult.DatabaseName | Should -Be $dbName + $dbResult.SynchronizationState | Should -BeIn @("Synchronized", "Synchronizing", "NotSynchronizing", "Initializing", "Reverting") + $dbResult.PSObject.Properties.Name | Should -Contain "IsFailoverReady" + $dbResult.PSObject.Properties.Name | Should -Contain "IsJoined" + $dbResult.PSObject.Properties.Name | Should -Contain "IsSuspended" + $dbResult.PSObject.Properties.Name | Should -Contain "SuspendReason" + } + + It "Returns performance metrics for databases" { + $results = Test-DbaAvailabilityGroup -SqlInstance $TestConfig.instance3 -AvailabilityGroup $agName -HealthCheck + $firstResult = $results | Select-Object -First 1 + + $firstResult.PSObject.Properties.Name | Should -Contain "LogSendQueueSize" + $firstResult.PSObject.Properties.Name | Should -Contain "LogSendRate" + $firstResult.PSObject.Properties.Name | Should -Contain "RedoQueueSize" + $firstResult.PSObject.Properties.Name | Should -Contain "RedoRate" + $firstResult.PSObject.Properties.Name | Should -Contain "FileStreamSendRate" + } + + It "Returns LSN tracking information" { + $results = Test-DbaAvailabilityGroup -SqlInstance $TestConfig.instance3 -AvailabilityGroup $agName -HealthCheck + $firstResult = $results | Select-Object -First 1 + + $firstResult.PSObject.Properties.Name | Should -Contain "LastCommitLSN" + $firstResult.PSObject.Properties.Name | Should -Contain "LastCommitTime" + $firstResult.PSObject.Properties.Name | Should -Contain "LastHardenedLSN" + $firstResult.PSObject.Properties.Name | Should -Contain "LastHardenedTime" + $firstResult.PSObject.Properties.Name | Should -Contain "LastReceivedLSN" + $firstResult.PSObject.Properties.Name | Should -Contain "LastReceivedTime" + $firstResult.PSObject.Properties.Name | Should -Contain "LastRedoneLSN" + $firstResult.PSObject.Properties.Name | Should -Contain "LastRedoneTime" + $firstResult.PSObject.Properties.Name | Should -Contain "LastSentLSN" + $firstResult.PSObject.Properties.Name | Should -Contain "LastSentTime" + } + + It "Returns recovery metrics" { + $results = Test-DbaAvailabilityGroup -SqlInstance $TestConfig.instance3 -AvailabilityGroup $agName -HealthCheck + $firstResult = $results | Select-Object -First 1 + + $firstResult.PSObject.Properties.Name | Should -Contain "EstimatedRecoveryTime" + $firstResult.PSObject.Properties.Name | Should -Contain "EstimatedDataLoss" + $firstResult.PSObject.Properties.Name | Should -Contain "SynchronizationPerformance" + } + + It "Works with Linux AGs (instance3 is Linux)" { + $results = Test-DbaAvailabilityGroup -SqlInstance $TestConfig.instance3 -AvailabilityGroup $agName -HealthCheck + $results | Should -Not -BeNullOrEmpty + $results.Count | Should -BeGreaterThan 0 + $results.AvailabilityGroup | Should -Contain $agName + } + + It "Returns multiple results when AG has multiple databases" { + $PSDefaultParameterValues["*-Dba*:EnableException"] = $true + $secondDbName = "dbatoolsci_agdb2_$(Get-Random)" + + $splatDatabase2 = @{ + SqlInstance = $TestConfig.instance3 + Name = $secondDbName + Owner = "sa" + } + $null = New-DbaDatabase @splatDatabase2 + + $splatAddDatabase2 = @{ + SqlInstance = $TestConfig.instance3 + AvailabilityGroup = $agName + Database = $secondDbName + SeedingMode = "Automatic" + } + $null = Add-DbaAgDatabase @splatAddDatabase2 + $PSDefaultParameterValues.Remove("*-Dba*:EnableException") + + $results = Test-DbaAvailabilityGroup -SqlInstance $TestConfig.instance3 -AvailabilityGroup $agName -HealthCheck + $results.Count | Should -BeGreaterOrEqual 2 + + $dbNames = $results.DatabaseName | Select-Object -Unique + $dbNames | Should -Contain $dbName + $dbNames | Should -Contain $secondDbName + + $PSDefaultParameterValues["*-Dba*:EnableException"] = $true + $null = Remove-DbaAgDatabase -SqlInstance $TestConfig.instance3 -AvailabilityGroup $agName -Database $secondDbName + $null = Remove-DbaDatabase -SqlInstance $TestConfig.instance3 -Database $secondDbName + $PSDefaultParameterValues.Remove("*-Dba*:EnableException") + } + } + + Context "When using -HealthCheck without AddDatabase compatibility" -Skip:$env:AppVeyor { + It "Returns health check data without requiring database validation parameters" { + $results = Test-DbaAvailabilityGroup -SqlInstance $TestConfig.instance3 -AvailabilityGroup $agName -HealthCheck + $results | Should -Not -BeNullOrEmpty + $results.AvailabilityGroup | Should -Contain $agName + } + + It "Does not require primary replica connection when using -HealthCheck" { + $results = Test-DbaAvailabilityGroup -SqlInstance $TestConfig.instance3 -AvailabilityGroup $agName -HealthCheck + $results | Should -Not -BeNullOrEmpty + } + } } \ No newline at end of file