Тест скорости R/W и IOPS на всех дисках по выбору

Опубликовано jeord -

Помучал Deepseek, и получился прикольный скрипт для программы DiskSpd.

# ========== SETTINGS ==========
$DiskspdPath = "C:\temp\DiskSpd\amd64\diskspd.exe"
$TestSize = "500M"
$Duration = 10

# ========== CHECK DISKSPD ==========
if (-not (Test-Path $DiskspdPath)) {
   Write-Host "ERROR: Diskspd not found at $DiskspdPath" -ForegroundColor Red
   exit 1
}

# ========== GET AVAILABLE FIXED DRIVES WITH MODELS ==========
$PhysicalDisks = Get-PhysicalDisk | Select-Object DeviceId, Model, @{Name="SizeGB";Expression={[math]::Round($_.Size/1GB, 2)}}
$LogicalDisks = Get-WmiObject Win32_LogicalDisk | Where-Object { $_.DriveType -eq 3 }

$Drives = @()
foreach ($Logical in $LogicalDisks) {
   $Partition = Get-Partition -DriveLetter $Logical.DeviceID[0] -ErrorAction SilentlyContinue
   $PhysDisk = if ($Partition) { $PhysicalDisks | Where-Object { $_.DeviceId -eq $Partition.DiskNumber } } else { $null }
   
   $Drives += [PSCustomObject]@{
       DeviceID = $Logical.DeviceID
       SizeGB = [math]::Round($Logical.Size/1GB, 2)
       FreeGB = [math]::Round($Logical.FreeSpace/1GB, 2)
       Model = if ($PhysDisk) { $PhysDisk.Model } else { "Unknown" }
       IsSystem = ($Logical.DeviceID -eq "C:")
   }
}

Write-Host "========================================" -ForegroundColor Cyan
Write-Host "   DISK IOPS PERFORMANCE TEST" -ForegroundColor Cyan
Write-Host "========================================" -ForegroundColor Cyan
Write-Host ""
Write-Host "Available fixed drives:" -ForegroundColor Yellow
Write-Host ""

for ($i = 0; $i -lt $Drives.Count; $i++) {
   Write-Host "  [$($i+1)] $($Drives[$i].DeviceID) - $($Drives[$i].Model) ($($Drives[$i].SizeGB) GB)" -ForegroundColor White
}

Write-Host ""
Write-Host "  [A] Test ALL drives" -ForegroundColor Green
Write-Host "  [Q] Quit" -ForegroundColor Red
Write-Host ""
$Choice = Read-Host "Select drive number (or A/Q)"

if ($Choice -eq "Q") {
   Write-Host "Exiting..." -ForegroundColor Yellow
   exit 0
}

if ($Choice -eq "A") {
   $DrivesToTest = $Drives
} elseif ([int]$Choice -ge 1 -and [int]$Choice -le $Drives.Count) {
   $DrivesToTest = @($Drives[[int]$Choice - 1])
} else {
   Write-Host "Invalid choice. Exiting..." -ForegroundColor Red
   exit 1
}

Write-Host ""
Write-Host "WARNING: Tests will take ~30 seconds per drive." -ForegroundColor Yellow
Write-Host ""

# ========== FUNCTION TO EXTRACT METRICS ==========
function Get-DiskspdMetrics {
   param([string]$Output)
   
   # Find first line with "total:" followed by digits (real data, not zeros)
   $TotalLine = ($Output -split "`r`n|`n" | Where-Object { $_ -match "^total:\s+\d+" } | Select-Object -First 1)
   
   if (-not $TotalLine) {
       return @{ IOPS = "N/A"; MBs = "N/A"; Latency = "N/A" }
   }
   
   $Parts = $TotalLine -split '\s*\|\s*'
   
   if ($Parts.Count -ge 6) {
       return @{
           IOPS = $Parts[3]      # I/O per s
           MBs = $Parts[2]       # MiB/s
           Latency = $Parts[4]   # AvgLat
       }
   }
   
   return @{ IOPS = "N/A"; MBs = "N/A"; Latency = "N/A" }
}

