Hyper-v 2012 introduced a set of PowerShell cmdlet that allow you to measure VM resource consumption: CPU, memory, network, and storage. Measure data is stored inside the VM, so data move with the VM. The main purpose of VM resource metering is not to monitor VM host, but to provide information on resources (Cpu, Network, Memory, …) for reporting and billing, for or to balance VM in regards of resource capacity. By default, Hyper-v collect data every one hour. It can be changed only at the host level. You can use value between 1 hour and 24 hours.

/// PS>set-vmhost –computername HyperVHostName -ResourceMeteringSaveInterval 24:00:00 ///

If you try to use less than one hour, PowerShell will not throw an error, instead the interval will be set to one hour. Each host in your environment should be set with the same interval. Remember Metering data are store within the VM. Data will move with the VM.

/// PS>set-vmhost –computername host01,host02,…,host03 -ResourceMeteringSaveInterval 24:00:00 ///

Now we must enable metering for each VM, again metering data are stored within the VM. We don’t want to re-enable each VM only the new one.

/// PS> get-vm -computername host01,host02,…,host03 | ? ResourceMeteringEnabled -eq $false | Enable-VMResourceMetering ///

Now we can start collecting data.

/// PS>get-vm | Measure-VM ///


AvgCpu Measure the average CPU usage in Mhz per hour. Why in Mhz and not a percent, because VM can move and they can move between host with different CPU clock speeds. Metering data are stored in the VM so a 10 % CPU usage do not reflect the situation if the VM move from a 2.5 Ghz Cpu server to a 2 Ghz CPU server percent make no sense.

Ram We have 3 measures, Average, Maximum and Minimum memory used during the interval. If you don’t use dynamic memory, the 3 values are the same. TotalDisk is the disk allocation, it includes all snapshot. When using dynamic disk, it reports not the disk space used but the final disk size.

Network External traffic is reported in MB, only external traffics are reported by default. The system uses an ACL list to measure traffic from and to


/// PS>get-vm | Measure-VM | fl ///

You will get more data

Since Windows 2012 R2 you can get some new metrics. AggregatedAverageNormalizedIOPS. This is an average of IOPS during 20s, not the actual measure. AggregatedAverageLatency This the cumulated Latency during a 20 s sample. AggregatedDiskDataRead and AggregatedDiskDataWritten The total data read of written during the metering duration In windows 2016 only AggregatedNormalizedIOCount

The total IO of written during the metering duration

Note that you also have a detailed network and hard drive report

Now that we have all the data needed for billing and reporting how to use it. If you only have a single Hyper-v Server with few Vm you can simply use get-vm | Measure-VM | fl and phone the billing department. But if you only have Hyper-v host there are some chance that you don’t have a billing department. You could use ConvertTo-Json, it work well if you use it with only one Metering object :

/// PS> measure-vm -Name xRPVM | ConvertTo-Json ///

But if you use more than one report in your object, you will not have the NetworkMeteredTrafficReport or the HardDiskMetrics. Instead you will have this : "Microsoft.HyperV.PowerShell.VMNetworkAdapterPortAclMeteringReport",

You can find in my github a sample to convert data in a more readable format