Hello, qwert1235-
You can use the LayoutEx property (API reference) of the View object of the VM. That property holds info about all of the files associated with the VM, including their actual sizes on the datastore.
It is a bit more involved, but looks something like:
$strVMName = "myVM"
$viewVM = Get-View -ViewType VirtualMachine -Property Name, Config.Hardware.Device, LayoutEx -Filter @{"Name" = $strVMName}
## for each VirtualDisk device, get some info
$viewVM.Config.Hardware.Device | ?{$_ -is [VMware.Vim.VirtualDisk]} | %{
$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 @{
## 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
The output is something like:
ProvisionedSizeGB DiskLabel DatastorePath SizeOnDatastoreGB
----------------- --------- ------------- -----------------
16 Hard disk 1 [dStore02] myVM/myVM.vmdk 16
400 Hard disk 2 [dStore02] myVM/myVM_1.vmdk 251.7
This gets the Config.Device items that are VirtualDisks, gets the LayoutEx.Disk items that correspond to the given VirtualDisk keys, gets the LayoutEx.File items that correspond to the given FileKeys, and grabs their size-on-datastore. Nice.
It would be trivial to get this info for all VMs. You would just switch it up a bit, like:
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
That returns the given info for all VMs (I added VM name for each, too). Since the info is returned in objects, you could still do what you'd like with it -- sort, filter, Export-Csv, whatever.
Enjoy.