Skip to content
Menu
The Lonely Administrator
  • PowerShell Tips & Tricks
  • Books & Training
  • Essential PowerShell Learning Resources
  • Privacy Policy
  • About Me
The Lonely Administrator

Creating a Hyper-V VM Memory Report

Posted on July 20, 2015July 20, 2015

I use Hyper-V to run my lab environment. Since I work at home I don't have access to a "real" production network so I have to make do with a virtualized environment. Given budgetary constraints I also don't have a lot of high end hardware with endless amount of RAM and storage. So I often run my virtual machines with a bare minimum of memory. Most of the time this isn't a problem. Still, there are times when I need to quickly see how much memory I'm using up. I can use either the Get-VMMemory or Get-VM cmdlet.

Manage and Report Active Directory, Exchange and Microsoft 365 with
ManageEngine ADManager Plus - Download Free Trial

Exclusive offer on ADManager Plus for US and UK regions. Claim now!

The latter cmdlet includes a bit more detail.

All of the values are in bytes which I know I could convert to MB with a custom hashtable. But I don't want to do that all the time so I created a command to get detailed virtual machine memory.

#requires -version 4.0
#requires -module Hyper-V

Function Get-VMMemoryReport {
<#
.Synopsis
Get a VM memory report.
.Description
This command gets memory settings for a given Hyper-V virtual machine. All memory values are in MB. The Utilization value is the percentage of assigned memory is use or in demand.

The command requires the Hyper-V module and must be run in an elevated PowerShell session.
.Parameter VMName
The name of the virtual machine or a Hyper-V virtual machine object. This parameter has an alias of "Name." 
.Parameter VM
A Hyper-V virtual machine object. See examples.
.Parameter Low
Filter out virtual machines without memory issues. Only get virtual machines with a Low memory status.
.Parameter Computername
The name of the Hyper-V server to query. The default is the local host. The parameter has an alias of CN.
.Example
PS C:\> Get-VMMemoryReport chi-core01 -ComputerName chi-hvr2 

Computername : CHI-HVR2
Name         : CHI-CORE01
Status       : Low
Dynamic      : True
Assigned     : 514
Demand       : 472
Utilization  : 91.83
Startup      : 512
Minimum      : 512
Maximum      : 1024
Buffer       : 20
Priority     : 50


Get a memory report for a single virtual machine.
.Example
PS C:\> Get-VM -computer chi-hvr2 | where {$_.state -eq 'running'} | Get-VMMemoryReport | Sort Status,Name | Out-Gridview -title "Memory Report"

Display a memory report for all running VMs using Out-Gridview.
.Example
PS C:\> get-vmmemoryreport -low -cn chi-hvr2 | format-table Name,Assigned,Demand,Utilization,Maximum

Name       Assigned Demand Utilization Maximum
----       -------- ------ ----------- -------
CHI-SQL01      2586   2534       97.99    4096
CHI-FP02        846    812       95.98    2048
CHI-CORE01      514    483       93.97    1024

Get virtual machines with a low memory status.
.Example
PS C:\> get-content d:\MyVMs.txt | get-vmmemoryreport | Export-CSV c:\work\VMMemReport.csv -notypeinformation
Get virtual machine names from the text file MyVMs.txt and pipe them to Get-VMMemoryReport. The results are then exported to a CSV file.
.Example
PS C:\> get-vm -computer chi-hvr2 | get-vmmemoryreport | Sort Maximum | convertto-html -title "VM Memory Report" -css c:\scripts\blue.css -PreContent "<H2>Hyper-V Memory Report</H2>" -PostContent "<br>An assigned value of 0 means the virtual machine is not running." | out-file c:\work\vmmemreport.htm
Get a memory report for all virtual machines, sorted on the maximum memory property. This command then creates an HTML report.

.Notes
Last Updated: July 20, 2015
Version     : 3.0

.Link
Get-VM
Get-VMMemory
.Inputs
String
Hyper-V virtual machine
.Outputs
Custom object
#>

[cmdletbinding(DefaultParameterSetName="Name")]
Param(
[Parameter(Position=0,HelpMessage="Enter the name of a virtual machine",
ValueFromPipeline,ValueFromPipelineByPropertyName,
ParameterSetName="Name")]
[alias("Name")]
[ValidateNotNullorEmpty()]
[string]$VMName="*",

[Parameter(Position=0,Mandatory,HelpMessage="Enter the name of a virtual machine",
ValueFromPipeline,ValueFromPipelineByPropertyName,
ParameterSetName="VM")]
[ValidateNotNullorEmpty()]
[Microsoft.HyperV.PowerShell.VirtualMachine[]]$VM,

[switch]$Low,

[ValidateNotNullorEmpty()]
[Parameter(ValueFromPipelinebyPropertyName)]
[ValidateNotNullorEmpty()]
[Alias("CN")]
[string]$Computername=$env:COMPUTERNAME
)

Begin {
    Write-Verbose "Starting $($MyInvocation.Mycommand)"  
    #initialize an array to hold results
    $data = @()
} #begin

Process {

    if ($PSCmdlet.ParameterSetName -eq "Name") {
        Try {
            $VMs = Get-VM -name $VMName -ComputerName $computername -ErrorAction Stop
        }
        Catch {
            Write-Warning "Failed to find VM $vmname on $computername"
            #bail out
            Return
        }
    }
    else {
         $VMs = $VM
    }

    foreach ($V in $VMs) {
    #get memory values
    Try {
        Write-Verbose "Querying memory for $($v.name) on $($computername.ToUpper())"
        $memorysettings = Get-VMMemory -VMName $v.name  -ComputerName $Computername -ErrorAction Stop

    if ($MemorySettings) {
        #calculate memory utilization if VM is running
        if ($v.State -eq 'running') {
            #calculate % to 2 decimal points
            $util = [math]::Round(($v.MemoryDemand/$v.MemoryAssigned)*100,2)
        }
        else {
            $util = 0
        }    
        #all values are in MB
        $hash=[ordered]@{
            Computername = $v.ComputerName.ToUpper()
            Name = $V.Name
            Status = $v.memoryStatus
            Dynamic = $V.DynamicMemoryEnabled
            Assigned = $V.MemoryAssigned/1MB
            Demand = $V.MemoryDemand/1MB
            Utilization = $util
            Startup = $V.MemoryStartup/1MB
            Minimum = $V.MemoryMinimum/1MB
            Maximum = $V.MemoryMaximum/1MB
            Buffer =  $memorysettings.buffer
            Priority = $memorysettings.priority
        }
    
        #write the new object to the pipeline
        $data+= New-Object -TypeName PSObject -Property $hash
    } #if $memorySettings found
    } #Try
    Catch {
        Throw $_
    } #Catch
    } #foreach $v in $VMs
} #process
End {
    if ($Low) {
        Write-Verbose "Writing Low memory status objects to the pipeline"
        $data.where({$_.status -eq 'Low'})
    }
    else {
        Write-Verbose "Writing all objects to the pipeline"
        $data
    }
    Write-Verbose "Ending $($MyInvocation.Mycommand)"
} #end
} #end Get-VMMemoryReport

