I need to find VM hard disk(s) capacity and compare it with actual disk size on a datastore in case it's thin type.
I can fing capacity -
$disk1Size = $VM.HardDisks[0].capacityKB / 1024 / 1024 # size allocated in GB ,
but have problem with actual disk size.
How can I find actual disk (vmdk) size?
Thanks a lot!
Ha, well, of course I should have known that you, Luc, had previously covered the topic at hand. I did not see your yadr post in my search results. Next time I should probabaly go to lucd.info first, then do a standard web search if the answer is not there.
You are welcome, qwert1235, glad to help. As for your follow-up question, you could use the Group-Object cmdlet to group the info objects together, say, based on the VMName property. To do so, you would pipe my second code block above to Group-Object, keeping the results in a variable for the later use you spoke of, like:
## group the results by VMName, and put into hashtable
$hshDiskInfo = $(
## ... the second code block from above -- put here ... ##
) | Group-Object -Property VMName -AsHashTable
Then, for example, you could get the disk info for a given VM by accessing that VM's disk info in the hash table, like:
## get the disk info for one VM, and add up the SizeOnDatastoreGB values
$hshDiskInfo["someVM"] | Measure-Object -Property SizeOnDatastoreGB -Sum
You can do what you want to with that hashtable to fit your needs, be that loop through all of its keys, or access just given VMs' info, or...
if you want to pull the actual size on the datastore of all vmdks combined for a VM you could use the following:
$vm.ExtensionData.Summary.Storage.Committed / 1024 / 1024 / 1024
It's a very helpfull. Thanks a lot!
How can i break it down to hard drives? The hard drives could be spread across multiple datastore and this summary will not work for my needs.
Thanks!
Unfortunately I don't know how to do that. Maybe one of the Gurus around here does though.
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.
That is a similar method to the one I'm using in my yadr – A vdisk reporter script.
With that difference, that my script also reports the size of eventual snapshots.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Matt,
Thanks a lot!
It's almost exactly what I am looking for....
How can I modify the script in order to have variable $SizeOnDatastoreGB for each hard drive at the end?
Basically, I want to have variables ProvisionedSize and SizeOnDatastore for each harddisk on VM. Something like $SizeOnDatastoreDisk1GB, $SizeOnDatastoreDisk2GB, $SizeOnDatastoreDisk3GB and etc...
I will need to use them in future.
Thanks again!
Ha, well, of course I should have known that you, Luc, had previously covered the topic at hand. I did not see your yadr post in my search results. Next time I should probabaly go to lucd.info first, then do a standard web search if the answer is not there.
You are welcome, qwert1235, glad to help. As for your follow-up question, you could use the Group-Object cmdlet to group the info objects together, say, based on the VMName property. To do so, you would pipe my second code block above to Group-Object, keeping the results in a variable for the later use you spoke of, like:
## group the results by VMName, and put into hashtable
$hshDiskInfo = $(
## ... the second code block from above -- put here ... ##
) | Group-Object -Property VMName -AsHashTable
Then, for example, you could get the disk info for a given VM by accessing that VM's disk info in the hash table, like:
## get the disk info for one VM, and add up the SizeOnDatastoreGB values
$hshDiskInfo["someVM"] | Measure-Object -Property SizeOnDatastoreGB -Sum
You can do what you want to with that hashtable to fit your needs, be that loop through all of its keys, or access just given VMs' info, or...
your code is good, but the diskchain would lose disks of snapshots not in current snapshot chain.
but this method can't get the diskextent files of disks in snapshots that are are not in current snapshot chain
That is maybe why they are called "orphaned disks".
There is another function to find those.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference