Skip to content

Instantly share code, notes, and snippets.

@SweetAsNZ
Last active January 19, 2026 21:41
Show Gist options
  • Select an option

  • Save SweetAsNZ/ee3daf460987cb9e402e99186b3659c2 to your computer and use it in GitHub Desktop.

Select an option

Save SweetAsNZ/ee3daf460987cb9e402e99186b3659c2 to your computer and use it in GitHub Desktop.
Initiates a failover of an Exchange mailbox database to another server within its Database Availability Group (DAG). Waits if too may failovers have happened. Optionally choose the server or by default take the first one available
function Invoke-ExchangeDatabaseFailover {
<#
.SYNOPSIS
Initiates a failover of an Exchange mailbox database to another server within its Database Availability Group (DAG).
.DESCRIPTION
This function allows administrators to trigger a failover of a specified Exchange mailbox database to another server
within its Database Availability Group (DAG). Optionally, a target server can be specified for the failover.
.PARAMETER DatabaseName
The name of the Exchange mailbox database to failover.
.PARAMETER TargetServer
(Optional) The target server to which the database should be failed over. If not specified, the function will choose an appropriate server.
.PARAMETER LogFile
The path to the log file where operation details will be recorded. Defaults to a log file in the user's Documents folder.
.PARAMETER RetryCount
Number of retry attempts if no synchronized passive copies are found. Default is 2 retries (3 total attempts).
.PARAMETER RetryDelayMinutes
Number of minutes to wait between retry attempts. Default is 5 minutes.
.PARAMETER maxSyncAttempts
Maximum number of attempts to verify that the previous active server's copy is synchronized after failover. Default is 60 attempts.
.EXAMPLE
Invoke-ExchangeDatabaseFailover "DB01"
Initiates a failover of the "DB01" mailbox database to the first available healthy passive copy in its DAG.
.EXAMPLE
Invoke-ExchangeDatabaseFailover -DatabaseName "DB01" -TargetServer "Server1"
Initiates a failover of the "DB01" mailbox database to the specific server "Server1".
.NOTES
Author: Tim West
Created: 19/01/2026
Updated: 20/01/2026
Status: Production
Version: 1.5.2
.CHANGELOG
2026-01-19: Initial version with basic failover logic
2026-01-19: Fixed DAG lookup to use Get-MailboxDatabase with DatabaseName parameter
2026-01-19: Added safe Exchange snap-in loading with error handling
2026-01-19: Fixed server name extraction from Name property (Database\Server format)
2026-01-19: Added passive copy selection logic that excludes current active server
2026-01-19: Added comprehensive logging of all database copies with status details
2026-01-19: Improved error handling - log before throw in all catch blocks
2026-01-19: Added fallback selection for passive copies when no healthy copies available
2026-01-19: Enhanced log file structure with timestamps and session markers
2026-01-19: Added handling for OutOfMemoryException with user guidance
2026-01-19: Added safety checks - prevent failover to seeding or out-of-sync copies (ReplayQueueLength > 0)
2026-01-19: Added retry logic with configurable wait time (default: 2 retries with 5 minute delays)
2026-01-19: Added throttling detection with optional 65-minute wait and retry for 'too many moves' error
2026-01-20: Added verification loop with do-until to confirm database is mounted on target server (max 30 attempts, 10 second intervals)
2026-01-20: Added verification loop to confirm previous active server's copy is synchronized after failover (max 60 attempts, 10 second intervals)
#>
[CmdletBinding()]
param (
[Parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $true)]
[string]$DatabaseName,
[string]$TargetServer,
[string]$LogFile = "$($ENV:USERPROFILE)\Documents\WindowsPowerShell\Scripts\Exchange\Invoke-ExchangeDatabaseFailover\Invoke-ExchangeDatabaseFailover.log",
[int]$RetryCount = 2,
[int]$RetryDelayMinutes = 5,
[int]$maxSyncAttempts = 100 # Suggest 60 for High Performing Servers, 100 for Underpowered Servers/High Traffic Volumes
)
$LogFileDir = Split-Path -Path $LogFile -Parent
If(-not (Test-Path $LogFileDir)){
New-Item -Path $LogFileDir -ItemType Directory -Force | Out-Null
}
If(-not (Test-Path $LogFile)){
New-Item -Path $LogFile -ItemType File -Force | Out-Null
}
$Date = (Get-Date).ToString("yyyyMMdd HH:mm:ss.ffff")
Add-Content $LogFile -Value "`n$Date - Starting Invoke-ExchangeDatabaseFailover for database '$DatabaseName' by $($ENV:USERNAME)"
# Import the Exchange module (safe-add, may already be loaded in EMS)
try {
Add-PSSnapin Microsoft.Exchange.Management.PowerShell.SnapIn -ErrorAction Stop
}
catch {
Add-Content $LogFile -Value "Warning: Could not add Exchange snap-in: $($_.Exception.Message) by $($ENV:USERNAME)"
}
try {
# Get the mailbox database copy status and the mailbox database object
$mbdb = Get-MailboxDatabase -Identity $DatabaseName -ErrorAction Stop
$dagObj = $mbdb.MasterServerOrAvailabilityGroup
if ($dagObj) {
$dag = $dagObj.Name
Add-Content $LogFile -Value "Database '$DatabaseName' found in DAG '$dag' by $($ENV:USERNAME)."
}
else {
$dag = $null
Add-Content $LogFile -Value "Database '$DatabaseName' is not part of a DAG (checked by $($ENV:USERNAME))."
}
}
catch {
Add-Content $LogFile -Value "Error finding database '$DatabaseName' or DAG: $($_ | Out-String) by $($ENV:USERNAME)"
throw "Database '$DatabaseName' not found or not part of a DAG. See log: $LogFile"
}
# Perform the failover
if($dag){
if(-not $TargetServer){
$attempt = 0
$maxAttempts = $RetryCount + 1
$targetCopy = $null
while ($attempt -lt $maxAttempts -and -not $targetCopy) {
$attempt++
if ($attempt -gt 1) {
$waitSeconds = $RetryDelayMinutes * 60
Write-Host "No synchronized passive copies found. Waiting $RetryDelayMinutes minutes before retry $attempt of $RetryCount..." -ForegroundColor Yellow
Add-Content $LogFile -Value "No synchronized passive copies found. Waiting $RetryDelayMinutes minutes before retry $attempt of $RetryCount by $($ENV:USERNAME)."
Start-Sleep -Seconds $waitSeconds
Write-Host "Retry attempt $attempt of $RetryCount starting..." -ForegroundColor Yellow
Add-Content $LogFile -Value "Retry attempt $attempt of $RetryCount starting by $($ENV:USERNAME)."
}
try{
$copies = Get-MailboxDatabaseCopyStatus -Identity $DatabaseName -ErrorAction Stop
# Find the current active server (the one currently mounted)
# The Name property is in format "Database\Server", so we need to parse it
$currentActiveCopy = $copies | Where-Object { $_.Status -eq 'Mounted' }
if ($attempt -eq 1) {
Add-Content $LogFile -Value "Found current active copy for database '$DatabaseName' by $($ENV:USERNAME)."
}
if ($currentActiveCopy.Name -match '\\(.+)$') {
$currentActiveServer = $Matches[1]
if ($attempt -eq 1) {
Write-Host -f Green "Current active server for database '$DatabaseName' is '$currentActiveServer'."
Add-Content $LogFile -Value "Current active server for database '$DatabaseName' is '$currentActiveServer' by $($ENV:USERNAME)."
}
} else {
$currentActiveServer = $currentActiveCopy.MailboxServer
if ($attempt -eq 1) {
Add-Content $LogFile -Value "Parsed current active server for database '$DatabaseName' as '$currentActiveServer' by $($ENV:USERNAME)."
}
}
if ($attempt -eq 1) {
Add-Content $LogFile -Value "Current active server: '$currentActiveServer' by $($ENV:USERNAME)."
}
# Log the status of all copies for debugging
foreach ($copy in $copies) {
if ($copy.Name -match '\\(.+)$') {
$serverName = $Matches[1]
} else {
$serverName = $copy.MailboxServer
}
Add-Content $LogFile -Value "Attempt $attempt - Copy on server '$serverName': Name='$($copy.Name)', Status='$($copy.Status)', ContentIndexState='$($copy.ContentIndexState)', CopyQueueLength='$($copy.CopyQueueLength)', ReplayQueueLength='$($copy.ReplayQueueLength)', ActivationPreference='$($copy.ActivationPreference)' by $($ENV:USERNAME)"
}
# Select target server - exclude the current active server and prefer healthy, synchronized copies by activation preference
$passiveCopies = $copies | Where-Object { $_.Status -ne 'Mounted' }
Add-Content $LogFile -Value "Attempt $attempt - Found $($passiveCopies.Count) passive copies for database '$DatabaseName' by $($ENV:USERNAME)."
# Filter out seeding copies and out-of-sync copies (ReplayQueueLength > 0)
$syncedCopies = $passiveCopies | Where-Object {
$_.Status -ne 'Seeding' -and
$_.Status -ne 'Initializing' -and
$_.ReplayQueueLength -eq 0
}
Add-Content $LogFile -Value "Attempt $attempt - Found $($syncedCopies.Count) synchronized passive copies (not seeding, ReplayQueueLength = 0) by $($ENV:USERNAME)."
# Try to get healthy synchronized copy first, sorted by activation preference
$targetCopy = $syncedCopies | Where-Object { $_.Status -eq 'Healthy' } | Sort-Object ActivationPreference | Select-Object -First 1
if (-not $targetCopy) {
# Fallback: any synchronized passive copy
$targetCopy = $syncedCopies | Sort-Object ActivationPreference | Select-Object -First 1
if ($targetCopy) {
Add-Content $LogFile -Value "Attempt $attempt - No healthy synchronized copies found. Using synchronized copy with status '$($targetCopy.Status)' by $($ENV:USERNAME)."
}
}
if (-not $targetCopy -and $attempt -lt $maxAttempts) {
# Will retry
Add-Content $LogFile -Value "Attempt $attempt - No suitable synchronized passive copies found for database '$DatabaseName'. Will retry after delay by $($ENV:USERNAME)."
continue
}
if (-not $targetCopy) {
Add-Content $LogFile -Value "All $maxAttempts attempts exhausted. No candidate activation server found for database '$DatabaseName'. All passive copies are either seeding or out of sync (ReplayQueueLength > 0) by $($ENV:USERNAME)."
throw "No candidate activation server found for database '$DatabaseName' after $maxAttempts attempts. All passive copies are seeding or out of sync. See log: $LogFile"
}
# Extract server name from the target copy
if ($targetCopy.Name -match '\\(.+)$') {
$activateServer = $Matches[1]
Add-Content $LogFile -Value "Parsed target server for failover as '$activateServer' by $($ENV:USERNAME)."
} else {
$activateServer = $targetCopy.MailboxServer
Add-Content $LogFile -Value "Using MailboxServer property for target server: '$activateServer' by $($ENV:USERNAME)."
}
Add-Content $LogFile -Value "Selected target server: '$activateServer' for failover by $($ENV:USERNAME)."
Add-Content $LogFile -Value "Target copy status: Status='$($targetCopy.Status)', ReplayQueueLength='$($targetCopy.ReplayQueueLength)', CopyQueueLength='$($targetCopy.CopyQueueLength)' by $($ENV:USERNAME)."
Write-Host "Selected target: '$activateServer' (Status: $($targetCopy.Status), ReplayQueue: $($targetCopy.ReplayQueueLength), CopyQueue: $($targetCopy.CopyQueueLength))" -ForegroundColor Cyan
Move-ActiveMailboxDatabase -Identity $DatabaseName -ActivateOnServer $activateServer -Confirm:$false
Write-Host "Failover command executed. Verifying database is now active on '$activateServer'..." -ForegroundColor Cyan
Add-Content $LogFile -Value "Failover command executed for database '$DatabaseName' to server '$activateServer'. Verifying activation by $($ENV:USERNAME)."
# Verify the failover completed successfully
$failoverComplete = $false
$verifyAttempts = 0
$maxVerifyAttempts = 30
do {
$verifyAttempts++
Start-Sleep -Seconds 10
$updatedCopies = Get-MailboxDatabaseCopyStatus -Identity $DatabaseName -ErrorAction Stop
$mountedCopy = $updatedCopies | Where-Object { $_.Status -eq 'Mounted' }
if ($mountedCopy.Name -match '\\(.+)$') {
$currentMountedServer = $Matches[1]
} else {
$currentMountedServer = $mountedCopy.MailboxServer
}
if ($currentMountedServer -eq $activateServer) {
$failoverComplete = $true
Write-Host "Failover of database '$DatabaseName' confirmed successfully from '$currentActiveServer' to '$activateServer'." -ForegroundColor Green
Add-Content $LogFile -Value "Failover of database '$DatabaseName' from '$currentActiveServer' to '$activateServer' confirmed successful (verified mounted on target) by $($ENV:USERNAME) - Success"
}
else {
Write-Host "Verification attempt $verifyAttempts of $maxVerifyAttempts - Database still mounted on '$currentMountedServer', waiting..." -ForegroundColor Yellow
Add-Content $LogFile -Value "Verification attempt $verifyAttempts - Database '$DatabaseName' still mounted on '$currentMountedServer' by $($ENV:USERNAME)"
}
} while (-not $failoverComplete -and $verifyAttempts -lt $maxVerifyAttempts)
if (-not $failoverComplete) {
Write-Host "Warning: Failover command completed but database is still mounted on '$currentMountedServer' after $maxVerifyAttempts verification attempts." -ForegroundColor Yellow
Add-Content $LogFile -Value "Warning: Failover verification timeout - Database '$DatabaseName' still mounted on '$currentMountedServer' after $maxVerifyAttempts attempts by $($ENV:USERNAME)"
}
# Additional verification: Check that the previous active server's copy is now synchronized
if ($failoverComplete) {
Write-Host "Verifying that previous active server '$currentActiveServer' copy is synchronized..." -ForegroundColor Cyan
Add-Content $LogFile -Value "Checking synchronization status of previous active server '$currentActiveServer' by $($ENV:USERNAME)."
$syncComplete = $false
$syncAttempts = 0
do {
$syncAttempts++
Start-Sleep -Seconds 10
$updatedCopies = Get-MailboxDatabaseCopyStatus -Identity $DatabaseName -ErrorAction Stop
$previousActiveCopy = $updatedCopies | Where-Object {
if ($_.Name -match '\\(.+)$') { $Matches[1] -eq $currentActiveServer }
else { $_.MailboxServer -eq $currentActiveServer }
}
if ($previousActiveCopy.CopyQueueLength -eq 0 -and $previousActiveCopy.ReplayQueueLength -eq 0) {
$syncComplete = $true
Write-Host "Previous active server '$currentActiveServer' is now synchronized (CopyQueue: 0, ReplayQueue: 0)." -ForegroundColor Green
Add-Content $LogFile -Value "Previous active server '$currentActiveServer' synchronized successfully - CopyQueueLength: 0, ReplayQueueLength: 0 by $($ENV:USERNAME) - Success"
}
else {
Write-Host "Sync check $syncAttempts of $maxSyncAttempts - CopyQueue: $($previousActiveCopy.CopyQueueLength), ReplayQueue: $($previousActiveCopy.ReplayQueueLength), waiting..." -ForegroundColor Yellow
Add-Content $LogFile -Value "Sync attempt $syncAttempts - Previous server '$currentActiveServer': CopyQueue=$($previousActiveCopy.CopyQueueLength), ReplayQueue=$($previousActiveCopy.ReplayQueueLength) by $($ENV:USERNAME)"
}
} while (-not $syncComplete -and $syncAttempts -lt $maxSyncAttempts)
if (-not $syncComplete) {
Write-Host "Warning: Previous active server '$currentActiveServer' not fully synchronized after $maxSyncAttempts attempts (CopyQueue: $($previousActiveCopy.CopyQueueLength), ReplayQueue: $($previousActiveCopy.ReplayQueueLength))." -ForegroundColor Yellow
Add-Content $LogFile -Value "Warning: Sync verification timeout - Previous server '$currentActiveServer' not synchronized after $maxSyncAttempts attempts by $($ENV:USERNAME)"
}
}
}
catch {
$Err = $_.Exception.Message
# Check for "too many moves" throttling error
if ($Err -match 'too many moves have happened recently') {
Write-Host "`nExchange has blocked the move due to throttling - too many moves within 1 hour." -ForegroundColor Yellow
Add-Content $LogFile -Value "Move blocked by Exchange throttling: $Err by $($ENV:USERNAME)"
$waitMinutes = 65
$response = Read-Host "`nWait $waitMinutes minutes (1 hour 5 mins) and retry? (Y/N)"
if ($response -eq 'Y' -or $response -eq 'y') {
Write-Host "Waiting $waitMinutes minutes before retrying..." -ForegroundColor Cyan
Add-Content $LogFile -Value "User chose to wait $waitMinutes minutes for throttling window to expire by $($ENV:USERNAME)"
$waitSeconds = $waitMinutes * 60
$endTime = (Get-Date).AddSeconds($waitSeconds)
while ((Get-Date) -lt $endTime) {
$remaining = ($endTime - (Get-Date))
Write-Progress -Activity "Waiting for Exchange throttling window" `
-Status "Time remaining: $([math]::Floor($remaining.TotalMinutes)) minutes $($remaining.Seconds) seconds" `
-PercentComplete ((($waitSeconds - $remaining.TotalSeconds) / $waitSeconds) * 100)
Start-Sleep -Seconds 30
}
Write-Progress -Activity "Waiting for Exchange throttling window" -Completed
Write-Host "Wait complete. Retrying failover..." -ForegroundColor Cyan
Add-Content $LogFile -Value "Throttling wait complete. Retrying failover for database '$DatabaseName' by $($ENV:USERNAME)"
try {
Move-ActiveMailboxDatabase -Identity $DatabaseName -ActivateOnServer $activateServer -Confirm:$false
Write-Host "Failover command executed after throttling wait. Verifying database is now active on '$activateServer'..." -ForegroundColor Cyan
Add-Content $LogFile -Value "Failover command executed after throttling wait. Verifying activation by $($ENV:USERNAME)."
# Verify the failover completed successfully
$failoverComplete = $false
$verifyAttempts = 0
$maxVerifyAttempts = 30
do {
$verifyAttempts++
Start-Sleep -Seconds 10
$updatedCopies = Get-MailboxDatabaseCopyStatus -Identity $DatabaseName -ErrorAction Stop
$mountedCopy = $updatedCopies | Where-Object { $_.Status -eq 'Mounted' }
if ($mountedCopy.Name -match '\\(.+)$') {
$currentMountedServer = $Matches[1]
} else {
$currentMountedServer = $mountedCopy.MailboxServer
}
if ($currentMountedServer -eq $activateServer) {
$failoverComplete = $true
Write-Host "Failover of database '$DatabaseName' confirmed successfully from '$currentActiveServer' to '$activateServer' after throttling wait." -ForegroundColor Green
Add-Content $LogFile -Value "Failover confirmed successful after throttling wait by $($ENV:USERNAME) - Success"
}
else {
Write-Host "Verification attempt $verifyAttempts of $maxVerifyAttempts - Database still mounted on '$currentMountedServer', waiting..." -ForegroundColor Yellow
Add-Content $LogFile -Value "Post-throttling verification attempt $verifyAttempts - Database still on '$currentMountedServer' by $($ENV:USERNAME)"
}
} while (-not $failoverComplete -and $verifyAttempts -lt $maxVerifyAttempts)
if (-not $failoverComplete) {
Write-Host "Warning: Database still mounted on '$currentMountedServer' after $maxVerifyAttempts verification attempts." -ForegroundColor Yellow
Add-Content $LogFile -Value "Warning: Post-throttling failover verification timeout by $($ENV:USERNAME)"
}
# Additional verification: Check that the previous active server's copy is now synchronized
if ($failoverComplete) {
Write-Host "Verifying that previous active server '$currentActiveServer' copy is synchronized..." -ForegroundColor Cyan
Add-Content $LogFile -Value "Checking synchronization status of previous active server '$currentActiveServer' by $($ENV:USERNAME)."
$syncComplete = $false
$syncAttempts = 0
$maxSyncAttempts = 60
do {
$syncAttempts++
Start-Sleep -Seconds 10
$updatedCopies = Get-MailboxDatabaseCopyStatus -Identity $DatabaseName -ErrorAction Stop
$previousActiveCopy = $updatedCopies | Where-Object {
if ($_.Name -match '\\(.+)$') { $Matches[1] -eq $currentActiveServer }
else { $_.MailboxServer -eq $currentActiveServer }
}
if ($previousActiveCopy.CopyQueueLength -eq 0 -and $previousActiveCopy.ReplayQueueLength -eq 0) {
$syncComplete = $true
Write-Host "Previous active server '$currentActiveServer' is now synchronized (CopyQueue: 0, ReplayQueue: 0)." -ForegroundColor Green
Add-Content $LogFile -Value "Previous active server '$currentActiveServer' synchronized successfully - CopyQueueLength: 0, ReplayQueueLength: 0 by $($ENV:USERNAME) - Success"
}
else {
Write-Host "Sync check $syncAttempts of $maxSyncAttempts - CopyQueue: $($previousActiveCopy.CopyQueueLength), ReplayQueue: $($previousActiveCopy.ReplayQueueLength), waiting..." -ForegroundColor Yellow
Add-Content $LogFile -Value "Sync attempt $syncAttempts - Previous server '$currentActiveServer': CopyQueue=$($previousActiveCopy.CopyQueueLength), ReplayQueue=$($previousActiveCopy.ReplayQueueLength) by $($ENV:USERNAME)"
}
} while (-not $syncComplete -and $syncAttempts -lt $maxSyncAttempts)
if (-not $syncComplete) {
Write-Host "Warning: Previous active server '$currentActiveServer' not fully synchronized after $maxSyncAttempts attempts (CopyQueue: $($previousActiveCopy.CopyQueueLength), ReplayQueue: $($previousActiveCopy.ReplayQueueLength))." -ForegroundColor Yellow
Add-Content $LogFile -Value "Warning: Sync verification timeout - Previous server '$currentActiveServer' not synchronized after $maxSyncAttempts attempts by $($ENV:USERNAME)"
}
}
}
catch {
Add-Content $LogFile -Value "Retry after throttling wait - Move active mailbox database '$DatabaseName' to server '$activateServer' - FAILED"
Add-Content $LogFile -Value "$($_ | Out-String) by $($ENV:USERNAME) - FAILED"
throw "Failed to move active mailbox database '$DatabaseName' to server '$activateServer' after throttling wait. $($_.Exception.Message)"
}
}
else {
Add-Content $LogFile -Value "User declined to wait for throttling window. Move cancelled by $($ENV:USERNAME)"
throw "Failover cancelled by user. Exchange throttling requires waiting before retry. $Err"
}
}
else {
Add-Content $LogFile -Value "Move active mailbox database '$DatabaseName' to server '$activateServer' - FAILED"
Add-Content $LogFile -Value "$($_ | Out-String) by $($ENV:USERNAME) - FAILED"
if ($Err -match 'OutOfMemoryException') {
Write-Host "Exchange Server encountered an OutOfMemoryException. This is a server resource issue, not a script problem." -ForegroundColor Yellow
Write-Host "Recommended actions: Check Exchange server memory usage, restart Exchange services, or retry the operation." -ForegroundColor Yellow
}
throw "Failed to move active mailbox database '$DatabaseName' to server '$activateServer'. $Err"
}
}
}
}
else{
try{
Move-ActiveMailboxDatabase -Identity $DatabaseName -ActivateOnServer $TargetServer -Confirm:$false
Write-Host "Failover command executed. Verifying database is now active on '$TargetServer'..." -ForegroundColor Cyan
Add-Content $LogFile -Value "Failover command executed for database '$DatabaseName' to server '$TargetServer'. Verifying activation by $($ENV:USERNAME)."
# Verify the failover completed successfully
$failoverComplete = $false
$verifyAttempts = 0
$maxVerifyAttempts = 30
do {
$verifyAttempts++
Start-Sleep -Seconds 10
$updatedCopies = Get-MailboxDatabaseCopyStatus -Identity $DatabaseName -ErrorAction Stop
$mountedCopy = $updatedCopies | Where-Object { $_.Status -eq 'Mounted' }
if ($mountedCopy.Name -match '\\(.+)$') {
$currentMountedServer = $Matches[1]
} else {
$currentMountedServer = $mountedCopy.MailboxServer
}
if ($currentMountedServer -eq $TargetServer) {
$failoverComplete = $true
Write-Host "Failover of database '$DatabaseName' confirmed successfully to '$TargetServer'." -ForegroundColor Green
Add-Content $LogFile -Value "Failover of database '$DatabaseName' to server '$TargetServer' confirmed successful (verified mounted on target) by $($ENV:USERNAME) - Success"
}
else {
Write-Host "Verification attempt $verifyAttempts of $maxVerifyAttempts - Database still mounted on '$currentMountedServer', waiting..." -ForegroundColor Yellow
Add-Content $LogFile -Value "Verification attempt $verifyAttempts - Database '$DatabaseName' still mounted on '$currentMountedServer' by $($ENV:USERNAME)"
}
} while (-not $failoverComplete -and $verifyAttempts -lt $maxVerifyAttempts)
if (-not $failoverComplete) {
Write-Host "Warning: Failover command completed but database is still mounted on '$currentMountedServer' after $maxVerifyAttempts verification attempts." -ForegroundColor Yellow
Add-Content $LogFile -Value "Warning: Failover verification timeout - Database '$DatabaseName' still mounted on '$currentMountedServer' after $maxVerifyAttempts attempts by $($ENV:USERNAME)"
}
}
catch {
Add-Content $LogFile -Value "Move active mailbox database '$DatabaseName' to $($TargetServer) by $($ENV:USERNAME) - FAILED"
Add-Content $LogFile -Value "$($_ | Out-String)"
throw "Failed to move active mailbox database '$DatabaseName' to $($TargetServer) - FAILED. $($_)"
}
}
}
Add-Content $LogFile -Value "`n$Date - Completed Invoke-ExchangeDatabaseFailover.ps1 Script run by $($ENV:USERNAME)"
Add-Content $LogFile -Value "------------------------------------------------------------`n"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment