How to Set Up Windows Server 2019 Storage Replica

Storage Replica is a Windows Server feature that enables synchronous or asynchronous block-level replication between servers or clusters for disaster recovery and high availability. Available in both Windows Server 2019 Standard (limited to 2TB per volume) and Datacenter editions, Storage Replica replicates at the volume level, meaning all data on a volume is replicated regardless of file type or application. This guide covers server-to-server replication setup, testing failover, and monitoring replication health.

Storage Replica Prerequisites

Both source and destination servers must meet these requirements: Windows Server 2019 Standard or Datacenter, at least two volumes per server (one for data, one for the replication log), log volumes that are at least 8GB (9GB+ recommended for production), and log volumes formatted with NTFS or ReFS. The log volume should be on the fastest storage available — SSD is strongly recommended. Both servers must be accessible by hostname and have network connectivity for replication traffic.

# Install Storage Replica feature on both source and destination servers
Install-WindowsFeature -Name Storage-Replica -IncludeManagementTools -Restart

# Verify installation
Get-WindowsFeature -Name Storage-Replica | Select-Object Name, InstallState, DisplayName

Preparing Volumes for Replication

# On source server (SR-SRC): 
# - D: = data volume (to be replicated)
# - E: = log volume (dedicated, NTFS, SSD preferred)

# On destination server (SR-DST):
# - D: = replica volume (same size or larger than source)
# - E: = log volume (same size as source log volume)

# Verify volumes are NTFS or ReFS and have enough free space
Get-Volume | Where-Object { $_.DriveLetter -in @('D','E') } |
  Select-Object DriveLetter, FileSystem, Size, SizeRemaining

# Run the Storage Replica prerequisites test
Test-SRTopology `
  -SourceComputerName SR-SRC `
  -SourceVolumeName D: `
  -SourceLogVolumeName E: `
  -DestinationComputerName SR-DST `
  -DestinationVolumeName D: `
  -DestinationLogVolumeName E: `
  -DurationInMinutes 30 `
  -ResultPath C:SRTestResults

Configuring Server-to-Server Replication

# Create the replication partnership from source server
New-SRPartnership `
  -SourceComputerName SR-SRC `
  -SourceRGName SRC-RG01 `
  -SourceVolumeName D: `
  -SourceLogVolumeName E: `
  -DestinationComputerName SR-DST `
  -DestinationRGName DST-RG01 `
  -DestinationVolumeName D: `
  -DestinationLogVolumeName E: `
  -ReplicationMode Synchronous `
  -LogSizeInBytes 8GB

# For asynchronous replication (lower latency impact, some data loss on failure)
New-SRPartnership `
  -SourceComputerName SR-SRC `
  -SourceRGName SRC-RG01 `
  -SourceVolumeName D: `
  -SourceLogVolumeName E: `
  -DestinationComputerName SR-DST `
  -DestinationRGName DST-RG01 `
  -DestinationVolumeName D: `
  -DestinationLogVolumeName E: `
  -ReplicationMode Asynchronous `
  -LogSizeInBytes 8GB `
  -AsyncRPO 30  # Maximum allowed RPO in seconds

Monitoring Replication Status

# Check replication group status
Get-SRGroup | Select-Object Name, Replicas

# Detailed replication status per volume
(Get-SRGroup).Replicas | Select-Object ReplicationMode, ReplicationStatus, CurrentLsn, LastInSyncTime, DataVolume

# Monitor replication progress during initial sync
while ($true) {
    $status = (Get-SRGroup -ComputerName SR-SRC).Replicas | 
      Select-Object ReplicationStatus, PercentSynced, LastInSyncTime
    Write-Host "$(Get-Date -Format HH:mm:ss) Status: $($status.ReplicationStatus) | Synced: $($status.PercentSynced)%"
    if ($status.ReplicationStatus -eq "ContinuouslyReplicating") { break }
    Start-Sleep -Seconds 30
}

# Check replication on destination
Get-SRPartnership -ComputerName SR-DST | Select-Object *

Configuring Replication Network

# Specify a dedicated replication network to avoid saturating production traffic
Set-SRNetworkConstraint `
  -SourceComputerName SR-SRC `
  -SourceRGName SRC-RG01 `
  -SourceNWInterface "10.10.20.1" `
  -DestinationComputerName SR-DST `
  -DestinationRGName DST-RG01 `
  -DestinationNWInterface "10.10.20.2"

# Verify network constraints
Get-SRNetworkConstraint

Performing a Failover (Planned)

# Step 1: Verify replication is current
$replica = (Get-SRGroup -ComputerName SR-SRC).Replicas
if ($replica.ReplicationStatus -ne "ContinuouslyReplicating") {
    Write-Warning "Replication not current! Status: $($replica.ReplicationStatus)"
} else {
    Write-Output "Replication current. Last sync: $($replica.LastInSyncTime)"
}

# Step 2: Stop applications on source (drain connections, stop services)
Stop-Service -Name MyAppService -ComputerName SR-SRC

# Step 3: Switch replication direction (promotes destination to source)
Set-SRPartnership `
  -NewSourceComputerName SR-DST `
  -SourceRGName DST-RG01 `
  -DestinationComputerName SR-SRC `
  -DestinationRGName SRC-RG01

# Step 4: Verify destination volume is now accessible (no longer read-only)
Get-Volume -DriveLetter D -CimSession SR-DST | Select-Object DriveLetter, OperationalStatus

Testing Replication Without Failover

# Use Test-Failover to mount a snapshot of the destination volume (non-disruptive)
# Available in Windows Server 2019 Datacenter
Mount-SRDestination `
  -ComputerName SR-DST `
  -Name DST-RG01 `
  -TemporaryPath T:

# Verify data on the test mount
Get-ChildItem T:

# Dismount the test snapshot
Dismount-SRDestination -ComputerName SR-DST -Name DST-RG01

Storage Replica should be combined with regular failover testing on a quarterly basis to validate that replication is functioning correctly and that RTO (Recovery Time Objective) and RPO (Recovery Point Objective) targets are achievable. Document the complete failover procedure including application-specific steps and assign runbook responsibilities to ensure the team can execute failover under pressure during an actual disaster recovery scenario.