jamesbowling
VMware Employee
VMware Employee

Script to gather VM Name and Total Size on disk

Jump to solution

I am trying to find a script that will output the following information:

  • VM Name
  • Total Size of VM (VMDKs)

I thought I saw one here before but can't seem to find it anywhere.  Any help would be greatly appreciated!

James B. | Blog: http://www.vSential.com | Twitter: @vSential --- If you found this helpful then please awards helpful or correct points accordingly. Thanks!
0 Kudos
1 Solution

Accepted Solutions
RvdNieuwendijk
Leadership
Leadership

You get the error message using the function because the function expects a VMware.VimAutomation.ViCore.Impl.V1.Inventory.VirtualMachineImpl object and you give it a VMware.Vim.VirtualMachine object. If you change your part of the code into:

# Connect to VIServer
Connect-VIServer $VIServer

#Initialise Array
$Report = @()

# Gather VM Size Information
    $AllVMs = Get-VM
    ForEach ($vm in $AllVMs){
            $Size = Get-VmSize($vm)
        }
        $Report += $Size

$Report | Export-Csv "C:\VMDiskSize.csv"

# Disconnect from VIServer
Disconnect-VIServer $VIServer -Confirm:$False

It will not give an error. But it will also not give the desired output as it will give you the total disk size of all virtual machines.

You will get the desired result with:

# Connect to VIServer
Connect-VIServer $VIServer

#Initialise Array
$Report = @()

# Gather VM Size Information
$AllVMs = Get-VM
ForEach ($vm in $AllVMs){
    $Row = "" | Select-Object VM,Size
    $Row.VM = $vm.Name
    $Row.Size = (Get-VmSize($vm))/1GB
    $Report += $Row
}

$Report | Export-Csv "C:\VMDiskSize.csv"

# Disconnect from VIServer
Disconnect-VIServer $VIServer -Confirm:$False

Blog: https://rvdnieuwendijk.com/ | Twitter: @rvdnieuwendijk | Author of: https://www.packtpub.com/virtualization-and-cloud/learning-powercli-second-edition

View solution in original post

0 Kudos
9 Replies
avlieshout
VMware Employee
VMware Employee

I wrote a function for this a while ago. Have a look at

http://www.van-lieshout.com/2009/07/how-big-is-my-vm/

Cheers,

Arnim

Arnim van Lieshout Blogging: http://www.van-lieshout.com Twitter: http://www.twitter.com/avlieshout If you find this information useful, please award points for "correct" or "helpful".
jamesbowling
VMware Employee
VMware Employee

Not sure if I am using this correctly but here is the script that was put together using your function:

#Global Functions
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
}

# Connect to VIServer
Connect-VIServer $VIServer

#Initialise Array
$Report = @()

# Gather VM Size Information
    $AllVMs = Get-View -ViewType VirtualMachine | Where {-not $_.Config.Template}
    ForEach ($vm in $AllVMs){
            $Size = Get-VmSize($vm)
        }
        $Report += $Size

$Report | Export-Csv "C:\VMDiskSize.csv"

# Disconnect from VIServer
Disconnect-VIServer $VIServer -Confirm:$False

When I run it I get the following error:

Cannot bind parameter 'VIObject'. Cannot convert the "VMware.Vim.VirtualMachine" value of type "VMware.Vim.VirtualMachine" to type "VMware.VimAutomation.Sdk.Types.V1.VIObject".
At :line:17 char:22
+     Get-View -VIObject <<<<  $vm | % {

Thanks for your help on this!

James B. | Blog: http://www.vSential.com | Twitter: @vSential --- If you found this helpful then please awards helpful or correct points accordingly. Thanks!
0 Kudos
RvdNieuwendijk
Leadership
Leadership

Why don't you use:

Get-VM | Select-Object Name,UsedSpaceGB | Export-Csv "C:\VMDiskSize.csv"


Regards, Robert

Blog: https://rvdnieuwendijk.com/ | Twitter: @rvdnieuwendijk | Author of: https://www.packtpub.com/virtualization-and-cloud/learning-powercli-second-edition
0 Kudos
jamesbowling
VMware Employee
VMware Employee

This doesn't return what I need.  When I run that, it actually returns -1 for everything.  I forgot to mention that this is querying against a 3.5 deployment and not 4.X.

James B. | Blog: http://www.vSential.com | Twitter: @vSential --- If you found this helpful then please awards helpful or correct points accordingly. Thanks!
0 Kudos
mattboren
Expert
Expert

Hey, @jamesbowling-

Looks like the function Get-VMSize is expecting a VM object (as returned by Get-VM) instead of the VirtualMachine View object that you are passing to it.  The line

Get-View -VIObject $vm | % {...

tries to get the View object from the parameter "$vm".  So, you could either update that line in the function to just pipe the View object that you are passing like:

$vm | %{...

or you could adjust the way that you are using the function to pass it VM objects instead of View objects.  I would go with the former (pass View objects to the function, update the function to accept/use them) for the sake of speed (should run far quicker when using the View objects versus using Get-VM).

Oh, and for the sake of reading/understanding code later, maybe rename the $vm variable to $viewVM or something, so as to hint at the object type...

RvdNieuwendijk
Leadership
Leadership

You get the error message using the function because the function expects a VMware.VimAutomation.ViCore.Impl.V1.Inventory.VirtualMachineImpl object and you give it a VMware.Vim.VirtualMachine object. If you change your part of the code into:

# Connect to VIServer
Connect-VIServer $VIServer

#Initialise Array
$Report = @()

# Gather VM Size Information
    $AllVMs = Get-VM
    ForEach ($vm in $AllVMs){
            $Size = Get-VmSize($vm)
        }
        $Report += $Size

$Report | Export-Csv "C:\VMDiskSize.csv"

# Disconnect from VIServer
Disconnect-VIServer $VIServer -Confirm:$False

It will not give an error. But it will also not give the desired output as it will give you the total disk size of all virtual machines.

You will get the desired result with:

# Connect to VIServer
Connect-VIServer $VIServer

#Initialise Array
$Report = @()

# Gather VM Size Information
$AllVMs = Get-VM
ForEach ($vm in $AllVMs){
    $Row = "" | Select-Object VM,Size
    $Row.VM = $vm.Name
    $Row.Size = (Get-VmSize($vm))/1GB
    $Report += $Row
}

$Report | Export-Csv "C:\VMDiskSize.csv"

# Disconnect from VIServer
Disconnect-VIServer $VIServer -Confirm:$False

Blog: https://rvdnieuwendijk.com/ | Twitter: @rvdnieuwendijk | Author of: https://www.packtpub.com/virtualization-and-cloud/learning-powercli-second-edition
0 Kudos
jamesbowling
VMware Employee
VMware Employee

Thanks for the quick replies!  It is working correctly now.  Thanks for your help!

James B. | Blog: http://www.vSential.com | Twitter: @vSential --- If you found this helpful then please awards helpful or correct points accordingly. Thanks!
0 Kudos
RvdNieuwendijk
Leadership
Leadership

You're welcome.

Blog: https://rvdnieuwendijk.com/ | Twitter: @rvdnieuwendijk | Author of: https://www.packtpub.com/virtualization-and-cloud/learning-powercli-second-edition
0 Kudos
JasonHess
Contributor
Contributor

How could you do this for just a list of VM's?

I know how to import a csv and key off of it, but I can't get the array/string stuff right... It works great agaist the whole vcenter though.

Thanks!

0 Kudos