VMware Aria Operations Guest|Needed Memory (KB) metric retrieved at point in time directly from vSphere using PowerShell and PowerCLI
search cancel

VMware Aria Operations Guest|Needed Memory (KB) metric retrieved at point in time directly from vSphere using PowerShell and PowerCLI

book

Article ID: 410736

calendar_today

Updated On:

Products

VMware vCenter Server

Issue/Introduction

VMware Aria Operations contains various metrics to enable users to monitor and manage their vCenter and components effectively. Once such metric for virtual machines is Guest|Needed Memory which has been defined as the amount of memory needed for the Guest OS to perform optimally. This memory is considered as a cache for the disk and is a little more than the actual used memory. (For more information on the metric and its definition please see VMware Aria Operations documentation). 

This metric is gathered using VMware Tools on the virtual machine and therefore, we can use vSphere SDKs and APIs that use VMware Tools to pull the same information and gather the point-in-time metric for a specific virtual machine (vm). 

VMware Aria Operations is still the primary source for this data and can be considered the True source. The script provided is a replication based on the calculation used for the metric and can be considered an "as-is" resource, meaning it is not subject to guaranteed support by Broadcom and any assistance provided is in a "best effort" capacity and dependent on the individual engineer's discretion. This script is not guaranteed to be updated on the same timeline as potential changes or updates to the metric in VMware Aria Operations.

Environment

VMware Aira Operations

VMware vCenter Server

Resolution

# Retrieve Guest|Needed Memory as seen in Aria Ops directly from vSphere
# The description of this value is the amount of memory needed to run the guest without swapping
# Linux Guest|Needed Memory can be defined as follows:
#
# z - max(0, m - (0.05 * z))
#
# Where:
# z represents guest.mem.physUsable which is derived from "present" in /proc/zoneinfo
# m represents "MemAvailable" which is derived from /proc/meminfo
#
# And can be described as Total memory minus not needed memory plus a 5% reservation. 
#
#
# Windows Guest|Needed Memory can be defined as follows:
#
# Find the value according to Windows spec (in KB, uint64)
# Derived as ("guest.mem.physUsable" - max(0, UNNEEDED_BYTES - 5% of "guest.mem.physUsable")), where, 
# for Vista and later 
# UNNEEDED_BYTES = "Win32_PerfRawData_PerfOS_Memory=@#FreeAndZeroPageListBytes" + "Win_PerfRawData_PerfOS_Memory=@#StandbyCacheReserveBytes". 
# For older Windows, UNNEEDED_BYTES = "Win32_PerfRawData_PerfOS_Memory=@#AvailableBytes".
# This script assumes Windows Vista or later
#
# Note this script relies on VMware Tools being installed with at least version 
# 11.0.0 or higher


###############################################################################
Note, this script is not production ready and requires review and authorization 
by the user before implementing outside of a test environment. Using the below 
code snippet is at the initiators own risk. Furthermore, this is not a script 
that VMware by Broadcom claims as their own or can be further supported by 
VMware by Broadcom or its representatives. The script has been provided purely 
as an example and is meant to be iterated on and re-scripted according to the 
user's needs. 
###############################################################################

# Define variables
$vcenter = "<vCenter FQDN>"
$username = "[email protected]"
$password = "<password for administrator>"
$vmName = "<enter virtual machine name>"
$vmObj = Get-VM -Name ${vmName}
$vmOS = ${vmObj} | Select-Object Name, @{N="Configured OS";E={$_.ExtensionData.Config.GuestFullName}}
$guestUser = "<administrative user of the virtual machine>"
$guestPass = "<password of the virtual machine administrative user>"


# Login to vCenter
# https://developer.broadcom.com/powercli/latest/vmware.vimautomation.core/commands/connect-viserver
Connect-VIServer -Server ${vcenter} -User ${username} -Password ${password}

# Check if virtual machine is powered on, if not then close the loop
if (${vmObj} -and ${vmObj}.PowerState -eq "PoweredOn") {
    # Check guestOS type to determine how to calculate
    if (${vmOS} -like "*Windows*") {
        Write-Host "Guest OS is type Windows"
        
        try {
    
            # Find "guest.mem.physUsable" which is 
            # "Win32_OperatingSystem=SINGLETON(*)#TotalVisibleMemorySize" from WMI in KB (uint64)
            $guestMemPhysUsable = Invoke-VMScript -VM ${vmObj} -ScriptText `'Get-CimInstance Win32_OperatingSystem | Select-Object @{N="Memory(KB)";E={$_.TotalVisibleMemorySize}' ` -GuestUser ${guestUser} -GuestPassword ${guestPass}

            $memory = Invoke-VMScript -VM ${vmObj} -ScriptText `'Get-CimInstance -ClassName Win32_PerfRawData_PerfOS_Memory'` -GuestUser ${guestUser} -GuestPassword ${guestPass}

            $guestUnneededBytes = $memory.FreeAndZeroPageListBytes + $memory.StandbyCacheReserveBytes

            $fivePerc = 0.05 * ${guestMemPhysUsable}
            $unNeededWOFivePerc = ${guestUnneededBytes} - ${fivePerc}
            $maxOfZeroAndUnneeded = [System.Math]::Max(0, ${unNeededWOFivePerc})

            $guestNeededMem = ${guestMemPhysUsable} - ${maxOfZeroAndUnneeded}
            Write-Host "Guest|NeededMemory: ${guestNeededMem}"
        } catch {
            Write-Error "An error occurred: $($_.Exception.Message)"
        }

    } else if (${vmOS} -like "*Linux*") {
        Write-Host "Guest OS is type Linux"
        
        try {
            # Define the script to be executed in the guest OS
            # The 'cat' command reads the content of the file
            $guestMemPhysUsableScript = "cat /proc/zoneinfo"
            $guestMemAvailableScript = "cat /proc/meminfo"

            $guestMemPhysUsableResult = Invoke-VMScript -VM ${vmObj} -ScriptText ${guestMemPhysUsableScript} -GuestUser ${guestUser} -GuestPassword ${guestPass} -ScriptType "Sh"
            $guestMemAvailableResult = Invoke-VMScript -VM ${vmObj} -ScriptText ${guestMemAvailableScript} -GuestUser ${guestUser} -GuestPassword ${guestPass} -ScriptType "Sh"

            $fivePerc = 0.05 * ${guestMemPhysUsableResult}
            $unNeededWOFivePerc = ${guestMemAvailableResult} - ${fivePerc}
            $maxOfZeroAndUnneeded = [System.Math]::Max(0, ${unNeededWOFivePerc})

            $guestNeededMem = ${guestMemPhysUsable} - ${maxOfZeroAndUnneeded}
            Write-Host "Guest|NeededMemory: ${guestNeededMem}"
   
        } catch {
            Write-Error "An error occurred: $($_.Exception.Message)"
        }
    } else {
        Write-Host "Guest OS type is not Windows or Linux"
        Write-Host "Cannot calculate Guest|Needed Memory without OS type"
    }
} else {
    # Stop the run because VM is not in the right power state
    Write-Host "Virtual Machine ${vmName} is not found or not in the correct power state to complete this action."
}

# Disconnect from vCenter
# https://developer.broadcom.com/powercli/latest/vmware.vimautomation.core/commands/disconnect-viserver
Disconnect-VIServer -Server ${vcenter} -Confirm:$false