qwert1235
Enthusiast
Enthusiast

find VM disks actual size

Jump to solution

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!

0 Kudos
1 Solution

Accepted Solutions
mattboren
Expert
Expert

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...

View solution in original post

0 Kudos
10 Replies
Hosted201110141
Enthusiast
Enthusiast

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

qwert1235
Enthusiast
Enthusiast

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!

0 Kudos
Hosted201110141
Enthusiast
Enthusiast

Unfortunately I don't know how to do that.  Maybe one of the Gurus around here does though.

0 Kudos
mattboren
Expert
Expert

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.

LucD
Leadership
Leadership

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

0 Kudos
qwert1235
Enthusiast
Enthusiast

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!

0 Kudos
mattboren
Expert
Expert

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...

0 Kudos
KaldrZhu
Contributor
Contributor

your code is good, but the diskchain would lose disks of snapshots not in current snapshot chain.

0 Kudos
KaldrZhu
Contributor
Contributor

but this method can't get the diskextent files of disks in snapshots that are are not in current snapshot chain

0 Kudos
LucD
Leadership
Leadership

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

0 Kudos