Excerpt
Quick, repeatable way to see CPU/RAM/vSAN headroom across hosts and choose where to place the next VM. Today it pointed us to vsan2.
Intro
Before cloning a new Windows VM, I ran a fast PowerCLI sweep across three vSAN hosts to compare free CPU, free memory, and vSAN free space. All three had identical vSAN capacity; vsan2 had the most free RAM, so that’s the landing spot.
Straight line (what I did)
• Pulled CPU and memory usage per host (MHz/MB) and calculated free.
• Queried each host’s vSAN datastore(s) and summed free/total GB.
• Printed a compact table to compare vsan1/2/3 at a glance.
• Chose the host with the highest Mem_Free_GB (tie-break on vSAN free).
Command (copy/paste)
# Hosts to check (redacted)
$hosts = 'vsan1.example.local','vsan2.example.local','vsan3.example.local'
$report = foreach ($h in $hosts) {
try {
$vmh = Get-VMHost -Name $h -ErrorAction Stop
$cpuTot = $vmh.CpuTotalMhz; $cpuUse = $vmh.CpuUsageMhz
$memTot = $vmh.MemoryTotalMB; $memUse = $vmh.MemoryUsageMB
$vsan = $vmh | Get-Datastore | Where-Object { $_.Type -eq 'vsan' }
$dsCapGB = ($vsan | Measure-Object CapacityGB -Sum).Sum
$dsFreeGB = ($vsan | Measure-Object FreeSpaceGB -Sum).Sum
$dsFreePct = if ($dsCapGB) { [math]::Round(100*($dsFreeGB/$dsCapGB),2) } else { 0 }
[pscustomobject]@{
Host = $vmh.Name
CPU_Free_GHz = [math]::Round(($cpuTot-$cpuUse)/1000,2)
CPU_Total_GHz = [math]::Round($cpuTot/1000,2)
CPU_Free_pct = if ($cpuTot) { [math]::Round(100*(($cpuTot-$cpuUse)/$cpuTot),2) } else { 0 }
Mem_Free_GB = [math]::Round(($memTot-$memUse)/1024,2)
Mem_Total_GB = [math]::Round($memTot/1024,2)
Mem_Free_pct = if ($memTot) { [math]::Round(100*(($memTot-$memUse)/$memTot),2) } else { 0 }
vSAN_Free_GB = [math]::Round($dsFreeGB,2)
vSAN_Total_GB = [math]::Round($dsCapGB,2)
vSAN_Free_pct = $dsFreePct
}
} catch {
[pscustomobject]@{ Host=$h; CPU_Free_GHz='n/a'; CPU_Total_GHz='n/a'; CPU_Free_pct='n/a';
Mem_Free_GB='n/a'; Mem_Total_GB='n/a'; Mem_Free_pct='n/a';
vSAN_Free_GB='n/a'; vSAN_Total_GB='n/a'; vSAN_Free_pct='n/a' }
}
}
$report | Format-Table -AutoSize
# Optional: pick best host by RAM, then vSAN GB
$best = $report | Where-Object { $_.Mem_Free_GB -is [double] } |
Sort-Object Mem_Free_GB, vSAN_Free_GB -Descending | Select-Object -First 1
"Suggested placement: $($best.Host) (Mem free: $($best.Mem_Free_GB) GB, vSAN free: $($best.vSAN_Free_GB) GB)"
Result today
• vsan2 showed the most free RAM, with CPU headroom similar across all three and identical vSAN free space.
• Suggested placement: vsan2.
Pocket I’m keeping
• Check host headroom before every clone—30 seconds now saves hours later.
• Prefer RAM headroom for Windows VDI/worker VMs; CPU is usually similar across nodes.
• Keep a one-liner that prints the table and the suggested host.
What I hear now
Clone to vsan2, power up, then let DRS/vMotion rebalance after the build window. Repeat this check whenever adding workloads or after maintenance.
© 2012–2025 Jet Mariano. All rights reserved.
For usage terms, please see the Legal Disclaimer.