VMware Cloud Community
bseymour
Contributor
Contributor

Get Disk information for Guests

I am trying to retrieve Guest VM Disk information and I want to gather the following:

  • Host Name
  • Cluster
  • Guest Name
  • Guest Provisioned Space
  • Each Drive
    • Provisioned Space
    • Free Space
    • Location of Disk

The script works except it is not grabbing all the disks. Some guest have 4 or more disks associated with them. Can someone help with this?

Here is the script:

$VirtualCenter = Read-Host "Please enter the name of the Virtual Center Server"

$FileLocation = Read-Host "Please Enter Complete Path and file name to save the output.  Must end in .csv or .txt"

Connect-VIServer $VirtualCenter

$stats = @()

$ServerList = Get-VM | Sort Name

Clear

Foreach ($Guests in $ServerList) {

  $Guest = $Guests.Name.ToUpper()

  Write-Progress -Activity "Creating VMware Guest Inventory" -Status "Processing VM Guest $Guest"# Display progress bar

  $VM = Get-VM $Guest

  #$VMGuest = Get-VMGuest $Guest

  $ESXHost = $VM.Host.Name.ToUpper()

  $VMHost = Get-VMHost $ESXHost

  $row = New-Object System.Object

  $row | Add-Member -Type NoteProperty -Name "Guest" -Value $Guest

  $row | Add-Member -Type NoteProperty -Name "Guest Provisioned Space (GB)" -Value $VM.ProvisionedSpaceGB

  $DiskCount = 0

  $DT = @()

  ForEach ($vDisk in $VM.Guest.Disks) {

  $DriveLoc = "Guest Drive " + $DiskCount + " Location"

  $DriveLetter = "Guest Drive " + $DiskCount + ""

  $DriveSize = "Guest Drive " + $DiskCount + " Size"

  $DriveFree = "Guest Drive " + $DiskCount + " Free Space"

  $vDiskCap = [math]::Round(($vDisk.Capacity) / 1GB)

  $vDiskFree = [math]::Round(($vDisk.FreeSpace) / 1GB)

  $vDiskLoc = $VM.HardDisks[$DiskCount]

  $row | Add-Member -Type NoteProperty -Name $DriveLetter -Value $vDisk.Path

  $row | Add-Member -Type NoteProperty -Name $DriveSize -Value $vDiskCap

  $row | Add-Member -Type NoteProperty -Name $DriveFree -Value $vDiskFree

  $row | Add-Member -Type NoteProperty -Name $DriveLoc -Value $vDiskLoc.Filename

  $DiskCount++

  $DriveTotals = "" + $row.$DriveLetter + " " + $row.$DriveSize + ";"

  $DT += $DriveTotals

  }

  $row | Add-Member -Type NoteProperty -Name "Host Name" -Value $VMHost.ExtensionData.Summary.Config.Name.ToUpper()

  $ESXCluster = Get-Cluster -VMHost $ESXHost -ErrorAction SilentlyContinue

  IF (!$ESXCluster)

  {

  $row | Add-Member -Type NoteProperty -Name "Host is Member of Cluster" -Value "Stand Alone Host"

  } ELSE {

  $row | Add-Member -Type NoteProperty -Name "Host is Member of Cluster" -Value $ESXCluster.Name.ToUpper()

  }

  $stats += $row

}

$stats | Export-Csv -Force .\$FileLocation -NoTypeInformation

Invoke-Item .\$FileLocation

0 Kudos
1 Reply
LucD
Leadership
Leadership

You are stumbling on a known feature in the Export-Csv cmdlet.

This cmdlet looks at the first row in the array you are exporting, to determine how many columns there will be in the CSV file.

If the first row happens to be "shorter", in other words less properties, than the 2nd row, the CSV will not contain the extra columns of the 2nd row.

One way to fix this, is to sort the rows in the array in descending order on the number of properties/columns.

In other words, the longest row first.

So instead of

$stats | Export-Csv -Force .\$FileLocation -NoTypeInformation

do a

$stats | Sort-Object -Property {($_ | Get-Member).Count} -Descending |
Export-Csv -Force .\$FileLocation -NoTypeInformation


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos