Find Virtual Machines With Active Memory Limits
get-vms-with-memory-limits.ps1
There is a well known issue with Virtual Machines running on all versions of ESX from 3.0 to 5.5 regarding memory limits. The VMWare KB Article at http://kb.vmware.com/kb/1003470 goes into detail but in summary, if a VM has a memory limit that is lower than the allocation, performance issues are likely to be encountered.
The script below will find virtual machines with active memory limits in an attempt to identify those that may be impacted by this issue. Additionally it will retrieve the memory ballooning and swapping statistics as this can be a good indicator of memory based performance issues on the VM. It has been tested and should work against vCenter 2.5, vCenter 4.x, vCenter 5.x, ESX 3.x, ESX 4.x, ESXi 4.x and ESXi 5.x.
The results can be printed to the PowerShell console, exported to a CSV or emailed.
#.SYNOPSIS Find VMs with memory limits configured, compare limit to allocation and report on Ballooning and Swapping #.PARAMETER No parameters required #.DESCRIPTION Loops through all VMs on a number of viservers finding any VMs that have a configured memory limit. This value is compared to the memory # allocation of the server and a flag set if the limit is lower than the allocation. Ballooning and Swapping statistics are also gathered for each VM. # The results can be printed to the powershell console, exported in a file or emailed. The driver for this activity comes from the following VMWare KB # article http://kb.vmware.com/kb/1003470 "Balloon driver retains hold on memory causing virtual machine guest operating system performance issues " # Adds the powercli cmdlets Add-PSSnapin VMware.VimAutomation.Core -erroraction SilentlyContinue # Array of viservers you want to process. Can be a vCenter or ESX / ESXi host $viServers = "VIServer01","VIServer02","VIServer03" # Change these variables for your environment # Enter your smtp, email from and email to details here $smtpserver = "smtpserver.domain.com.au" $smtpFrom = "sendfrom@domain.com.au" $smtpTo = "sendto@domain.com.au" # This path is where the results will be saved in csv format $strOutFile = "C:\PathForCSV\NameForCSV.csv" $output = @() $today = get-date # Disconnects from any viserver to stop potential false positive results in ouput if ($global:DefaultVIServer -ne $null){ write-host "Disconnecting from current viserver(s)" disconnect-viserver * -confirm:$false } else { write-host "Not connected to any viserver, continuing" } # Loop through each VI server in turn foreach ($viServer in $viservers) { connect-viserver $viServer # Find all VMs attached to the VI Server and save them in an array $colVMs = get-vm # Loop through the array of VMs foreach ($objVM in $colVMs) { $VMView = $objVM | get-view # Check the Memory limit for values other than "-1" (unlimited) if (($vmView.Config.memoryallocation.Limit) -ne "-1") { # Print to the console if a VM with a limit is found write-host "Memory Limit Detected on " $objVM.Name -ForegroundColor Magenta # Compare the limit to the allocation. If the limit is less than the allocation, set a flag if ($vmview.config.memoryallocation.limit -lt $VMView.summary.config.MemorySizeMB ) { $AllocLimitMissMatch = $true } else { $AllocLimitMissMatch = $false } # Retrieve Ballooning and Swapping statistics for the VM. This can also be obtained from the $vmview object # but it doesn't seem to exist in vCenter 2.5 / ESX 3.5. This method works with all versions $VMBaloon = ($objVM | get-stat -Realtime -stat mem.vmmemctl.average -MaxSamples 1 -ErrorAction SilentlyContinue).Value $VMSwap = ($objVM | get-stat -Realtime -stat mem.swapped.average -Maxsamples 1 -ErrorAction SilentlyContinue).value # Save the results into a custom object. This part requires Powershell 3.0 $objResult = [PSCustomObject] @{ "VM Name" = $objVm.Name "Memory Allocation" = $VMView.summary.config.MemorySizeMB "Memory Limit" = $vmview.config.memoryallocation.limit "Memory Reservation" = $vmview.config.memoryallocation.Reservation "Memory Limit Less than Allocation" = $AllocLimitMissMatch "Ballooned Memory" = $VMBaloon "Swapped Memory" = $VMSwap "Power State" = $objVM.PowerState "vCenter Server" = $viServer } # Add the results object to an output object to be used in the report $output += $objResult } } # Disconnect from the current VI server and return to the start of the loop disconnect-viserver $viserver -confirm:$false } # Print the results on the screen and export to a csv file $output $output | export-csv $strOutFile -notype # HTML CSS for email body and .htm file $style = @"</pre> <style><!-- body { color:#333333; font-family:Calibri,Tahoma; font-size: 9pt; } h1 { text-align:center; } h2 { border-top:1px solid #666666; } th { font-weight:bold; color:#eeeeee; background-color:#333333; border-top:1px solid #666666; } .odd { background-color:#ffffff; } .even { background-color:#dddddd; } --></style> <pre>"@ # Build objects for the email to be sent $strSubject = “vSphere Memory Limit Report - ” + (get-date -DisplayHint date) $strMail = "</pre> <h2><span style="text-decoration: underline;">" + $strSubject + "</span></h2> <pre> Report showing all VMs with Memory Limits configured from targeted vCenter servers. " $message = new-object System.Net.Mail.MailMessage $smtpfrom, $smtpto $message.subject = $strSubject $message.IsBodyHTML = $true $message.Body = $output | sort-object vCenter,VM | convertto-html -head $style -body $strMail # Send mail message with report in html format send-mailmessage -bodyashtml $message.body -from $smtpFrom -smtpServer $smtpServer -subject $strSubject -to $smtpto