Discover Memory Overallocations

With the vSphere 5 licensing buzz from the past days and the incredibel number of hits on my Query vRAM post, I considered that a script to help you discover your memory overallocations might be useful.

The script uses the metric mem.usage.average to find out what amount of it’s allocated memory a guest is actually using. The script produces a report that will help you to determine which guests would be good candidates to lower their memory allocation.

Annotations

Line 12-13: The function collects all the guests for which you want a report.

Line 15-36: The script retrieves the statistical data, taking into account the selected time interval.

Line 38: The statistical data is organised in groups based on the EntityId.

Line 39-50: A guest that was offline during the time interval will have no statistical data.

Line 51-58: The result is placed in the pipeline.

Sample usage

The use of the function is rather straightforward.

By default the function will report on all guests in your vCenter. With the LocationName parameter you specify a datacenter, a cluster, a resourcepool, a folder and even an ESX(i) host. The function will then return the information for all guests under that location.

I also decided to provide some switches to let you select the timeframe the function should report on.

Realtime

In this mode, which is also the deault mode, you get the most recent value for the mem.usage.average metric.

You call the function like this

PowerShell

1

Get-VMMemUse

or like this

PowerShell

1

Get-VMMemUse-Realtime

Both of these will report on all the guests in your vCenter.

If you want to limit the guests, you use the LocationName parameter.

For example, to only report on the guests in a datacenter called MyDC, you would do.

PowerShell

1

Get-VMMemUse-LocationNameMyDC

Day

If you want to report on the average memory usage of the past day, you do

PowerShell

1

Get-VMMemUse-LocationNameMyDC-Day

Week

Similarly, if you want a report over the past week, you do

PowerShell

1

Get-VMMemUse-LocationNameMyDC-Week

Month

And finally, to get the report calculated over a month’s worth of data you do

PowerShell

1

Get-VMMemUse-LocationNameMyDC-Month

Output

By default the report will be displayed on the console. It looks something like this.

But you can also redirect the output to, for example a CSV file.

PowerShell

1

Get-VMMemUse|Export-Csv"C:\report.csv"-NoTypeInformation-UseCulture

Which shows a similar result but of course in a CSV file.

From this type of report it should be obvious for which guest lowering the memory allocation would be an option to consider.

Hi Sanyam,
Can you be more specific, what kind of shared folder are you talking about ?
Is that a Samba or NFS share for example, and do you have any access to the sharing host ?
And please also defined what exactly you mean with “maximum allocated size”.

steve

steve

Owen

November 25, 2013 at 11:58

I’m having difficulty running this script, which is a shame because it is exactly what i’m looking for!

Calling “Get-Inventory -Name MyVMName | Get-VM” returns:

Get-VM : The input object cannot be bound to any parameters for the command eit
her because the command does not take pipeline input or the input and its prope
rties do not match any of the parameters that take pipeline input.
At line:1 char:49

If I append Get-VMMemUse to the end of the script, then call the script using:
./memusescrupt.ps1 -LocationName MyDC -Day
It will run for hours and hours (we have 1000s) of VMs. Even specifying a folder or resourcepool with only a handful of VMs takes too long, which leads me to think that it is still running it against the entire DC.

Hi Owen,
When you just do ‘Get-Inventory -Name MyVMName’ it will return a VirtualMachine object. That is sufficient, no need to do a Get-VM after that.
The error message comes from the fact that the Get-VM cmdlet doesn’t have any parameter that accepts a VirtualMachine through the pipeline.

Did you define the parameters in the .ps1 file ?
In fact the .ps1 file should look something like this
param($location)

Owen

June 25, 2012 at 12:43

Great script LucD – thanks!
Though it seems that no matter which vCenter and LocationName I specify, it reports back on every VM in the datacenter listing. Also need to butcher the script to force it to run for a specific timeframe, IE the -Month or -Week arguments don’t seem to work. Any ideas?

Question: when I look at the MemAvgUsedGB and MemAvgUsedPerc results then I can’t help thinking that the numbers are so low.

For example: For a certain VM the MemAvgUsedGB is 0,4 and the configured memory is 2GB. When I lower the amount of memory for this VM to 1,5 GB the guest OS starts to swap and performance drops. This scenario can be reproduced with other VM’s.

and of course adding $peakuse to the new object. It produces some output but it seem to fail with identifying the maximum value. I cross checked one machine, in the csv file it reports 9.66 % PeakUsage. But when i look in vCenter 1 month graph peak is 22%

Eugene

Ian

July 21, 2011 at 16:11

Hi,

Great script but just on question. How do I run it? I am connected to vCenter. I have copied the script to a text file and saved it as a .ps1 and bat. When I run Get-VMMemUse I get an error “The term ‘Get-VMMemUse’ is not recognized as the name of a cmdlet, function, script file.