wiki.getshifting.com

--- Sjoerd Hooft's InFormation Technology ---

User Tools

Site Tools


hypervdiskload

Hyper-V Disks Load and Performance

Summary: How to measure Hyper-V 2 disk load and performance.
Date: Around 2020
Refactor: 1 March 2025: Checked links and formatting.

For a project I need how much bandwidth was required considering hoe much data was written to disk (All VMs were to be replicated to a different location). As I soon find out is that hyper-V does not keep this kind of data stored somewhere as vCenter does in a vSphere environment. Since Hyper-V 2 there are a few commands available to see the disk load end measure this. However, I found that the commands are unreliable, and especially in a Virtual Machine Manager environment where you run into name collision problems between VMM and Hyper-V commandlets (note that you sometimes can prefix commands like Hyper-V\get-VM).

The script

# Script Variables
$scriptname = [System.IO.Path]::GetFilenameWithoutExtension($MyInvocation.MyCommand.Path.ToString())
$scriptlocation = Split-Path $myinvocation.mycommand.path
 
# Start transcript for full logging capabilities
start-transcript -path "$scriptlocation\logtranscript.txt"
 
# Mail settings
#$weekdate = Get-Date -uformat %V
#$weekdate = get-date -Format yyyyMMdd-HHmm
$mailserver = "smtpserver"
$toemail = "sjoerd_getshifting.com"
$ccmail = "sjoerd_getshifting.com"
$fromemail = "$scriptname_getshifting.com"
#$monthreport = "$scriptlocation\$weekdate-$scriptname.csv"
 
# Run this script from a server with Virtual Machine Manager installed as well as the RSAT tools
$vmmserver = "vmm.getshifting.local"
Get-SCVMMServer $vmmserver
 
# Because the VMM server has both Hyper-V and VMM commandlets installed, and these commandlets can have the same name (or an alias), use all Hyper-V commands as 'Hyper-V\commandlet'
## For example: Hyper-V\Get-VM
 
Function Send-Email ($subject, $info){
    # Send high prio email without attachment
    if ($priority -eq "high" -and $monthreport -eq $null){
        Send-MailMessage -To $toemail -From $fromemail -cc $ccmail -SmtpServer $mailserver -Subject $subject -Body $info -BodyAsHtml -Priority High
    }
    # Send mail without attachment (some Controls do not need attachments)
    elseif ($monthreport -eq $null){
        Send-MailMessage -To $toemail -From $fromemail -cc $ccmail -SmtpServer $mailserver -Subject $subject -Body $info -BodyAsHtml
    }
    else{
        Send-MailMessage -To $toemail -From $fromemail -cc $ccmail -SmtpServer $mailserver -Subject $subject -Body $info -BodyAsHtml -Attachments "$monthreport"
    }
}
 
Function Show-Menu{
    param (
        [string]$Title = 'Hyper-V Performance'
    )
    #Clear-Host
    Write-Host "================ $Title ================"
 
    Write-Host "1: Press '1' to enable and reset resourcemonitoring in cluster1 (PRD)"
    Write-Host "2: Press '2' to collect disk resourcemonitoring in cluster1 (PRD)"
    Write-Host "3: Press '3' to enable and reset resourcemonitoring in cluster2 (Test)"
    Write-Host "4: Press '4' to collect disk resourcemonitoring in cluster2 (Test)"
    Write-Host " "
    Write-Host "5: Press '5' to disable resourcemonitoring in cluster1 and cluster2"
    Write-Host " "
    Write-Host "The report will be send to $toemail "
    Write-Host "Q: Press 'Q' to quit."
}
 
Function Enable-Metering{
    foreach($node in $nodes) {
    Write-host "Node: $node"
    #Set-VMHost -ComputerName $node -ResourceMeteringSaveInterval 24:00:00
    Set-VMHost -ComputerName $node -ResourceMeteringSaveInterval 5:00:00
    Get-VMHost -ComputerName $node | select ResourceMeteringSaveInterval
    $vms = Hyper-V\Get-VM -ComputerName $node
        foreach ($vm in $vms){
            $name = $vm.name
            write-host "VMname: $name"
            $vm | Enable-VMResourceMetering
            $vm | Reset-VMResourceMetering
        }
    }
}
 