#set an alias
Set-Alias -name gvmr -Value Get-VMMemoryReport

I've posted versions of this function over the last few years so you may have come across earlier iterations. The major changes in this version is that I'm calculating a utilization percent of memory demand vs assigned. I also added a switch to only show virtual machines with a Low memory status, since often that's the most important thing I want to know.

Now I can easily get information for a single VM

Or multiple:

Get-VMMemoryReport -Computername chi-hvr2 -low | out-gridview -title "Low Memory"

Clearly my SQL Server needs a little attention.

I hope you'll try it out and let me know what you think.


Behind the PowerShell Pipeline

Share this:

  • Click to share on X (Opens in new window) X
  • Click to share on Facebook (Opens in new window) Facebook
  • Click to share on Mastodon (Opens in new window) Mastodon
  • Click to share on LinkedIn (Opens in new window) LinkedIn
  • Click to share on Pocket (Opens in new window) Pocket
  • Click to share on Reddit (Opens in new window) Reddit
  • Click to print (Opens in new window) Print
  • Click to email a link to a friend (Opens in new window) Email

Like this:

Like Loading...

Related

reports

Powered by Buttondown.

Join me on Mastodon

The PowerShell Practice Primer
Learn PowerShell in a Month of Lunches Fourth edition


Get More PowerShell Books

Other Online Content

github



PluralSightAuthor

Active Directory ADSI Automation Backup Books CIM CLI conferences console Friday Fun FridayFun Function functions Get-WMIObject GitHub hashtable HTML Hyper-V Iron Scripter ISE Measure-Object module modules MrRoboto new-object objects Out-Gridview Pipeline PowerShell PowerShell ISE Profile prompt Registry Regular Expressions remoting SAPIEN ScriptBlock Scripting Techmentor Training VBScript WMI WPF Write-Host xml

©2025 The Lonely Administrator | Powered by SuperbThemes!
%d