Get actual usage of VMDK on SAN

powerclivmware-esxivmware-vcentervmware-vsphere

I have a script that retrieves details for all VMs in my vCenter Cluster. Essentially Get-VM | Get-Harddisk.

I can also get the Provisioned Space and Used Space values, but these are only for the VM as a whole, and I'd like to get this per VMDK file on the actual SAN.

I have had some luck with ($vm.extensiondata.layoutex.file|?{$_.name -contains $harddisk.filename.replace(".","-flat.")}).size/1GB but this does not retrieve details for all my VMs, and I cannot workout why?

UPDATE 1:
So I have found that this information is available through $vm.ExtensionData.Storage.PerDatastoreUsage. This returns an array of details of each datastore and shows how much disk is used. The issue now is that I don't know how to tally up which entry relates to which disk (other than manually checking). Its fine if each disk is on a different datastore, but when they are all on the same and of the same size (i.e. we have a Windows VM with 2 100GB Thin disks on same datastore) it proves more challenging.

Best Answer

I have eventually found this post https://communities.vmware.com/message/1816389#1816389 on the VMware Communities site that gives the following code as a solution that I can adapt:

Get-View -ViewType VirtualMachine -Property Name, Config.Hardware.Device, LayoutEx | %{
$viewVM = $_; $viewVM.Config.Hardware.Device | ?{$_ -is [VMware.Vim.VirtualDisk]} | %{
    ## for each VirtualDisk device, get some info
    $oThisVirtualDisk = $_
    ## get the LayoutEx Disk item that corresponds to this VirtualDisk
    $oLayoutExDisk = $viewVM.LayoutEx.Disk | ?{$_.Key -eq $oThisVirtualDisk.Key}
    ## get the FileKeys that correspond to the LayoutEx -> File items for this VirtualDisk
    $arrLayoutExDiskFileKeys = $oLayoutExDisk.Chain | ?{$_ -is [VMware.Vim.VirtualMachineFileLayoutExDiskUnit]}
    New-Object -TypeName PSObject -Property @{
        ## add the VM name
        VMName = $viewVM.Name
        ## the disk label, like "Hard disk 1"
        DiskLabel = $_.DeviceInfo.Label
        ## the datastore path for the VirtualDisk file
        DatastorePath = $_.Backing.FileName
        ## the provisioned size of the VirtualDisk
        ProvisionedSizeGB = [Math]::Round($_.CapacityInKB / 1MB, 1)
        ## get the LayoutEx File items that correspond to the FileKeys for this LayoutEx Disk, and get the size for the items that are "diskExtents" (retrieved as bytes, so converting to GB)
        SizeOnDatastoreGB = [Math]::Round(($arrLayoutExDiskFileKeys | %{$_.FileKey} | %{$intFileKey = $_; $viewVM.LayoutEx.File | ?{($_.Key -eq $intFileKey) -and ($_.Type -eq "diskExtent")}} | Measure-Object -Sum Size).Sum / 1GB, 1)
    } ## end new-object
} ## end foreach-object
} ## end outer foreach-object

I was lead via the communities site to the excellent blog http://www.lucd.info/2010/03/23/yadr-a-vdisk-reporter/ that has a solution that includes the size of the snapshots too