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.
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.
