Save to My DOJO
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.
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
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
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.
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.
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!
Not a DOJO Member yet?
Join thousands of other IT pros and receive a weekly roundup email with the latest content & updates!