Introduction to Hyper-V Performance Monitoring with PowerShell

Save to My DOJO

Introduction to Hyper-V Performance Monitoring with PowerShell

Virtual machines can quickly lose speed and efficiency unless managed properly. Using PowerShell, you can monitor Hyper-V performance so you can keep on top of your performance levels and ensure your Hyper-V VMs are running optimally at all times.

In my last article, I demonstrated how to work with performance counters but from a WMI (Windows Management Instrumentation) perspective, using the corresponding Win32 classes with Get-CimInstance. Today I want to circle back to using Get-Counter to retrieve performance counter information but as part of a toolmaking process. I expect that when you are looking at performance counters, you do so on a very granular level. That is, you are only interested in data from a specific counter. I am too. In fact, I want to develop some tooling around a performance counter so that I can quickly get the information I need.

Getting Started

I’m using Hyper-V running on my Windows 10 desktop, but there’s no reason you can’t substitute your own Hyper-V host.

#define a variable for the Hyper-V Host
$computer = $env:COMPUTERNAME

You should be able to test my code by setting your own value for $Computer.

Introduction to Hyper-V Performance Counters

Of all the Hyper-V performance counters, the one that interests me is part of the Hyper-V Dynamic Memory VM set.

Dynamic Memory Counters

I am especially interested in the pressure related counters. This should give me an indication if the virtual machine is running low on memory. You sometimes see this in the Hyper-V management console when you look at the memory tab for a given virtual machine. Sometimes you’ll see a Low status. I want to be able to monitor these pressure levels from PowerShell.

After a little research, I found the corresponding WMI class.

Get-CimInstance -class Win32_PerfFormattedData_BalancerStats_HyperVDynamicMemoryVM -ComputerName $computer |
Select Name,*Memory*,*Pressure | Out-GridView

Memory Counters via WMI and CIM

As you can see SRV2 is running a bit high. One of the benefits of using a WMI class instead of Get-Counter is that I can create a filter.

Get-CimInstance -class Win32_PerfFormattedData_BalancerStats_HyperVDynamicMemoryVM -ComputerName $computer -filter "CurrentPressure >=80" |
Select Name,*Memory*,*Pressure

High Memory Pressure VM

Building Basic PowerShell Tools With What We’ve Done So Far

One tool I could create would be to turn this one line command into a function, perhaps adding the Hyper-V host as a parameter. I could set the function to run in a PowerShell scheduled job.

Another option would be to register a WMI event subscription. This is an advanced topic that we don’t have room to cover in great detail. But here is some sample code.

$computername = $env:COMPUTERNAME
$query = "Select * from __InstanceModificationEvent within 30 where TargetInstance ISA 'Win32_PerfFormattedData_BalancerStats_HyperVDynamicMemoryVM' AND TargetInstance.CurrentPressure >=80"
$action = {
    $properties = @(@{Name = "Time";Expression = {$event.TimeGenerated}},'Name','AddedMemory','AveragePressure',
    'CurrentPressure','GuestVisiblePhysicalMemory','MaximumPressure','MemoryAddOperations',
    'MemoryRemoveOperations','MinimumPressure','PhysicalMemory','RemovedMemory',
    'SmartPagingWorkingSetSize')
    $event.SourceEventArgs.NewEvent.TargetInstance | select-Object -property $properties |
    Export-CSV C:workmempressure.csv -Append
}

$params = @{
Query = $Query
ComputerName = $Comptername 
Action = $action
MessageData = "VM Pressure Alert"
SourceIdentifier = "HVPressureAlert"
}

Register-CimIndicationEvent @params

The code is checking every 30 seconds (within 30) for instances of the performance counter where the current pressure value is greater or equal to 80. I am registering the event subscription on my computer.  As long as my PowerShell session is open, any time a VM goes above 80 for Current Pressure, information is logged to a CSV file.

When using an Action scriptblock, you won’t see when the event is raised with Get-Event. The only way I can tell is by looking at the CSV file.

image

To manually stop watching, simply unregister the event.

Get-EventSubscriber -SourceIdentifier HVPressureAlert | Unregister-Event

Using this kind of event subscription has a number of other applications when it comes to managing Hyper-V. I expect I’ll revisit this topic again.

But there’s one more technique I want to share before we wrap up for today.

Usually, I am a big believer in taking advantage of PowerShell objects in the pipeline. Using Write-Host is generally frowned upon. But there are always exceptions and here is one of them.  I want a quick way to tell if a virtual machine is under pressure. Color coding will certainly catch my eye.  Instead of writing objects to the pipeline, I’ll write a string of information to the console. But I will color code it depending on the value of CurrentPressure. You will likely want to set your own thresholds. I wanted settings so that I’d have something good to display.

$computer = $env:COMPUTERNAME
$data = Get-CimInstance -class Win32_PerfFormattedData_BalancerStats_HyperVDynamicMemoryVM -ComputerName $computer 
#get the length of the longest computername
$pad = ($data.name | Sort-Object | Select-Object -Last 1).length
#display results
$header = @"

Hyper-V Dynamic Memory Pressure
Host: $($computer.toUpper())
===============================
"@
Write-Host $header -ForegroundColor Cyan
foreach ($item in $data) {
  if ($item.CurrentPressure -ge 80) {
    $fg = "red"
  }
  elseif ($item.CurrentPressure -ge 50) {
    $fg = "yellow"
  }
  else {
    $fg = "White"
  }
 $line = "{0} [{1}MB] Avg: {2} Current: {3}" -f $item.Name.padright($pad),$item.PhysicalMemory,$item.AveragePressure,$item.CurrentPressure
 Write-host $line -ForegroundColor $fg
}

It wouldn’t take much to turn this into a function and create a reusable tool.

Colorized Performance Counters

I have at least one other performance monitoring tool technique I want to share with you but I think I’ve given you plenty to try out for today so I’ll cover that in my next article.

Wrap-Up

Have you built any custom tools for your Hyper-V environment? Do you find these types of tools helpful? Would you like us to do more? Let us know in the comments section below!

Thanks for reading!

Altaro Hyper-V Backup
Share this post

Not a DOJO Member yet?

Join thousands of other IT pros and receive a weekly roundup email with the latest content & updates!

Leave a comment or ask a question

Your email address will not be published. Required fields are marked *

Your email address will not be published.

Notify me of follow-up replies via email

Yes, I would like to receive new blog posts by email

What is the color of grass?

Please note: If you’re not already a member on the Dojo Forums you will create a new account and receive an activation email.