Visitors

VMware PowerCLI script to list Thin provisioned virtual disks (VMDK)

One of my clients was concerned about the number of virtual machines that were built with Thin provisioned disks. Before they go with the project to inflate all Thin provisioned disks (or migrate to Thick Provisioned Lazy Zeroed) they needed to know how much additional storage they would need.

PowerCLI to the rescue!

Yes, you can run ‘Get-VM | Select Name, ProvisionedSpaceGB, UsedSpaceGB‘ but, strictly speaking, it will not give you a clear picture.
ProvisionedSpaceGB – the total size of the VM: virtual disks (VMDK files) + snapshots + memory swap (if not reserved) + logs etc.
UsedSpaceGB – how much disk space is actually used by the VM.

The following script will identify all virtual machines with at least one thin provisioned disk, calculate the total size of configured virtual disks and then create a report of the disk usage and list all virtual disks helping you to identify which one of them is thin provisioned:

$report = @()
foreach ($vm in Get-VM){
 $view = Get-View $vm
   if ($view.config.hardware.Device.Backing.ThinProvisioned -eq $true){
   $row = '' | select Name, Provisioned, Total, Used, VMDKs, Thin
      $row.Name = $vm.Name
      $row.Provisioned = [math]::round($vm.ProvisionedSpaceGB , 2)
      $row.Total = [math]::round(($view.config.hardware.Device | Measure-Object CapacityInKB -Sum).sum/1048576 , 2)
      $row.Used = [math]::round($vm.UsedSpaceGB , 2)
      $row.VMDKs = $view.config.hardware.Device.Backing.Filename | Out-String
      $row.Thin = $view.config.hardware.Device.Backing.ThinProvisioned | Out-String
   $report += $row
}}
$report | Sort Name | Export-Csv -Path "D:Thin_Disks.csv"

Here is the example of the output:

Name Provisioned Total Used VMDKs Thin
Mgr05 52.06 50 26.78 [Datastore_02_GOLD] Mgr05/Mgr05.vmdk
[Datastore_02_GOLD] Mgr05/Mgr05_1.vmdk
True
True
SQL-009 1004.07 996 1000.94 [Datastore_318_BRONZE] SQL-009/SQL-009.vmdk
[Datastore_316_BRONZE] SQL-009/SQL-009.vmdk
[Datastore_319_BRONZE] SQL-009/SQL-009.vmdk
[Datastore_306_BRONZE] SQL-009/SQL-009.vmdk
True
True
False
False
DC01 185.05 181 30.15 [Datastore_17_GOLD] DC01/DC01.vmdk
[Datastore_17_GOLD] DC01/DC01_1.vmdk
[Datastore_17_GOLD] DC01/DC01_2.vmdk
True
False
True

UPDATE:

If you need to include the size used for each disk:

$report = @()
foreach ($vm in Get-VM){
$view = Get-View $vm
if ($view.config.hardware.Device.Backing.ThinProvisioned -eq $true){
$row = '' | select Name, Provisioned, Total, Used, VMDKs, VMDKsize, DiskUsed, Thin
    $row.Name = $vm.Name
    $row.Provisioned = [math]::round($vm.ProvisionedSpaceGB , 2)
    $row.Total = [math]::round(($view.config.hardware.Device | Measure-Object CapacityInKB -Sum).sum/1048576 , 2)
    $row.Used = [math]::round($vm.UsedSpaceGB , 2)
    $row.VMDKs = $view.config.hardware.Device.Backing.Filename | Out-String
    $row.VMDKsize = $view.config.hardware.Device | where {$_.GetType().name -eq 'VirtualDisk'} | ForEach-Object {($_.capacityinKB)/1048576} | Out-String
    $row.DiskUsed = $vm.Extensiondata.Guest.Disk | ForEach-Object {[math]::round( ($_.Capacity - $_.FreeSpace)/1048576/1024, 2 )} | Out-String
    $row.Thin = $view.config.hardware.Device.Backing.ThinProvisioned | Out-String
$report += $row
}}
$report | Sort Name | Export-Csv -Path "D:Thin_Disks.csv"

Here is the output:

Name Provisioned Total Used VMDKs VMDKsize DiskUsed Thin
My_Thin_VM 185.06 181 31.36 [DATASTORE_01] My_Thin_VM/My_Thin_VM.vmdk
[DATASTORE_01] My_Thin_VM/My_Thin_VM_1.vmdk
[DATASTORE_01] My_Thin_VM/My_Thin_VM_2.vmdk
41
40
100
27.85
1.15
0.09
True
True
True

Hope this helps.

