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.