9 Replies Latest reply on Jun 11, 2012 5:26 PM by JasonHess

    Script to gather VM Name and Total Size on disk

    jamesbowling Master
    VMware Employees

      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!

        • 1. Re: Script to gather VM Name and Total Size on disk
          avlieshout Expert
          VMware Employees

          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

          1 person found this helpful
          • 2. Re: Script to gather VM Name and Total Size on disk
            jamesbowling Master
            VMware Employees

            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!

            • 3. Re: Script to gather VM Name and Total Size on disk
              RvdNieuwendijk Virtuoso
              vExpertUser Moderators

              Why don't you use:

               

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


              Regards, Robert

              • 4. Re: Script to gather VM Name and Total Size on disk
                jamesbowling Master
                VMware Employees

                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.

                • 5. Re: Script to gather VM Name and Total Size on disk
                  mattboren Master
                  vExpert

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

                  1 person found this helpful
                  • 6. Re: Script to gather VM Name and Total Size on disk
                    RvdNieuwendijk Virtuoso
                    User ModeratorsvExpert

                    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
                    
                    

                    • 7. Re: Script to gather VM Name and Total Size on disk
                      jamesbowling Master
                      VMware Employees

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

                      • 9. Re: Script to gather VM Name and Total Size on disk
                        JasonHess Novice

                        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!