Monitoring with PowerShell: Monitoring Storage Spaces and Windows RAID

So this blog was requested a lot lately – I’m not a big fan of using Windows RAID anywhere but Storage Spaces is becoming more relevant each day, with S2D and larger deployments. Storage Spaces is Microsoft’s successor to the classical Windows Software RAID options.

I’ve made some scripts for both options, but I sure advise to look into Storage Spaces over classical Windows software RAID in any case.

Windows RAID Monitoring

So let’s start with the one I do not prefer, just to get it out of the way 😉 Monitoring Windows RAID is not really as straightforward as you’d expect. The issue is that it’s quite OS dependent on what data is returned via the wmi instances. To avoid using WMI/CIM we’re using diskpart instead. Diskpart prints to the console and the content is not easily converted into a PowerShell object.

So in comes regex. I found another blogger that had a visual basic script to monitor Windows RAID and used his regular expression, but converted to PowerShell instead;

try {
    $volumes = "list volume" | diskpart | Where-Object { $_ -match "^  [^-]" } | Select-Object -skip 1

    $RAIDState = foreach ($row in $volumes) {
        if ($row -match "\s\s(Volume\s\d)\s+([A-Z])\s+(.*)\s\s(NTFS|FAT)\s+(Mirror|RAID-5|Stripe|Spanned)\s+(\d+)\s+(..)\s\s([A-Za-z]*\s?[A-Za-z]*)(\s\s)*.*") {
            $disk = $matches[2] 		
            if ($row -match "OK|Healthy") { $status = "OK" }
            if ($row -match "Rebuild") { $Status = 'Rebuilding' }
            if ($row -match "Failed|At Risk") { $status = "CRITICAL" }
	
            [pscustomobject]@{
                Disk   = $Disk
                Status = $status
            }
        }
    }
    $RAIDState = $RAIDState | Where-Object { $_.Status -ne "OK" }
}
catch {
    write-output "Command has Failed: $($_.Exception.Message)"

}

if ($RAIDState) {
    write-ouput"Check Diagnostics. Possible RAID failure."
    write-ouput $RAIDState
}
else {
    write-output "Healthy - No RAID Mirror issues found"
}

And that’s it for this one. This will show the state of each disk and alert is if it anything but OK.

Monitoring Storage Spaces and physical disks

So monitoring Storage Spaces is a lot easier; the cmdlets are the same everywhere and it doesn’t require extracting information from other sources. All you need is to monitor both the physical disk, and the storage pool;


try {
    $Disks = get-physicaldisk | Where-Object { $_.HealthStatus -ne "Healthy" }
}
catch {
    write-output "Command has Failed: $($_.Exception.Message)"
    exit 1
}

if ($disks) {
    write-output "Check Diagnostics. Possible disk failure."
    write-output $disks
    exit 1
}
else {
    write-output "Healthy - No Physical Disk issues found"
}

This script would show the current physical disk health status, this is a combination of write-endurance on SSDs, SMART status for HDDs and other info that windows collects by default. You don’t need storage spaces for that portion, really.


try {
    $RAIDState = Get-VirtualDisk | where-object { $_.OperationalStatus -ne "OK"}
    }
    catch {
        write-output "Command has Failed: $($_.Exception.Message)"
        exit 1
    }
    
    if ($RAIDState) {
        write-output "Check Diagnostics. Possible RAID failure."
        write-output $RAIDState
        exit 1
    }
    else {
        write-output "Healthy - No StorageSpace issues found"
    }

And this one reports on the exact state of the virtual drive, thus if anything is wrong you’ll get an alert stating what happened. And that’s it for now! I hope you enjoyed and as always, Happy PowerShelling and I hope to see some of you at the #CyberDrainCTF!

Leave a comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.