Identifying Uncommitted Space culprits with PowerCLI

Note: A bit more testing on my end has found this script is only valuable if your VMDKs are on separate datastores. I am working to find a better metric to pull the data per VMDK.

Background

Have you ever heard of “Uncommitted Space” in vSphere? It's one of those things we all seem to ‘know’ without really knowing. It's a pretty standard metric most commonly found against vSphere Datastores. It's effectively calculated based on the provisioned and used storage of a datastore and its contents. However, many customers will run reports to identify uncommitted space values for their datastores but don't have any way of identifying the offending VMs and VMDKs that are contributing to this value.

In this post, I will share a very rough PowerCLI script that, when pointed to a VM, will tell you the uncommitted space value of not just the VM as a whole, but each VMDK attached to it. Skip to the end if you want it now, otherwise read on to find out how it works and if it's right for you.

What makes up the uncommitted space value? As with all things, it depends. Let's take an average VM configuration: 2 vCPU and 4GB RAM, with a 60GB “OS drive” and maybe a 200GB “Data Drive” (Hard Disk 1 and Hard Disk 2, respectively). Let's assume you left the vSphere defaults during VM creation so the VM will not have any memory reserved, nor will it have any additional virtual hardware (passed through devices etc). Let's also assume the VMDKs have been thin provisioned.

The “Uncommitted Space” of this VM is the “ProvisionedGB” metric minus the “UsedGB” metric.

“Provisioned” is the sum of capacity of all VMDKs attached to the VMDK, plus the memory allocation and any additional VM files (logs, vmx file, etc) and any snapshot deltas (if any). The memory allocation is used to estimate the swap file size of the VM when it's running. This storage is all considered “Provisioned” against the datastore to avoid a situation where the datastore is full of VMDKs, with no capacity for VM swap files, subsequently preventing any of the VMs from powering on. You can see how that's an issue.

“Used” is the sum of storage that has been actively written to or pre-allocated and reserved on the datastore for the VM. In the case of our example VM “Used” is the amount of data written to a thin-provisioned disk, which doesn't necessarily match the allocated capacity of a disk (unless you've filled the disk or previously written to it and not returned the blocks via an unmap capability).

I've provisioned a test VM with the following resources:

  • 1 x vCPU
  • 1GB Memory (no reservation)
  • 1 x 20GB OS Disk aka “Hard Disk 1” on “Datastore-A”
  • 1 x 20GB Data Disk aka “Hard Disk 2” on “Datastore-B”

Note: The VM files (vmx, logs, etc) will be stored on Datastore-A alongside “Hard Disk 1” (the OS disk).

Stock standard configuration, maybe a little on the small side. But these a good numbers to see how it behaves. The OS disk will have Windows Server installed, and the data disk will be empty so I can highlight the differences between thin and thick disks that contain no data. I will use the output of my PowerCLI script to highlight these differences.

Thin-provisioned, no reservation, powered off

OK, first, let's take a look at the uncommitted space reported for the VM while it's powered off:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
vmName: thinwindows
--- VM Name: thinwindows ---
Memory: 1GB
Total Provisioned: 41.21
Total Uncommitted space: 32.56GB
Hard disk break down
--- Disk name: Hard disk 1 ---
Storage Format: Thin
Provisioned Capacity: 20GB
--- Disk name: Hard disk 2 ---
Storage Format: Thin
Provisioned Capacity: 20GB
Uncommitted space per VMDK
--- thinwindows is spread across 2 datastores. ---
Searching Datastore Datastore-A
Disk: thinwindows.vmdk
Provisioned: 21.21GB
Uncommitted: 12.56GB
Searching Datastore Datastore-B
Disk: thinwindows_1.vmdk
Provisioned: 20GB
Uncommitted: 20GB

Take a look at those highlighted lines. They show the Provisioned and Uncommitted values of the reported VMDK. The first disk in this list shows 21.21GB Provisioned. Of the 1.21 GB over the VMDK allocated 20 GB, 1 GB is due to the space reserved for the potential of a VM swap file while the remaining ~210 MB is left for the VMX file, log files and other goodies that make up the VM. Uncommitted is showing 12.56 GB. It helps to think of this as the allocated but unused capacity. Let's compare this number to the Guest OS volume:

thin-guest-disk-1

