How to Diagnose and Repair Degraded Mirror Virtual Disks in Windows Server 2012 Storage Spaces


2 views

When working with Windows Server 2012 Storage Spaces, encountering a "Degraded" status on mirror virtual disks is more common than you might think. From the provided PowerShell outputs, we can see:

  • 4 healthy physical disks (2.73TB each) in a single storage pool
  • 3 virtual disks configured with 2-way mirror resiliency
  • Two virtual disks (Data and Work) showing Degraded/Warning status

First, let's verify the physical disk health status:

Get-PhysicalDisk | Where-Object {$_.HealthStatus -ne "Healthy"} | Format-Table -AutoSize

The key indicators in your VirtualDisk output show:

NumberOfAvailableCopies : 0
OperationalStatus      : Degraded

This suggests the mirror redundancy has been temporarily lost, likely due to:

  • Brief physical disk disconnection
  • Storage Spaces not automatically repairing the mirror
  • Potential NTFS file system inconsistencies

Here's the step-by-step repair process I've used successfully in production:

# First, verify repair candidates
Get-VirtualDisk | Where-Object {$_.OperationalStatus -eq "Degraded"} | 
    Select-Object FriendlyName, OperationalStatus, HealthStatus

# Then repair each affected virtual disk
$degradedDisks = Get-VirtualDisk | Where-Object {$_.OperationalStatus -eq "Degraded"}
foreach ($disk in $degradedDisks) {
    Repair-VirtualDisk -FriendlyName $disk.FriendlyName
    Update-StorageProviderCache
    Optimize-StoragePool -FriendlyName "Pool"
}

If the standard repair doesn't work, try these advanced steps:

# Check for hidden disk errors
Get-StorageJob | Where-Object {$_.Name -like "*repair*"} | Format-List *

# Reset the storage bus (requires reboot)
Reset-PhysicalDisk -FriendlyName "PhysicalDisk2" # Repeat for all disks

# Force a manual repair by temporary removing a disk
Set-PhysicalDisk -FriendlyName "PhysicalDisk2" -Usage Retired
Start-Sleep -Seconds 30
Set-PhysicalDisk -FriendlyName "PhysicalDisk2" -Usage AutoSelect
Repair-VirtualDisk -FriendlyName "Work"

To maintain storage health, implement these PowerShell monitoring scripts:

# Scheduled task to check storage health daily
$checkScript = {
    $report = @()
    $vDisks = Get-VirtualDisk
    foreach ($disk in $vDisks) {
        if ($disk.OperationalStatus -ne "OK") {
            $report += "Alert: $($disk.FriendlyName) is $($disk.OperationalStatus)"
        }
    }
    if ($report) { Send-MailMessage -Body ($report -join "n") -Subject "Storage Alert" }
}

Register-ScheduledJob -Name "StorageHealthMonitor" -ScriptBlock $checkScript -Trigger (New-JobTrigger -Daily -At "3:00 AM")

Remember to periodically validate your storage configuration with:

Test-StoragePool -FriendlyName "Pool"

When working with Windows Server 2012 Storage Spaces, encountering a "Degraded" status on mirrored virtual disks despite all physical disks showing "Healthy" can be particularly frustrating. Here's what's happening under the hood:

PS C:\> Get-VirtualDisk -FriendlyName "Work" | Select-Object OperationalStatus, HealthStatus

OperationalStatus HealthStatus
----------------- ------------
Degraded          Warning

First, verify the complete storage subsystem status with these PowerShell commands:

# Check physical disks
Get-PhysicalDisk | Select FriendlyName, OperationalStatus, HealthStatus, Size

# Examine storage pool health
Get-StoragePool -FriendlyName "Pool" | Select HealthStatus, OperationalStatus

# Detailed virtual disk inspection
Get-VirtualDisk | Select FriendlyName, ResiliencySettingName, 
    OperationalStatus, HealthStatus, Size

To force a repair of the degraded virtual disks, follow this sequence:

# First, identify which physical disk might be causing issues
$problemDisk = Get-PhysicalDisk | Where-Object {$_.HealthStatus -ne "Healthy"}

# If all disks show Healthy, try manual repair
Get-VirtualDisk -FriendlyName "Work" | Repair-VirtualDisk -AsJob

# Monitor repair progress
Get-StorageJob | Where-Object {$_.Name -like "*Repair*"}

When standard repair fails, try these advanced methods:

# 1. Reset the virtual disk
Reset-VirtualDisk -FriendlyName "Work"

# 2. Check for hidden disk errors
Get-StorageReliabilityCounter -PhysicalDisk (Get-PhysicalDisk -FriendlyName "PhysicalDisk2") |
    Select-Object Temperature, ReadErrorsTotal, WriteErrorsTotal

# 3. Reattach physical disks
$disks = Get-PhysicalDisk | Where-Object {$_.CanPool -eq $false}
$disks | Set-PhysicalDisk -Usage Retired
$disks | Set-PhysicalDisk -Usage AutoSelect

Implement these PowerShell monitoring scripts to catch issues early:

# Scheduled task to check disk health daily
$action = New-ScheduledTaskAction -Execute "powershell.exe" 
    -Argument "Get-VirtualDisk | Where-Object {\$_.HealthStatus -ne 'Healthy'} | Send-MailMessage ..."
$trigger = New-ScheduledTaskTrigger -Daily -At 3am
Register-ScheduledTask -TaskName "Storage Health Monitor" 
    -Action $action -Trigger $trigger

# Event log monitoring
Get-WinEvent -LogName Microsoft-Windows-StorageSpaces-Driver/Operational |
    Where-Object {$_.LevelDisplayName -eq "Error"}

As a last resort, reconstruct the virtual disk while preserving data:

# 1. Create temporary backup
Robocopy E:\Data F:\Backup /MIR /ZB /R:1 /W:1 /V /TEE /LOG:C:\backup.log

# 2. Remove and recreate the virtual disk
Remove-VirtualDisk -FriendlyName "Work" -Confirm:$false
New-VirtualDisk -StoragePoolFriendlyName "Pool" -FriendlyName "Work" 
    -Size 2TB -ResiliencySettingName Mirror -NumberOfColumns 2 
    -ProvisioningType Thin

# 3. Restore data
Robocopy F:\Backup E:\Data /MIR /ZB /R:1 /W:1 /V /TEE /LOG:C:\restore.log