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.
Is there anyway to get the actual size used for each individual VMDK?
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
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.
Thanks Mark. I guess Ill keep playing with it.
Jim
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
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 :)
Pleasure!
Mark,
Can you share what changes if any you made? Ive been too busy to get back to it today, but its on my short list to address this week.
Jim
Hi Jim,
I have not amended the script at all. To test it further I even copied it from the blog and ran it without “| Sort VM | Export-Csv -Path “D:Thin_Disks.csv”” in the last line. All worked just fine.
I also noticed I need to amend “| Sort VM” to “| Sort Name”… Will update the post.
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.
Hi,
The scrip uses straight forward export to CSRV file. I guess, it is Comma Separated. The VMDKs field (cell) contains a list of VM’s vmdk files, one per line.
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)
I also get a blank CSV file. We are on ESX version 5.5 update 1. Maybe that is the issue?
Jason,
I am also on vSphere 5.5. My CSV file started populating once I added Device ID to the script.
Jim
Hi Jim,
Where exactly in the script did you add the Device ID?
Thanks
Hi Mark…
i have one issue ..i am writing the python script ..
“I WANT TO RETURN THE HARD DISK PROVISION TYPE –MEANS ITS THICK OR THIN LAZY ZEROED OF VM MACHINE–
IS THERE ANY COOMAD TO THAT..?
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).
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
The Script from here is working with 5.1: http://www.null-byte.org/development/vmware-powercli-get-all-thick-provisioned-disks/
I don’t know why $view.config.hardware.Device.Backing ist not working and why […] $_.Backing.ThinProvisioned is working, but it does!
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
My csv is blank can you help?
actually can i get this info for thick and thin?
Hi Jack,
See message from 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”
Thank you Mark I will give that a try.
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
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.
Hi Jonathan,
You are absolutely right. The script needs to be worked on to address these configurations.
great script for its original intent – ez to modify for customizations on a per user basis.. Thanks Mark for the support..
can you adapt the script so it can list out all the vm’s with a eager zeroed disk?
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?
Yes, it does. I have just tested it on vCenter 5.1 Build 947673
I use PowerGui 3.8.0.219 and vSphere PowerCLI 5.5.0.6579
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?
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.
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?
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
I have upgraded my PowerCLI version to 5.8, still am facing the issue of balnk CSV.
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
can you choose a certain datastore name to only pull from or for a certain cluster to reduce the number of records?
Yes, you can. Play with $vm in “Get-VM” and use “Get-Cluster -Name MYCLUSTER | Get-VM” or “Get-Datastore -Name MyDATASTORE | Get-VM“
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
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
> 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.
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
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.
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 “;”
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?
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
Thank you for this, I was wondering how hard it would be to add the cluster name for each VM?
Get-VM | where{(Get-HardDisk -VM $_ ).StorageFormat -contains ‘Thin’}
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.