62 comments to VMware PowerCLI script to list Thin provisioned virtual disks (VMDK)

  • Is there anyway to get the actual size used for each individual VMDK?

  • Alexandre Pitre

    Wondering the same thing than Spencer

  • Apologies for the delay, here are the amendments to the script:
    1) Line 5: $row = “” | select Name, Provisioned, Total, Used, VMDKs, VMDKsize, DiskUsed, Thin
    2) Add these two lines after Line 10:
    $row.VMDKsize = $view.config.hardware.Device | where {$_.GetType().name -eq ‘VirtualDisk’} | ForEach-Object {($_.capacityinKB)/1048576} | Out-String
    $row.DiskUsed = $vm.Extensiondata.Guest.Disk | ForEach-Object {[math]::round( ($_.Capacity – $_.FreeSpace)/1048576/1024, 2 )} | Out-String

  • Jim T

    Hey Mark, Quick question about your script.

    I’m new to PowerCLI. I could not get it to run successfully as written, (No items added to CSV file, including headers). After digging around and playing with it I had to change lines and 13 to have the Device ID after Device name. In the Machines I checked that’s where the Virtual disk was located.

    $view.config.hardware.Device[12].Backing.ThinProvisioned

    However, It seems the script when run this way misses some servers that have Thin Provisioned Disks. Am I missing something here?

  • Hi Jim,
    I double checked the script and it works OK for me.
    The “if ($view.config.hardware.Device.Backing.ThinProvisioned -eq $true){” statements selects only Thin Provisioned devices which can only be virtual disks.

  • Hi Mark – I am having similar issues to Jim and getting a blank report produced. Are there any prerequisites that need to be met? How can I manually check the variable to see if it exists and is populated within my database?

    • Hi Mark,
      The easiest way to test the script is to create a variable(s) and then play with it like this:
      My_Test_VM – a VM with at least one Thin Disk
      $vm = Get-VM My_Test_VM
      $view = Get-View $vm
      and then run:
      $view.config.hardware.Device.Backing.ThinProvisioned
      $view.config.hardware.Device
      $view.config.hardware.Device.Backing.Filename
      $view.config.hardware.Device | where {$_.GetType().name -eq ‘VirtualDisk’}
      etc, etc

  • Jim T

    Mark,
    Ive been using PowerGUI to work on the script. You will need to add the VMware Powershell Libraries. Once there you can try opening and running the scripts. Then look in the variables window and start expanding it out and you can find the variable info you are looking for. That’s how I found that my device ID for the Virtual disk was 12.

    Jim

  • Thanks chaps… managed to get it working with your help! keep up the good work :)

  • Hello Mark,
    What type of delimiter do you use in Excel for csv file? I am asking because I have problem with categorization of the information when I reach “VMDKs” tab. Each datastore is on different box instead of being in one and the same.

  • I want to take this the opposite direction! I’d love to take all VMs in a cluster, identify those with thick provisioned VMDK, and demonstrate potential savings by converting them to thin.

    • Hi,
      Here is the clue for you:
      $vm = Get-VM -Name My_Thick_VM
      #DiskGB
      [Math]::Round((($vm.HardDisks | Measure-Object -Property CapacityKB -Sum).Sum * 1KB / 1GB),2)
      #DiskFree
      [Math]::Round((($vm.Guest.Disks | Measure-Object -Property FreeSpace -Sum).Sum / 1GB),2)

  • Jason M

    I also get a blank CSV file. We are on ESX version 5.5 update 1. Maybe that is the issue?

  • Anil

    Hi Mark,

    Even I am also getting the blank CSV file.

    Hi Tim,

    Could you please share what changes you have done.

    • It is really strange. I tested the script in my vSphere 5.5 environment (vCenter 1750596, ESXi build 1746974) and it worked absolutely fine.
      I use PowerGUI and the latest version of PowerCLI (Build 1931983).

  • John bons

    The blank issue is because of the powercli version
    PowerCLI 5.5 Release 1 build 1295336 is working
    PowerCLI 5.1 Release 1 build 793510 is not working aka blank csv $view.config.hardware.Device.Backing is not available in this version

  • Basem

    Hello,

    Thank you for this script. How can i get total Disk for all VMs ?

    Any help will be highly appreciated.

    Basem

    • Hi Basem,
      You can declare a variable $totalVMDKsize = 0 and then right at the end of the loop, after $report += $row add $totalVMDKsize = $totalVMDKsize + $row.Total
      $totalVMDKsize will take the total Disk for all VMs that have thin provisioned disk(s)
      You can also add the total used disk space… $totalVMDKsizeUSED = 0, $totalVMDKsizeUSED = $totalVMDKsizeUSED + $row.used
      Regards
      Mark

  • Jack

    My csv is blank can you help?

  • Jack

    Here is what I really need and let me know if this is crazy :)
    I need to know the total datastore size > vm total size (including swap, etc) > os file system size (linux and windows) > and then calculate how mush OS is allocated inside the vmdk then to datastore

  • Andy

    Exactly what I looked for. Can I manage it somehow to get every single vmdk in a seperate line instead of a linebreak in the cell?

  • There is an assumption being made here that can cause the script to fail. You’re assuming that your VMDK are 1:1 mapped to active partitions. If you have 2 partitions on a single VMDK, or use linux LVM then the $view.config.hardware.Device.Virtual Disk.capacityInKB won’t have the same number of entries as $vm.Extensiondata.Guest.Disk.Capacity. In windows, it’s not as common to see this assumption being wrong. However in linux systems it can happen quite frequently to accommodate hot-extending a lun more than a few times or creating a mount point greater than 2TB prior to VMware 5.5.

  • Pat R.

    great script for its original intent – ez to modify for customizations on a per user basis.. Thanks Mark for the support..

  • Steve

    can you adapt the script so it can list out all the vm’s with a eager zeroed disk?

  • Shantanu

    Does this script also run with vSphere 5.1? coz am still getting blank csv file, even after upgrading PowerCLI version to 5.5 R 1?

  • Shantanu

    Hi Mark,
    As mentioned in my earlier post both PowerCLI & Power GUI are updated with the versions mentioned by you.
    On troubleshooting further I fond that the script fails to return value when I pass the string $view.config.hardware.Device.Backing, till Device it throws up output bun when I add .backing it throws blank output.
    Can you help me troubleshooting this?

  • Paul Sheard

    I’m using VMware vSphereCLI 5.5 Release 2 Patch 1 and I get the BLANK.CSV… any ideas on using this great script with this version of vSphereCLI

    • Hi Paul,
      You need to download and install the latest VMware PowerCLI. I use vSphere PowerCLI 5.5.0.6579 with PowerGui 3.8.0.219.

    • Hi Paul, I have just upgraded VMware PowerCLI to 5.8 build 6734 and tested the script. It worked OK.

      • Paul Sheard

        Hi mark, thanks for your reply’s and testing.. very strange in how this still gives me a blank.csv?? My version of PowerGUI is 3.8.0.129 btw..

        Are you simply pasting the script in to the PowerGUI editor window Mark and then executing it?

        • Yes, I though the HTML formatting may interfere with the script syntax and to test that I simply copied the script off the web site. All worked for me.
          Could you check PowerCLI version for me please?

          • Paul Sheard

            vSphere PowerCLI? 5.5 Release 2 Patch 1 if thats the case.. I’m just trying to download the VMware power packs for PowerGUI.. so I can connect it to our vCenter

        • Shantanu

          I have upgraded my PowerCLI version to 5.8, still am facing the issue of balnk CSV.

  • KT

    Blank csv file here as well… version info below:
    PowerCLI Version
    —————-
    VMware vSphere PowerCLI 5.8 Release 1 build 2057893
    —————
    Snapin Versions
    —————
    VMWare AutoDeploy PowerCLI Component 5.5 build 1983942
    VMWare ImageBuilder PowerCLI Component 5.5 build 1983942
    VMware License PowerCLI Component 5.5 build 1265954
    VMware Storage PowerCLI Component 5.8 build 2057894
    VMware VDS PowerCLI Component 5.8 build 2031581
    VMware vSphere PowerCLI Component 5.8 build 2031581

  • Lou

    can you choose a certain datastore name to only pull from or for a certain cluster to reduce the number of records?

  • Edson

    I have upgraded my PowerCLI version to 5.8 Release 1 build 2057893, still am facing the issue of balnk CSV

    PowerCLI C:> Get-VIToolkitVersion

    PowerCLI Version
    —————-
    VMware vSphere PowerCLI 5.8 Release 1 build 2057893
    —————
    Snapin Versions
    —————
    VMWare AutoDeploy PowerCLI Component 5.5 build 1983942
    VMWare ImageBuilder PowerCLI Component 5.5 build 1983942
    VMware License PowerCLI Component 5.5 build 1265954
    VMware Storage PowerCLI Component 5.8 build 2057894
    VMware VDS PowerCLI Component 5.8 build 2031581
    VMware vSphere PowerCLI Component 5.8 build 2031581

  • Michal

    Hi Mark, How to split cell into separate cells?

    Basicaly I just need
    VMDKs, VMDKsize, DiskUsed,Thin
    but in separate row for each vmdk.

    Thanks

  • Arild Skullerud

    > I have upgraded my PowerCLI version to 5.8 Release 1 build 2057893, still am facing the issue of blank CSV

    Same problem here. Have libraries in place. Turned off certificate check. Run in PowerGUI V 3.8. Have PowerCLI 5.8 Release 1 build 2057893 installed.

  • Arild Skullerud

    More info. I use your updated script + this line to connect to the server:
    #Add snapin for runing at command line.
    #add-pssnapin VMware.VimAutomation.Core

    #connect to server
    Connect-VIServer “MYSERVER.SYS.COM” -User Administrator -Password MYPASSWORD

  • Arild Skullerud

    Hm. There seems to be a problem with how the script identifies the VM ID.
    Get-VM liste my servers like this:
    VSNVP2-44_Domino_… PoweredOn 2 4,000
    OCLVA_Arkiv_LUN2-218 PoweredOn 4 8,000
    The first server has a very long name. Thus the 3 …, but even is I try
    Get-View OCLVA_Arkiv_LUN2-218 my output gives errors like this:

    Get-View : 10.04.2015 12:08:27 Get-View View with Id ‘OCLVA_Arkiv_LU
    N2-218’ was not found on the server(s).
    At line:1 char:9
    + Get-View <<<< OCLVA_Arkiv_LUN2-218
    + CategoryInfo : ObjectNotFound: (:) [Get-View], VimException
    + FullyQualifiedErrorId : Core_GetView_WriteNotFoundError,VMware.VimAutoma
    tion.ViCore.Cmdlets.Commands.DotNetInterop.GetVIView

    So it seems like the script sees no servers and can not populate the CSV.

  • compendius

    Here is a oneliner I use that is very fast

    Get-View -ViewType “VirtualMachine” -Property @(“Config.hardware.device”) `
    | select @{N=”chd”;E={$_.config.hardware.device}} `
    | %{$_.chd | select @{N=”chdbf”;E={$_.backing.filename}},@{N=”chdbt”;E={$_.backing.thinprovisioned}} `
    | where {$_.chdbt -eq $true}} `
    | Export-Csv “./thin.csv” -NoTypeInformation -UseCulture

  • Hi, i changed the script a little bit.

    $report = @()
    foreach ($vm in Get-VM){
    $view = Get-View $vm
    $thinProvisionState = $view.config.hardware.device | where{$_.Backing -match “VMware.Vim.VirtualDiskFlatVer2BackingInfo”} | select -expand Backing | select -expand ThinProvisioned
    if ($thinProvisionState -eq $true){
    $row = $row = ” | select Name, Provisioned, Total, Used, VMDKs, VMDKsize, DiskUsed, Thin
    $row.Name = $vm.Name
    $row.Provisioned = [math]::round($vm.ProvisionedSpaceGB , 2)
    $row.Total = [math]::round(($view.config.hardware.Device | Measure-Object CapacityInKB -Sum).sum/1048576 , 2)
    $row.Used = [math]::round($vm.UsedSpaceGB , 2)
    $row.VMDKs = $view.config.hardware.Device.Backing.Filename | Out-String
    $row.VMDKsize = $view.config.hardware.Device | where {$_.GetType().name -eq ‘VirtualDisk’} | ForEach-Object {($_.capacityinKB)/1048576} | Out-String
    $row.DiskUsed = $vm.Extensiondata.Guest.Disk | ForEach-Object {[math]::round( ($_.Capacity – $_.FreeSpace)/1048576/1024, 2 )} | Out-String
    $row.Thin = $view.config.hardware.Device.Backing.ThinProvisioned | Out-String
    $report += $row
    }}
    $report
    $report | Sort Name | Export-Csv -Path “c:tempThin_Disks.csv” -delimiter “;”

  • Brian

    Hi thanks for a great post :)

    Im working on pulling information about every vmdk a vm contains, and the thin provisioned is really tricky.
    The $vm.Extensiondata.Guest.Disk gives what vmware tools report, but in reality in the datastorebrowser the size can be bigger.

    Is there a solution for getting the content of datastorebrowser with filesize?

  • Krishna

    I need to get SCSI controller ID of a Hard Disk. i.e Virtual Device Node drop down list value like SCSI(0:0) Hard disk1

  • Chopper3

    Thank you for this, I was wondering how hard it would be to add the cluster name for each VM?

  • Runar

    Get-VM | where{(Get-HardDisk -VM $_ ).StorageFormat -contains ‘Thin’}

  • crayd

    The second script which reports size for each disk runs fine for me but the output has issues. The two parameters ($view.config.hardware.Device and $vm.Extensiondata.Guest.Disk) do not necessarily list objects in the same order. The capacity and filename do not always belong to the same disk as the calculated used space.

Leave a Reply

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

  

  

  

This site uses Akismet to reduce spam. Learn how your comment data is processed.