Slightly off, but let's do the math. Total Space - Free Space = Guest Used or 19.6 GB - 10.9 GB = 8.7GB. Right, so the Windows install is at 8.7GB. Stay with me here: the 10.9 GB of remaining space is not far off the Uncommitted value of 12.56GB. Keep in mind, uncommitted includes the 1.21 GB of extras which really leaves us with 11.35 GB. Looks off, but if we switch this around: 20 GB allocated - 8.7 GB used = 11.30 GB. That's awfully close to our Uncommitted value (minus the 1.21 GB extras). So we've figured out this number is almost exact. There's quite possibly some extra bits I've missed here but I'll figure it out and update the post.

Thin-provisioned, no reservation, powered on

Now that the machine is powered on, let's run my script again and go through the output:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
vmName: thinwindows
--- VM Name: thinwindows ---
Memory: 1GB
Total Provisioned: 41.08
Total Uncommitted space: 31.35GB
Hard disk break down
--- Disk name: Hard disk 1 ---
Storage Format: Thin
Provisioned Capacity: 20GB
--- Disk name: Hard disk 2 ---
Storage Format: Thin
Provisioned Capacity: 20GB
Uncommitted space per VMDK
--- thinwindows is spread across 2 datastores. ---
Searching Datastore Datastore-A
Disk: windows.vmdk
Provisioned: 21.08GB
Uncommitted: 11.35GB
Searching Datastore Datastore-B
Disk: windows_1.vmdk
Provisioned: 20GB
Uncommitted: 20GB

Now we're seeing some changes. The Provisioned has changed a little bit. The ‘extras’ on top have shrunk to 1.08 GB. Uncommitted has dropped by 1.21 GB compared to the powered off uncommitted value. That number rings a bell, doesn't it? ESXi no longer has to ‘set aside’ an estimate storage for a swap file or overheads as the VM is powered on and it knows exactly what needs to be set aside. That new amount is 1.08 GB.

Let's quickly compare to eager and lazy thick

Thick Eager provisioned, no reservation, powered off

Let's have a look at the same VM but with both disks converted to Thick Eager Provisioned disks:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
vmName: thinwindows
--- VM Name: thinwindows ---
Memory: 1GB
Total Provisioned: 41.21
Total Uncommitted space: 1.21GB
Hard disk break down
--- Disk name: Hard disk 1 ---
Storage Format: EagerZeroedThick
Provisioned Capacity: 20GB
--- Disk name: Hard disk 2 ---
Storage Format: EagerZeroedThick
Provisioned Capacity: 20GB
Uncommitted space per VMDK
--- thinwindows is spread across 2 datastores. ---
Searching Datastore Datastore-A
Disk: thinwindows.vmdk
Provisioned: 21.21GB
Uncommitted: 1.21GB
Searching Datastore Datastore-B
Disk: thinwindows_1.vmdk
Provisioned: 20GB
Uncommitted: 0GB

Well, well, well. We've confirmed the ‘set-aside’ value of 1.21 GB while the VM is powered off. What about powered on?

Thick Eager provisioned, no reservation, powered on

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
vmName: thinwindows
--- VM Name: thinwindows ---
Memory: 1GB
Total Provisioned: 41.08
Total Uncommitted space: 0.00GB
Hard disk break down
--- Disk name: Hard disk 1 ---
Storage Format: EagerZeroedThick
Provisioned Capacity: 20GB
--- Disk name: Hard disk 2 ---
Storage Format: EagerZeroedThick
Provisioned Capacity: 20GB
Uncommitted space per VMDK
--- thinwindows is spread across 2 datastores. ---
Searching Datastore Datastore-A
Disk: thinwindows.vmdk
Provisioned: 21.08GB
Uncommitted: 0GB
Searching Datastore Datastore-B
Disk: thinwindows_1.vmdk
Provisioned: 20GB
Uncommitted: 0GB

Cool! You can see the uncommitted space has now gone to 0 GB for both disks. Even the Provisioned amount reduced as ESXi has corrected the amount ‘set aside’ for running the VM.

The script

Right, so how am I getting this info? Well, my script below is poorly thrown together to get an MVP. Obviously I could clean it up to return a decent table of information but I wanted to get this out there for the community.

The script (quite inefficiently I'll admit) scans through all datastores looking for any VMDKs that are attached to the VM. From there, it can poll the DiskFile properties to get Committed and Uncommitted values. I can probably refine this but time is short :(.

If you have any questions, feedback or suggestions please ask away in the comments.

Code