Our workloads run on VMs and containers, the proliferation of both sometimes is hard to track and even if we are using them for LABS or DEV/TEST/PROD environments monitor or measure it a key feature.
I will show you how easy is to stay on track with just few lines of powershell.
Let’s start with a single Hyper-V host. Get the footprint of a Virtual Machine can be simply obtained with a function like this:
1 2 3 4 5 6 7 |
function Get-VMFootprint ($VM){ $total_size = 0 foreach ($disk in ($VM | Get-VMHardDiskDrive | Select-object -expandproperty path) ){ $total_size += Get-Item $disk | Select-Object -ExpandProperty Length } Return [math]::round($total_size/1GB,2) } |
Once defined, I can call it in a foreach loop. To get a better user experience I will also add Write-Progress as shown here:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
$counter = 0 $vm_counter = 0 $total = 0 foreach ($VMHost in $ALL_VM_NODES){ $counter += 1 foreach ($VM in (get-vm -computername $VMHost)){ $vm_counter += 1 Write-Progress -Status "Get Footprint of $($VM.Name)" -Activity "Retrieve information from $($VmHost)" -PercentComplete $($couter/$NumNodes*100) $VmSize = $(Get-VMFootprint($VM)) Write-Verbose "$($VM.Name) - $VmSize GB" $total += $VmSize } } Write-Output "$vm_counter VMs Footprint: $total GB " |
With this end result:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
#requires -runasadministrator # # Paolo Frigo, https://www.scriptinglibrary.com # This script will get the size of all VHDX files of all VMs hosted on your Hyper-V # # notes - Please have a look to get-vmfootprintbyenv.ps1 in case you want to run this # script against multiple hyper-v hosts function Get-VMFootprint ($VM){ $total_size = 0 foreach ($disk in ($VM | Get-VMHardDiskDrive | Select-object -expandproperty path) ){ $total_size += Get-Item $disk | Select-Object -ExpandProperty Length } Return [math]::round($total_size/1GB,2) } $counter = 0 $vm_counter = 0 $total = 0 foreach ($VMHost in $ALL_VM_NODES){ $counter += 1 foreach ($VM in (get-vm -computername $VMHost)){ $vm_counter += 1 Write-Progress -Status "Get Footprint of $($VM.Name)" -Activity "Retrieve information from $($VmHost)" -PercentComplete $($couter/$NumNodes*100) $VmSize = $(Get-VMFootprint($VM)) Write-Verbose "$($VM.Name) - $VmSize GB" $total += $VmSize } } Write-Output "$vm_counter VMs Footprint: $total GB " |
If your environment leverages Microsoft Hyper-V more extensively with multiple nodes/hosts and obtain the same result sometimes can be tricky.
But using invoke-command there is no need to copy the previous powershell script on each host and we can simply run this one:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
#requires -runasadministrator #requires -modules ActiveDirectory # # Paolo Frigo, https://www.scriptinglibrary.com # This script will sum all VM Footprints according to the filter PROD/TEST/DEV used. # $Filter = "prod" # prod, test or dev $VMNODES = "VMNode-01", "VMNode-02", "VMNode-03" #get-adcomputer -filter {name -like "My_Naming_Convention"} | Select-object -expandproperty name $Result = 0 foreach ($VMHost in $VMNODES) { if (Test-Connection $VMHost -Quiet -Count 1) { $VM = get-vm -computername $VMHost | Where-Object {$_.name -match "$Filter"} $Disks = $VM | Get-VMHardDiskDrive | Select-object -expandproperty path $total_size = Invoke-Command -ComputerName $VMHost -ScriptBlock { param($Disks) $total = 0 #write-host $disks foreach ($disk in $disks) { $size = [math]::round((get-item -Path $disk | select-object -ExpandProperty length)/1GB,2) write-host "Disk: $disk `t Size $size GB" $total += $size } return $total } -ArgumentList (,$Disks) $Result += $total_size } else { raise "$VMHost is not reachable" } } Write-Output "$Filter VM footprint is $Result GB".ToUpper() |
As usual this scripts are available on my github repository.