Hyper-V Host Memory Utilization with PowerShell

Posted on by Jeff Hicks in Hyper-V, and PowerShell

Several weeks ago, I posted a PowerShell script on my blog that uses commands in the Hyper-V module to report on memory utilization per virtual machine. I rely heavily on virtualization to provide a complete domain environment since I work at home. At present, my workload is spread between laptop running 8GB of RAM and a Gigabyte Brix with 16GB of RAM. I’m in the process of planning for something new. But in the meantime, memory utilization, especially from the Hyper-V host perspective is important to me. So I thought I’d share with you some PowerShell-related suggestions that should give you a good idea of how much memory is being used and what virtual machine is using it.

I’m going to be querying my Hyper-V server from my desktop.


The first step I can take is to query WMI for the Win32_OperatingSystem. I’m using Get-CimInstance as I am trying to wean myself off of Get-WmiObject.


I’ve selected a few memory related properties.

Memory properties from the Win32_OperatingSystem class (Image Credit: Jeff Hicks)
Memory properties from the Win32_OperatingSystem class (Image Credit: Jeff Hicks)

The memory values are in KB. If I divide the number by 1KB that will give me the value in MB. If I divide by 1MB, I’ll get the value in GB. Here’s a more complete one-line command that also calculates utilization percentages.


A formatted display of memory properties (Image Credit: Jeff Hicks)
A formatted display of memory properties (Image Credit: Jeff Hicks)

As you can see, memory is getting pretty tight. What virtual machines are eating this memory up? To figure that out, I need to get all the currently running VMs.


How much memory is currently assigned?


Total assigned virtual machine memory (Image Credit: Jeff Hicks)
Total assigned virtual machine memory (Image Credit: Jeff Hicks)

But probably more important is how much memory is actually being demanded?

Total virtual machine memory demanded (Image Credit: Jeff Hicks)
Total virtual machine memory demanded (Image Credit: Jeff Hicks)

There is also a maximum memory, which would be a worst case scenario. Here’s a one-line approach to getting the value.


Potential maximum VM memory (Image Credit: Jeff Hicks)
Potential maximum VM memory (Image Credit: Jeff Hicks)

If all the current running VMs needed to use their maximum memory settings, they would need 23GB. That’s a problem because the server only has 16! Hopefully it won’t come to that. With this, I can create a custom object to display total virtual machine memory utilization.


A VM memory summary (Image Credit: Jeff Hicks)
A VM memory summary (Image Credit: Jeff Hicks)

Notice I’m not simply writing text to the screen I am using an object. This makes it much easier if I had multiple hosts to manage, or if I wanted to export to a CSV or something.

I can take this a step further and look at each running VM. Since I can get each machine’s assigned and demand memory, I can divide those values by the host’s available memory and calculate what percentage each VM is consuming.


I saved the results to a variable, so I could do different things with it like this:


VM utilization of host memory (Image Credit: Jeff Hicks)
VM utilization of host memory (Image Credit: Jeff Hicks)

Looks like my SQL Server needs some attention, or I could shut a few things down to free up resources.

In any event, I’ve given you several commands you could run to get a handle on memory utilization on the Hyper-V host. But personally, I’d prefer everything in one place. So I wrote a function that combines everything I’ve covered.


Now, I can get everything I need with a single command.


Getting Hyper-V host memory status (Image Credit: Jeff Hicks)
Getting Hyper-V host memory status (Image Credit: Jeff Hicks)

I modified the property names, as I thought they were getting a bit long for my tastes. The memory values are in GB. Details for each running virtual machine are stored in the VMs property. Because I used the common parameter Out-Variable, I can easily get that information without having to re-run the command.

Viewing VM memory details (Image Credit: Jeff Hicks)
Viewing VM memory details (Image Credit: Jeff Hicks)

Because everything is an object I can slice and dice the data anyway, I need or use any other PowerShell cmdlet. I hope you’ll let me know what you think. Now if you’ll excuse me, I think I have some virtual machines that need some attention.

BECOME A PETRI MEMBER:

Don't have a login but want to join the conversation? Sign up for a Petri Account

Register