23 August 2012

Getting to know which Hyper-V guest is using disk using PowerShell script

Best way to investigate disk usage on hyper-v host is to look at all guests and figure out, which one is exhausting the system. The only way to get those readings is using perfmon (Performance Monitor) Hyper-V specific counters. Simple Task Manager or Resource Monitor doesn’t give that detail.

I got even further and scripted this. First take a look at the script:

$date = Get-Date
"importing AD module"
import-module activedirectory
"Getting computer list from AD"
$servers = Get-ADComputer -LDAPFilter "(operatingsystem=*server*)" | sort name
$servers |  measure
$i=1
write-host "Getting Hyper-V Disk Activity information..."
$info = $servers | foreach {
    $computername = $_.name
    write-host ($i++) $computername
 
    $readcounter = "\\" + $computername + "\Hyper-V Virtual Storage Device(*)\Read Bytes/sec"
    (get-counter -Counter $readcounter).countersamples | foreach {
        $obj = new-object psobject
        $obj | add-member noteproperty Host ($computername)
        $obj | add-member noteproperty Access ("Read")
        $obj | add-member noteproperty VHD ($_.InstanceName)
        $obj | add-member noteproperty MBps ([Math]::Round($_.CookedValue/1024/1024,2))
        $obj
        }
    
    $writecounter = "\\" + $computername + "\Hyper-V Virtual Storage Device(*)\Write Bytes/sec"
    (get-counter -Counter $writecounter).countersamples | foreach {
        $obj = new-object psobject
        $obj | add-member noteproperty Host ($computername)
        $obj | add-member noteproperty Access ("Write")
        $obj | add-member noteproperty VHD ($_.InstanceName)
        $obj | add-member noteproperty MBps ([Math]::Round($_.CookedValue/1024/1024,2))
        $obj
        }
        
    }
    
$filename2 = "c:\serverinfo\HVdiskactivity {0}.{1:d2}.{2:d2} {3:d2}.{4:d2}.csv" -f $date.year,$date.month,$date.day,$date.hour,$date.minute
# $info | Export-Csv -Path $filename2 -encoding utf8
$info2 = $info | where {$_.MBps -ge 1} | sort MBps -Descending
$info3 = $info2 | ConvertTo-Html
$info4 = [string]$info3
 
if($info2){
Send-MailMessage -SmtpServer smtp.domain.com -To rauno.magi@domain.com -From rauno.magi@domain.com -Subject "Hyper-v guests having greatest VHD activity" -Body $info4 -BodyAsHtml
}

What does this script do? Let’s look at step by step:



  1. First it import’s Active Directory module and uses it to get the list of all servers, which will be recorded to variable $servers

  2. Then it uses this list of servers to query performance information on each of them using get-counter cmdlet. It would be nice to reduce the list to hyper-v server’s only, but this is cosmetical and performance issue and doesn’t affect the functionality

  3. Nice thing is creating a new empty object and populate all properties/rows with data got from new-object cmdlet.

  4. All the information gathered will be stored into $info variable, which can be optionally saved to a csv file. This command is commented out at the moment

  5. Filtered and sorted list (disk activity more than 1MB per second, biggest numbers on top) will be sent as a e-mail message attachment in the message body.

No comments:

Post a Comment