Monitoring Storage disk queue’s and IO with PowerShell

/wp-content/uploads/2011/03/windows_powershell_icon.png?w=58&h=58&h=58Here’s one that used to bother me alot. The problem usually went as follows:

“Your XenApp servers have very high disk queue’s and IO”

“What’s causing it?”

“dunno…”

With Server 2008, the task manager’s resource monitor feature will help you find these items. But in server 2003 this was a perilous task. The specific details for disk io per process are stored in performance monitor under each specific process running. Trying to analyse each process was a massive pain, but powershell can do some very clever work to helpĀ alleviateĀ this!

I wrote two quick functions which act similar to “top” in linux for giving an on screen view, updating at interval of what exactly is creating IO activity. These two functions are:

get-IODataBytes:

storageio

Get-IODataOperations

storageioops

The code for these functions are below:

[sourcecode language=”powershell”]
function get-iodatabytes{
$result=(get-counter -counter "Process(*)IO Data Bytes/sec" -ea 0).countersamples | ? {$_.cookedvalue -gt 0} | select instancename,@{Name="SessionID";Expression={if ($_.path.contains("#")){($_.path.split("#)"))[1]}else{"0"}}},@{Name="IO Data Bytes/sec";Expression={[math]::Round($_.cookedvalue,0)}},@{Name="IO Data KBytes/sec";Expression={[math]::Round($_.cookedvalue / 1024,0)}} | sort -Descending "IO Data Bytes/sec" | ft
$currentqueue=(((get-counter -counter "PhysicalDisk(0 C:)Current Disk Queue Length" -ea 0).countersamples) | select cookedvalue).cookedvalue
clear
write-warning "Hit [CTRL] + [C] to exit live capture"
write-host "Current Disk queue: $currentqueue"
return $Result
}

FUnction get-IODataOperations {
$result=(get-counter -counter "Process(*)IO Data Operations/sec" -ea 0).countersamples | ? {$_.cookedvalue -gt 0} | select instancename,@{Name="SessionID";Expression={if ($_.path.contains("#")){($_.path.split("#)"))[1]}else{"0"}}},@{Name="IO Data Operations/sec";Expression={[math]::Round($_.cookedvalue,0)}} | sort -Descending "IO Data Operations/sec" | ft
$currentqueue=(((get-counter -counter "PhysicalDisk(0 C:)Current Disk Queue Length" -ea 0).countersamples) | select cookedvalue).cookedvalue
clear
write-warning "Hit [CTRL] + [C] to exit live capture"
write-host "Current Disk queue: $currentqueue"
return $Result
}

[/sourcecode]

if you wish to loop one of these functions, simply use the following code:

[sourcecode language=”powershell”]
while ($true){
get-iodataoperations
start-sleep 1
}
[/sourcecode]

Related Posts

New Module: Creating an RDP file password with Pow... Here's something that is surprisingly tricky to automate in this day and age. Creating a password and storing it in an RDP file. I'm not here to debat...
Dealing with multi numbered versions in powershell... So here's a quick little blog about something i discovered in powershell while googling today. Lots of vendors like to use version numbers includin...
New Free Tool: Citrix Director Notification Servic... Citrix Director for XenApp and XenDesktop can be a great utility for information about your Application / Desktop virtualisation environment. In Direc...

4 Comments About “Monitoring Storage disk queue’s and IO with PowerShell

      1. J

        Thanks for the reply….

        Tired it and when running the PS script it doesn’t return any results nor any errors.

        Windows PowerShell
        Copyright (C) 2012 Microsoft Corporation. All rights reserved.

        PS C:Windowssystem32> cd
        PS C:> cd temp
        PS C:temp> .diskio.ps1
        PS C:temp>

        function get-iodatabytes{
        $result=(get-counter -counter “Process(*)IO Data Bytes/sec” -ea 0).countersamples | ? {$_.cookedvalue -gt 0} | select instancename,@{Name=”SessionID”;Expression={if ($_.path.contains(“#”)){($_.path.split(“#)”))[1]}else{“0″}}},@{Name=”IO Data Bytes/sec”;Expression={[math]::Round($_.cookedvalue,0)}},@{Name=”IO Data KBytes/sec”;Expression={[math]::Round($_.cookedvalue / 1024,0)}} | sort -Descending “IO Data Bytes/sec” | ft
        $currentqueue=(((get-counter -counter “PhysicalDisk(0 C:)Current Disk Queue Length” -ea 0).countersamples) | select cookedvalue).cookedvalue
        clear
        write-warning “Hit [CTRL] + [C] to exit live capture”
        write-host “Current Disk queue: $currentqueue”
        return $Result
        }

        FUnction get-IODataOperations {
        $result=(get-counter -counter “Process(*)IO Data Operations/sec” -ea 0).countersamples | ? {$_.cookedvalue -gt 0} | select instancename,@{Name=”SessionID”;Expression={if ($_.path.contains(“#”)){($_.path.split(“#)”))[1]}else{“0″}}},@{Name=”IO Data Operations/sec”;Expression={[math]::Round($_.cookedvalue,0)}} | sort -Descending “IO Data Operations/sec” | ft
        $currentqueue=(((get-counter -counter “PhysicalDisk(0 C:)Current Disk Queue Length” -ea 0).countersamples) | select cookedvalue).cookedvalue
        clear
        write-warning “Hit [CTRL] + [C] to exit live capture”
        write-host “Current Disk queue: $currentqueue”
        return $Result
        }

        Reply
  1. Fake

    This was awesome and exactly what I was looking for.

    Note that in the counter parameter there is a typo: “Process(*)IO Data Bytes/sec” needs to be “Process(*)\IO Data Bytes/sec”

    Reply

Leave a Reply