How big is my VM?

If you want to know the size of your vm, you probably first look at the size of the virtual disks in the vm’s settings, but there’s more to it. A virtual machine consists of the following set of files:

  • Config files (.vmx, .vmxf, .vmsd, .nvram)
  • Log files (.log)
  • Disk files (.vmdk)
  • Snapshots (delta.vmdk, .vmsn)
  • Swapfile (.vswp)

To make things more complicated, these files can be stored on different datastores. So if you want to know how much storage is occupied by your vm, you have to add up all these file’s sizes.

I created a little Powershell function to help me out on this one. In its simplest form a vm consists of one or more directories. This script first creates an array with all directories occupied by the vm and then adds up all the file’s sizes in these directories. Just feed the function with a vm object and it will return the vm’s total size in bytes.

function Get-VmSize($vm)
{
    #Initialize variables
    $VmDirs =@()
    $VmSize = 0

    $searchSpec = New-Object VMware.Vim.HostDatastoreBrowserSearchSpec
    $searchSpec.details = New-Object VMware.Vim.FileQueryFlags
    $searchSpec.details.fileSize = $TRUE

    Get-View -VIObject $vm | % {
        #Create an array with the vm's directories
        $VmDirs += $_.Config.Files.VmPathName.split("/")[0]
        $VmDirs += $_.Config.Files.SnapshotDirectory.split("/")[0]
        $VmDirs += $_.Config.Files.SuspendDirectory.split("/")[0]
        $VmDirs += $_.Config.Files.LogDirectory.split("/")[0]
        #Add directories of the vm's virtual disk files
        foreach ($disk in $_.Layout.Disk) {
            foreach ($diskfile in $disk.diskfile){
                $VmDirs += $diskfile.split("/")[0]
            }
        }
        #Only take unique array items
        $VmDirs = $VmDirs | Sort | Get-Unique

        foreach ($dir in $VmDirs){
            $ds = Get-Datastore ($dir.split("[")[1]).split("]")[0]
            $dsb = Get-View (($ds | get-view).Browser)
            $taskMoRef  = $dsb.SearchDatastoreSubFolders_Task($dir,$searchSpec)
            $task = Get-View $taskMoRef 

            while($task.Info.State -eq "running" -or $task.Info.State -eq "queued"){$task = Get-View $taskMoRef }
            foreach ($result in $task.Info.Result){
                foreach ($file in $result.File){
                    $VmSize += $file.FileSize
                }
            }
        }
    }

    return $VmSize
}

If, for example, you want to know the size of vm VM01, you can use the function as shown in the example below.

$vm = Get-VM VM01
$size = Get-VmSize($vm)

Remember to test the scripts thoroughly before using it in your production environment, as I can take no responsibility for whatever happens to your environment using these scripts.

Related posts:

  1. List HBA WWPNs and LUNs using Powershell Tweet Lately I’m moving around my VMs and storage luns between my ESX clusters a lot to accomplish a complete redesign of my Virtual Infrastructure. At some point I got...
  2. Export and import customization profiles using Powershell Tweet One great thing in the automation of VM deployments is the use of customization profiles. These profiles are stored inside the vCenter Server database. However, when you loose the...
  3. Setting custom attributes with VMware PowerCLI Tweet Last week I wanted to extend my vCenter with some extra custom attributes on my VMs. This would extend the usability of the Export List feature for reporting purposes....
  4. Bulk change your ESX root password Tweet Have you ever been facing your security department demanding you to change your ESX root password? Well I did. At the current site there’s a strict security policy where...
  5. Reconnect ESX hosts using PowerShell Tweet This week I ran into problems with vCenter server and almost all of my VMs were orphaned in vCenter. To resolve this issue I needed to disconnect/connect each ESX...