Function Disable-Metering{
    foreach($node in $nodes) {
    Write-host "Node: $node"
    $vms = Hyper-V\Get-VM -ComputerName $node
        foreach ($vm in $vms){
            $name = $vm.name
            write-host "VMname: $name"
            $vm | Disable-VMResourceMetering
        }
    }
}
 
Function Collect-Metering{
    $allvms = @()
 
    foreach($node in $nodes) {
        Write-host "Node: $node"
        $vms = Hyper-V\Get-VM -ComputerName $node
        $measures = Hyper-V\Get-VM -ComputerName $node | Measure-VM | select vmname,meteringduration,AggregatedAverageNormalizedIOPS,AggregatedDiskDataRead,AggregatedDiskDataWritten,AggregatedNormalizedIOCount
        foreach ($vm in $vms){
            $vminfo = "" | select Name,State,MonitoringEnabled,MeteringDuration,AggregatedAverageNormalizedIOPS,AggregatedDiskDataRead,AggregatedDiskDataWritten,AggregatedNormalizedIOCount
            #write-host "VM: $vm"
            #$vmobject = Hyper-V\Get-VM -ComputerName $node | where {$_.Name -like "*$vm*"}
            #write-host "VMobject: $vmobject"
            $name = $vm.name
            write-host "VMname: $name"
            $vminfo.name = $name
            $vminfo.state = $vm.state
            $vminfo.monitoringenabled = $vm.ResourceMeteringEnabled
            $measure = $measures | where {$_.vmname -eq $name}
            #foreach ($measure in $measures)
            $vminfo.meteringduration = $measure.meteringduration
            $vminfo.AggregatedAverageNormalizedIOPS = $measure.AggregatedAverageNormalizedIOPS
            $vminfo.AggregatedDiskDataRead = $measure.AggregatedDiskDataRead
            $vminfo.AggregatedDiskDataWritten = $measure.AggregatedDiskDataWritten
            $vminfo.AggregatedNormalizedIOCount = $measure.AggregatedNormalizedIOCount
            $allvms += $vminfo
        }
    }
    $allvms | export-csv -NoTypeInformation $monthreport
    $subject = $Cluster + " Hyper-V Performance Report"
    $body = "See the attached report"
    Send-Email $subject $body
}
 
# Start menu
do
{
    Show-Menu
    $selection = Read-Host "Please make a selection"
    switch ($selection)
    {
        '1' {
            $cluster = "cluster1.prd.shift.com"
            $nodes = Get-ClusterNode -cluster $cluster
            Enable-Metering
        } '2' {
            $cluster = "cluster1.prd.shift.com"
            $nodes = Get-ClusterNode -cluster $cluster
            $weekdate = get-date -Format yyyyMMdd-HHmm
            $monthreport = "$scriptlocation\$weekdate-$scriptname.csv"
            Collect-Metering
        } '3' {
            $cluster = "cluster2.test.shift.com"
            $nodes = Get-ClusterNode -cluster $cluster
            Enable-Metering
        } '4' {
            $cluster = "ccluster2.test.shift.com"
            $nodes = Get-ClusterNode -cluster $cluster
            $weekdate = get-date -Format yyyyMMdd-HHmm
            $monthreport = "$scriptlocation\$weekdate-$scriptname.csv"
            Collect-Metering
        } '5' {
            $cluster = "cluster1.prd.shift.com"
            $nodes = Get-ClusterNode -cluster $cluster
            Disable-Metering
            $cluster = "cluster2.test.shift.com"
            $nodes = Get-ClusterNode -cluster $cluster
            Disable-Metering
        }
    }
    pause
}
until ($selection -eq 'q')
 
 
# Stop transcript
stop-transcript

Resources

hypervdiskload.txt · Last modified: by 127.0.0.1