2026-03-06

Get VM's Virtual Hard Disk Size with Keyword

$keyword = 'Off'

$vms = Get-VM | Where-Object { $_.Name -like "*$keyword*" }

if (-not $vms) {
   Write-Host "找不到 VM 名稱包含 '$keyword' 的虛擬機。" -ForegroundColor Yellow
   return
}

$vmResults = @()
$grandTotalBytes = 0

foreach ($vm in $vms) {
   $hdds = Get-VMHardDiskDrive -VMName $vm.Name -ErrorAction SilentlyContinue

   if (-not $hdds) {
       $vmResults += [pscustomobject]@{
           VMName     = $vm.Name
           VhdCount    = 0
           TotalSizeGB = 0.0
           Detail     = "<無掛載虛擬硬碟>"
       }
       continue
   }

   $vmTotalBytes = 0
   $detailLines = New-Object System.Collections.Generic.List[string]

   foreach ($hdd in $hdds) {
       $vhdPath = $hdd.Path

       if ([string]::IsNullOrWhiteSpace($vhdPath) -or -not (Test-Path -LiteralPath $vhdPath)) {
           $detailLines.Add("Missing/Invalid: $vhdPath")
           continue
       }

       try {
           $vhd = Get-VHD -Path $vhdPath -ErrorAction Stop
           $fileSizeBytes = [int64]$vhd.FileSize
           $vmTotalBytes += $fileSizeBytes

           $sizeGB = [math]::Round($fileSizeBytes / 1GB, 3)
           # 用字串插值,避免 -f 在特殊字元時出事
           $detailLines.Add("$vhdPath => $sizeGB GB")
       }
       catch {
           $msg = $_.Exception.Message
           $inner = $null
           if ($_.Exception.InnerException) {
               $inner = $_.Exception.InnerException.Message
           }
           if ($inner) { $msg = "$msg | Inner: $inner" }
           $detailLines.Add("ReadError: $vhdPath => $msg")
       }
   }

   $grandTotalBytes += $vmTotalBytes

   $vmResults += [pscustomobject]@{
       VMName     = $vm.Name
       VhdCount    = ($hdds | Measure-Object).Count
       TotalSizeGB = [math]::Round($vmTotalBytes / 1GB, 3)
       Detail     = ($detailLines -join "`n")
   }
}

$vmResults |
   Sort-Object -Property TotalSizeGB -Descending |
   Format-Table -AutoSize VMName, VhdCount, TotalSizeGB

"`n===== 明細(每台 VM 的各 VHD 實際大小) ====="
foreach ($r in $vmResults) {
   "`n[$($r.VMName)] 共 $($r.VhdCount) 顆,合計 $($r.TotalSizeGB) GB"
   $r.Detail
}

$grandTotalGB = [math]::Round($grandTotalBytes / 1GB, 3)
"`n===== 全部合計(VM 名稱包含 '$keyword') ====="
"合計占用:$grandTotalGB GB"

沒有留言:

張貼留言