My Daily Hyper-V Status Email–Part 5 of 5

My Daily Hyper-V Status Email–Part 5 of 5

  • Comments 2

After displaying event logs, virtual machine health and storage health – the last thing that is included in my daily status email is usage data.

For this I take advantage of the built in metrics functionality that is part of Hyper-V.


Looking at this report – I realize I should probably filter our replicated virtual machines (those are all the entries with zero data).  I guess I will have to fix that at some point in the future.  Regardless – here is the code that I use today:

# VM Metrics
$message = $message + "<style>TH{background-color:blue}TR{background-color:$($tableColor)}</style>"
$message = $message + "<B>Virtual Machine Utilization Report</B> <br> <br> "
$message = $message +  "CPU utilization data: <br>" + ($metricsData | `
                                                           select-object @{Expression={$_.VMName};Label="Virtual Machine"}, `
                                                                         @{Expression={$_.AvgCPU};Label="Average CPU Utilization (MHz)"} `
                                                                         | ConvertTo-HTML -Fragment) `
                                                                         +" <br>"
$message = $message + "Memory utilization data: <br>" + ($metricsData | `
                                                             select-object @{Expression={$_.VMName};Label="Virtual Machine"}, `
                                                                           @{Expression={$_.AvgRAM};Label="Average Memory (MB)"}, `
                                                                           @{Expression={$_.MinRAM};Label="Minimum Memory (MB)"}, `
                                                                           @{Expression={$_.MaxRAM};Label="Maximum Memory (MB)"} `
                                                                           | ConvertTo-HTML -Fragment) `
                                                                           +" <br>"
$message = $message + "Network utilization data: <br>" + ($metricsData | `
                                                             select-object @{Expression={$_.VMName};Label="Virtual Machine"}, `
                                                                           @{Expression={"{0:N2}" -f (($_.NetworkMeteredTrafficReport | where-object {($_.Direction -eq "Inbound")}`
                                                                              | measure-object TotalTraffic -sum).sum / 1024)};Label="Inbound Network Traffic (GB)"}, `
                                                                           @{Expression={"{0:N2}" -f (($_.NetworkMeteredTrafficReport | where-object {($_.Direction -eq "Outbound")} `
                                                                              | measure-object TotalTraffic -sum).sum / 1024)};Label="Outbound Network Traffic (GB)"} `
                                                                           | ConvertTo-HTML -Fragment) `
                                                                           +" <br>"
$message = $message + "Disk utilization data: <br>" + ($metricsData | `
                                                           select-object @{Expression={$_.VMName};Label="Virtual Machine"}, `
                                                                         @{Expression={"{0:N2}" -f ($_.TotalDisk / 1024)};Label="Disk Space Used (GB)"} `
                                                                         | ConvertTo-HTML -Fragment) `
                                                                         +" <br>"
$message = $message + "Metering Duration data: <br>" + ($metricsData | `
                                                            select-object @{Expression={$_.VMName};Label="Virtual Machine"}, `
                                                                          @{Expression={$_.MeteringDuration};Label="Metering data duration"} `
                                                                          | ConvertTo-HTML -Fragment) `
                                                                          +" <br>"
# Reset metrics
get-vm | Reset-VMResourceMetering
get-vm | Enable-VMResourceMetering

Notes about this code:

  • $metricsData contains the output of “get-vm | measure-vm” (this is mentioned in my first post in this series).  The reason why I do this is because measure-vm is a heavy command (it uses a chunk of CPU and disk) so I only want to run it once.
  • Once again - I use raw HTML to set the color of the table headers. 
  • Again - I run the output of these commands through Select-Object with the use of the “Expression” option to set column labels appropriately.
  • Again - I use ConvertTo-HTML –Fragment to get a nice HTML table outputted.
  • At the end of this code I reset the counters, and enable metering on all virtual machines.  I do this so that if I add any new virtual machines, they get picked up automatically.


Leave a Comment
  • Please add 2 and 5 and type the answer here:
  • Post
  • Thank you dear Ben,

    I have a quick question please, I noticed that the "Metering Duration Data counters" are empty all the time, however the Resource Metering is enabled. What is the reason?

    Best regards,

  • Ben,

    First of all, thank you for all the great information that you provide... I'm truly grateful.

    Upon setting up this status email script to run daily, I noticed that SR-IOV would stop working right after the script was run. At first, I didn't make the connection to this script and I posted on the TechNet forums to see if anyone had any ideas why it would stop working after working for about a year on that box successfully (

    Following the suggestions provide by those responding to that post, I was able to get SR-IOV working again by shutting down the VMs, removing the NIC, adding a new NIC back, manually configuring the MAC address and checking the option for SR-IOV, and then restarting each of the VMs. But, after getting SR-IOV working successfully again, it would always stop working right after this script executed. After disabling the status script, SR-IOV has been working for days without fail.

    I'm wondering if anyone else has experienced this issue and wondering why examining Hyper-V state through PowerShell (as this script does) would cause SR-IOV to stop working.




Page 1 of 1 (2 items)