Lately I have been trying to determine which of my VMs have oversized, or allocated more resources than they need. I know that there are programs, plugins etc which do this, however I wanted to take a shot a just a quick script that could give some direction. Although if anyone has a program/appliance they like(maybe free) for right-sizing VMs let me know.

So without further adieu here is my quick little script.

Param($days, $ref)

$date=get-date -hour 0 -minute 0 -second 0
$vms= get-vm | Where-Object {$_.powerstate -like "*on"} | sort-object

$vms | Where-object {((Get-Stat -Entity (Get-VM $_) -Stat mem.usage.average -Start $date.AddDays(-"$days")`
 -Finish $date.AddDays(-1) | where-object {$_.Instance -eq ""}).value|measure-object -average).average -lt $ref}

The script takes all of the VMs that are powered on and sorts them.
From here it looks at the average usage(a percent) of a VMs memory over the last $days. $days being a number. It then compares that average with the reference number provided($ref), if the overall average over $days is less than $ref, the VM object is returned.

An Example:

./averagemem.ps1 -days 20 -ref 25

Assuming you named the script “averagemem.ps1” like I did, the script will return all the VMs who in the last 20 days have had an average memory usage of under 25%. Pretty neat stuff!

This is in no way an end all be all of whether a VM is right-sized on memory or not, but if you have a large environment it can definitely narrow down how many VMs you should be examining.

I hope this Help!



Matthew Andrews · July 30, 2012 at 1:18 pm

You may want to mention that this script depends on some of the syntax changes in powershell 3.

    C-Rad · July 30, 2012 at 2:24 pm

    I don’t think it does, which part are you seeing that I am not?

Travis Quinnelly · August 2, 2012 at 2:00 pm

Love this script. Perhaps it will help me in convincing the boss to allow me to remove some memory from over-allocated VMs.

    C-Rad · August 2, 2012 at 2:20 pm

    True Story! I hate when someone comes in and says “Hey this VM need 4 CPUs added to it!”…. To which I reply, “Say What Now?!”

Christoffer Zettermark · August 7, 2012 at 3:13 am

You could save some time by removing “Get-VM” from the Get-Stat statement:

Get-Stat -Entity $_ …..

Should work just as fine.

Jim Nickel · February 7, 2014 at 4:24 pm

How would you change this to display the percentage of average memory used as well?

So….instead of just showing which VMs fall under the reference average, you could display the percentage too.


    C-Rad · February 9, 2014 at 6:25 pm

    Try this..I took out all the variables. I know it isn’t exactly what you are looking for, but hopefully it will help

    ((Get-Stat -Entity (Get-VM “VM Name“) -Stat mem.usage.average -Start (get-date).AddDays(-“7”) -Finish (get-date).AddDays(-1) | where-object {$_.Instance -eq “”}).value|measure-object -average).average

Leave a Reply