12 Comments on “How big is my VM?”

  1. #1 Top 5 Planet V12n blog posts week 31 | News, Articles and Analysis about Virtualization
    on Aug 2nd, 2009 at 12:59 pm

    [...] van Lieshout – How big is my VM?To make things more complicated, these files can be stored on different datastores. So if you want [...]

  2. #2 Quelle taille (totale) fait ma VM ? - Hypervizor.fr
    on Aug 18th, 2009 at 6:46 pm

    [...] En cherchant un moyen élégant de remonter dans rapport la taille occupée par les différents snapshots d’une VM, nous sommes tombés sur un script powershell récemment posté par Arnim van Lieshout : How big is my VM? [...]

  3. #3 NiTRo
    on Aug 18th, 2009 at 6:49 pm

    Hi Arnim, i made some changes to make it work on vCenter 4.0 : http://www.hypervizor.fr/?p=1034
    Thanks a lot for this script !

  4. #4 Arnim van Lieshout
    on Aug 18th, 2009 at 10:12 pm

    Thank you for sharing this NiTRo.
    As soon as I have my vSphere4 test rig in place I’ll check out your modifications.

    Arnim

  5. #5 Trent
    on Oct 27th, 2009 at 10:51 pm

    Thanks for the info … I was poking in the SDK reference guide to try and find usage on HostDatastoreBrowserSearchSpec for my Snapshot report script. I ended up just modifying yours because you get more info than needed which I might use later.

    My modified script just pulls “delta.vmdk” and the vmsn file, then adds them up and divides by 1mb.

    I will give you credit if/when I pass mine along to my friends who were also looking for a snapshot size feature!

    trentwtaylor at gmail if you want it.

  6. #6 NiTRo
    on Nov 15th, 2009 at 8:56 pm

    @Trent : i posted the script you need if it may help you : http://www.hypervisor.fr/?p=1379

  7. #7 yattong
    on Jul 20th, 2010 at 4:45 pm

    hey,

    I have been trying to run this against all vm’s, not just one but its seems to just give me a total of all vm’s rather than individual totals.

    any ideas?

  8. #8 Arnim van Lieshout
    on Jul 23rd, 2010 at 2:43 pm

    Hi Yattong,

    You could use:
    Get-VM | Select-Object Name,@{N=”Size”; E={Get-VmSize($_)/1GB}}

  9. #9 Trent
    on Jul 23rd, 2010 at 2:48 pm

    @ yattong

    You need to call this function inside a loop (and for each return, add it to a report).

    For instance, mine is modified to only pull snapshot size but I basically do:

    Write-Host “`Gathering info on $VIServer…”
    $VMWithSnaps = Get-VM | Get-Snapshot
    $VMWithSnapsGroup = $VMWithSnaps | Group-Object VM

    That gets me an array of VM’s with snapshots. Then I simply call this function from withing a loop and add it to my report array.

    $Report1 = @()
    $VMWithSnapsGroup | Foreach-Object {
    “do all the things I want it to do”
    $Report1 += $object

    Then at the end, I email myself the report.

    $HTMLReport = $Report1 | ConvertTo-Html
    send-SMTPmail $EmailTo $EmailFrom “Snapshots Exist” $SMTPSRV $HTMLReport

    I’m sure Nitro has a better way … I’m just a sys admin, not a programmer.

  10. #10 yattong
    on Jul 29th, 2010 at 12:19 pm

    thanks guys,

    (Using Nitro updated script)

    Tried so many different option, embedding foreach ($vm) into the same script but couldnt get it to work.

    In the end, created another script with
    $vms = get-vm
    foreach ($vm in $vms)
    {
    C:\getvmsize(“$vm”)
    }
    worked for me.

    just have to find out how to append the output to a report.
    thanks again.

  11. #11 Navil
    on Nov 12th, 2012 at 1:43 pm

    could someone please point me to the way how ouput data from (get-vmguest).disks to
    server1 disk1 capacity(Gb) free(Gb) free(%)
    server1 disk2 capacity(Gb) free(Gb) free(%)
    server1 disk3 capacity(Gb) free(Gb) free(%)
    server2 disk1 capacity(Gb) free(Gb) free(%)

    because right now it gives me:
    server1 disk1 capacity(Gb) free(Gb) disk2 capacity(Gb) free(Gb disk3 capacity(Gb) free(Gb)

  12. #12 Navil
    on Nov 14th, 2012 at 10:04 am

    #Done it like this:

    $Report= @()
    $AllVMs = Get-View -ViewType VirtualMachine | Where {-not $_.Config.Template}
    ForEach ($vm in $AllVMs){
    $vmDisks=$vm.Guest.Disk
    $name = $vm.Name
    ForEach ($disk in $vmDisks) {
    [double] $diskSize = $Disk.Capacity
    [double] $diskFreeSpace = $Disk.FreeSpace
    $diskSizeGB = [Math]::Round($diskSize / 1gb, 0) #disk size
    $diskFreeSpaceGB = [Math]::Round($diskFreeSpace / 1gb, 1) #disk size free
    $percentFree = [Math]::Round(($diskFreeSpaceGB/$diskSizeGB)*100,0)

    $Row = “” | Select-Object Name,Path,Capacity,Free,Free_p
    $Row.Name = $name
    $Row.Path = $Disk.DiskPath
    $Row.Capacity = $diskSizeGB
    $Row.Free = ($diskFreeSpaceGB)
    $Row.Free_p = ($percentFree)
    $Report += $Row

    }
    }
    $Report | Export-Csv “VMDiskSize.csv”
    $Report | format-table -auto

Leave a Comment