internal/functions/Invoke-DbMirrorValidation.ps1
#ValidationTags#Messaging,FlowControl,Pipeline,CodeStyle# function Invoke-DbMirrorValidation { <# .SYNOPSIS Validates if a mirror is ready .DESCRIPTION Validates if a mirror is ready Thanks to https://github.com/mmessano/PowerShell/blob/master/SQL-ConfigureDatabaseMirroring.ps1 .PARAMETER Primary SQL Server name or SMO object representing the primary SQL Server. .PARAMETER PrimarySqlCredential Login to the primary instance using alternative credentials. Windows and SQL Authentication supported. Accepts credential objects (Get-Credential) .PARAMETER Mirror SQL Server name or SMO object representing the mirror SQL Server. .PARAMETER MirrorSqlCredential Login to the target instance using alternative credentials. Windows and SQL Authentication supported. Accepts credential objects (Get-Credential) .PARAMETER Witness SQL Server name or SMO object representing the witness SQL Server. .PARAMETER WitnessSqlCredential Login to the target instance using alternative credentials. Windows and SQL Authentication supported. Accepts credential objects (Get-Credential) .PARAMETER Database The database or databases to mirror .PARAMETER NetworkShare The network share where the backups will be .PARAMETER InputObject Enables piping from Get-DbaDatabase .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. Using this switch turns this "nice by default" feature off and enables you to catch exceptions with your own try/catch. .NOTES Tags: Mirror, HA Author: Chrissy LeMaire (@cl), netnerds.net dbatools PowerShell module (https://dbatools.io, clemaire@gmail.com) Copyright: (c) 2018 by dbatools, licensed under MIT License: MIT https://opensource.org/licenses/MIT .EXAMPLE PS C:\> $params = @{ Primary = 'sql2017a' Mirror = 'sql2017b' MirrorSqlCredential = 'sqladmin' Witness = 'sql2019' Database = 'onthewall' NetworkShare = '\\nas\sql\share' } PS C:\> Invoke-DbMirrorValidation @params Do things #> [CmdletBinding()] param ( [DbaInstanceParameter]$Primary, [PSCredential]$PrimarySqlCredential, [parameter(Mandatory)] [DbaInstanceParameter[]]$Mirror, [PSCredential]$MirrorSqlCredential, [DbaInstanceParameter]$Witness, [PSCredential]$WitnessSqlCredential, [string[]]$Database, [string]$NetworkShare, [parameter(ValueFromPipeline)] [Microsoft.SqlServer.Management.Smo.Database[]]$InputObject, [switch]$EnableException ) process { if ((Test-Bound -ParameterName Primary) -and (Test-Bound -Not -ParameterName Database)) { Stop-Function -Message "Database is required when SqlInstance is specified" return } $InputObject += Get-DbaDatabase -SqlInstance $Primary -SqlCredential $SqlCredential -Database $Database foreach ($db in $InputObject) { $server = $db.Parent $dbname = $db.Name $canmirror = $true $dest = Connect-DbaInstance -SqlInstance $Mirror -Credential $MirrorSqlCredential $endpoints = @() $endpoints += Get-DbaEndpoint -SqlInstance $server | Where-Object EndpointType -eq DatabaseMirroring $endpoints += Get-DbaEndpoint -SqlInstance $dest | Where-Object EndpointType -eq DatabaseMirroring if (Test-Bound -ParameterName Witness) { try { $witserver = Connect-DbaInstance -SqlInstance $Witness -SqlCredential $WitnessSqlCredential $endpoints += Get-DbaEndpoint -SqlInstance $witserver | Where-Object EndpointType -eq DatabaseMirroring $witdb = Get-DbaDatabase -SqlInstance $witserver -Database $db.Name $wexists = $true if ($witdb.Status -ne 'Restoring') { $canmirror = $false } if ($witdb) { $witexists = $true } else { Write-Message -Level Verbose -Message "Database ($dbname) exists on witness server" $canmirror = $false $witexists = $false } } catch { $wexists = $false $canmirror = $false } } if ($db.MirroringStatus -ne [Microsoft.SqlServer.Management.Smo.MirroringStatus]::None) { Write-Message -Level Verbose -Message "Cannot setup mirroring on database ($dbname) due to its current mirroring state: $($db.MirroringStatus)" $canmirror = $false } if ($db.Status -ne [Microsoft.SqlServer.Management.Smo.DatabaseStatus]::Normal) { Write-Message -Level Verbose -Message "Cannot setup mirroring on database ($dbname) due to its current Status: $($db.Status)" $canmirror = $false } if ($db.RecoveryModel -ne 'Full') { Write-Message -Level Verbose -Message "Cannot setup mirroring on database ($dbname) due to its current recovery model: $($db.RecoveryModel)" $canmirror = $false } $destdb = Get-DbaDatabase -SqlInstance $dest -Database $db.Name if ($destdb.RecoveryModel -ne 'Full') { $canmirror = $false } if ($destdb.Status -ne 'Restoring') { $canmirror = $false } if ($destdb) { $destdbexists = $true } else { Write-Message -Level Verbose -Message "Database ($dbname) does not exist on mirror server" $canmirror = $false $destdbexists = $false } if ((Test-Bound -ParameterName NetworkShare) -and -not (Test-DbaPath -SqlInstance $dest -Path $NetworkShare)) { Write-Message -Level Verbose -Message "Cannot access $NetworkShare from $($destdb.Parent.Name)" $canmirror = $false $nexists = $false } else { $nexists = $true } if ($server.EngineEdition -ne $dest.EngineEdition) { Write-Message -Level Verbose -Message "This mirroring configuration is not supported. Because the principal server instance, $server, is $($server.EngineEdition) Edition, the mirror server instance must also be $($server.EngineEdition) Edition." $canmirror = $false $edition = $false } else { $edition = $true } # There's a better way to do this but I'm sleepy if ((Test-Bound -ParameterName Witness)) { if ($endpoints.Count -eq 3) { $endpointpass = $true } else { $endpointpass = $false } } else { if ($endpoints.Count -eq 2) { $endpointpass = $true } else { $endpointpass = $false } } $results = [pscustomobject]@{ Primary = $Primary Mirror = $Mirror Witness = $Witness Database = $db.Name RecoveryModel = $db.RecoveryModel MirroringStatus = $db.MirroringStatus State = $db.Status EndPoints = $endpointpass DatabaseExistsOnMirror = $destdbexists DatabaseExistsOnWitness = $witexists OnlineWitness = $wexists EditionMatch = $edition AccessibleShare = $nexists DestinationDbStatus = $destdb.Status WitnessDbStatus = $witdb.Status ValidationPassed = $canmirror } if ((Test-Bound -ParameterName Witness)) { $results | Select-DefaultView -Property Primary, Mirror, Witness, Database, RecoveryModel, MirroringStatus, State, EndPoints, DatabaseExistsOnMirror, OnlineWitness, DatabaseExistsOnWitness, EditionMatch, AccessibleShare, DestinationDbStatus, WitnessDbStatus, ValidationPassed } else { $results | Select-DefaultView -Property Primary, Mirror, Database, RecoveryModel, MirroringStatus, State, EndPoints, DatabaseExistsOnMirror, EditionMatch, AccessibleShare, DestinationDbStatus, ValidationPassed } } } } |