# ========== RUN TESTS ==========
foreach ($Drive in $DrivesToTest) {
   $TestFile = "$($Drive.DeviceID)\testfile.dat"
   $DirectIO = if ($Drive.IsSystem) { "" } else { "-h" }
   
   Write-Host "========================================" -ForegroundColor Cyan
   Write-Host "   TESTING: $($Drive.DeviceID) - $($Drive.Model)" -ForegroundColor Cyan
   Write-Host "   Size: $($Drive.SizeGB) GB | Free: $($Drive.FreeGB) GB" -ForegroundColor Cyan
   Write-Host "========================================" -ForegroundColor Cyan
   Write-Host ""
   
   # ========== TEST 1: Random Read 4K ==========
   Write-Host "[1/3] Random Read 4K..." -ForegroundColor Yellow
   $Raw1 = cmd /c "$DiskspdPath -c$TestSize -d$Duration -w0 -r -o8 -t8 -b4k $DirectIO -L $TestFile 2>&1"
   $M1 = Get-DiskspdMetrics ($Raw1 -join "`n")
   Write-Host "   Done. IOPS: $($M1.IOPS)" -ForegroundColor Gray
   Write-Host ""

   # ========== TEST 2: Mixed 70/30 4K ==========
   Write-Host "[2/3] Mixed 70/30 Read/Write 4K..." -ForegroundColor Yellow
   $Raw2 = cmd /c "$DiskspdPath -c$TestSize -d$Duration -w30 -r -o8 -t8 -b4k $DirectIO -L $TestFile 2>&1"
   $M2 = Get-DiskspdMetrics ($Raw2 -join "`n")
   Write-Host "   Done. IOPS: $($M2.IOPS)" -ForegroundColor Gray
   Write-Host ""

   # ========== TEST 3: Sequential Read 1M ==========
   Write-Host "[3/3] Sequential Read 1M..." -ForegroundColor Yellow
   $Raw3 = cmd /c "$DiskspdPath -c$TestSize -d$Duration -w0 -o1 -t1 -b1M $DirectIO -L $TestFile 2>&1"
   $M3 = Get-DiskspdMetrics ($Raw3 -join "`n")
   Write-Host "   Done. Speed: $($M3.MBs) MB/s" -ForegroundColor Gray
   Write-Host ""

   # ========== GENERATE REPORT ==========
   Write-Host "========================================" -ForegroundColor Cyan
   Write-Host "   REPORT: $($Drive.DeviceID) - $($Drive.Model)" -ForegroundColor Cyan
   Write-Host "========================================" -ForegroundColor Cyan
   Write-Host ""
   Write-Host "1. Random Read 4K:" -ForegroundColor Green
   Write-Host "   IOPS: $($M1.IOPS) | Speed: $($M1.MBs) MB/s | Latency: $($M1.Latency) ms"
   Write-Host ""
   Write-Host "2. Mixed 70/30 4K:" -ForegroundColor Green
   Write-Host "   IOPS: $($M2.IOPS) | Speed: $($M2.MBs) MB/s | Latency: $($M2.Latency) ms"
   Write-Host ""
   Write-Host "3. Sequential Read 1M:" -ForegroundColor Green
   Write-Host "   Speed: $($M3.MBs) MB/s | Latency: $($M3.Latency) ms"
   Write-Host ""
   
   # ========== VERDICT ==========
   $IOPS = if ($M1.IOPS -ne "N/A" -and $M1.IOPS -ne "0.00") { [double]$M1.IOPS } else { 0 }
   
   Write-Host "--- VERDICT ---" -ForegroundColor Cyan
   if ($IOPS -gt 50000) {
       Write-Host "NVMe SSD. Excellent performance!" -ForegroundColor Green
   } elseif ($IOPS -gt 5000) {
       Write-Host "SATA SSD. Good performance." -ForegroundColor Green
   } elseif ($IOPS -gt 300) {
       Write-Host "High-performance HDD. Suitable for storage." -ForegroundColor Yellow
   } elseif ($IOPS -gt 0) {
       Write-Host "Standard HDD. Suitable for backups and archives." -ForegroundColor Yellow
   } else {
       Write-Host "Could not determine disk type." -ForegroundColor Gray
   }
   Write-Host ""
   
   # ========== CLEANUP ==========
   Write-Host "Delete test file? (y/n)" -ForegroundColor Yellow
   $Answer = Read-Host
   if ($Answer -eq "y") {
       Remove-Item $TestFile -Force -ErrorAction SilentlyContinue
       Write-Host "File $TestFile deleted." -ForegroundColor Green
   } else {
       Write-Host "File $TestFile kept. Remove manually: del $TestFile" -ForegroundColor Yellow
   }
   Write-Host ""
}

Write-Host "========================================" -ForegroundColor Cyan
Write-Host "   ALL TESTS COMPLETED" -ForegroundColor Cyan
Write-Host "========================================" -ForegroundColor Cyan

Теги