Powershell : Disk Performance


This was just a very quick script to tell me the top 10 processes utilizing the disk, it was more of a quick requirement I needed so I thought I’d put it on my blog just in case it helps anyone else.
Script : DiskMonitor.ps1

# Define a loop to monitor disk I/O continuously
while ($true) {
    try {
        # Get the current time for logging
        $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
        
        # Get disk I/O per process
        Write-Host "Querying disk I/O statistics at $timestamp..."
        $diskStats = Get-Counter -Counter "\Process(*)\IO Data Bytes/sec" `
                                -SampleInterval 5 -MaxSamples 1 -ErrorAction Stop
        
        # Check if the data returned is valid
        if ($diskStats.CounterSamples.Count -eq 0) {
            Write-Host "No data returned from performance counters."
            Start-Sleep -Seconds 10
            continue
        }
        
        # Process valid data
        $diskData = $diskStats.CounterSamples | Where-Object {
            $_.InstanceName -ne "_Total" -and $_.InstanceName -ne "Idle"
        } | Select-Object InstanceName, CookedValue | Sort-Object CookedValue -Descending
        
        if ($diskData.Count -eq 0) {
            Write-Host "No valid disk I/O data found."
            Start-Sleep -Seconds 10
            continue
        }
        
        # Get the top 10 processes using the most disk I/O
        $topProcesses = $diskData | Select-Object -First 10

        # Optional: Calculate total disk I/O
        $totalDiskIO = $diskData | Measure-Object -Property CookedValue -Sum
        $totalDiskIOValue = [math]::Round($totalDiskIO.Sum / 1KB, 2) # Convert to KB
        
        # Output the results
        Write-Host "Timestamp: $timestamp"
        Write-Host "Total Disk I/O: ${totalDiskIOValue} KB/sec"
        Write-Host "Top 10 Processes by Disk I/O (Bytes/sec):"
        
        # Format results into a table
        $formattedResults = $topProcesses | ForEach-Object {
            [PSCustomObject]@{
                ProcessName = $_.InstanceName
                DiskIOBytesPerSec = [math]::Round($_.CookedValue / 1KB, 2) # Convert to KB
            }
        }
        $formattedResults | Format-Table -AutoSize -Property ProcessName, DiskIOBytesPerSec

        Write-Host "-------------------------------------"
    }
    catch {
        Write-Host "An error occurred: $_" -ForegroundColor Red
    }

    # Wait before the next iteration
    Start-Sleep -Seconds 10
}

When this is run you get an output of the top processes using the disk as you can see below:


Previous Post Next Post

نموذج الاتصال