How to Shrink VMware VMDK Disk Files Programmatically: A Step-by-Step Guide


2 views

When working with VMware virtual machines, we often create generously sized VMDK files initially, only to realize later that much of that space goes unused. The process of reclaiming this space isn't as straightforward as one might hope, especially when dealing with:

  • Thick-provisioned disks
  • Snapshots and disk chains
  • OS-level fragmentation

Before attempting any disk operations, ensure:


1. No snapshots exist for the VM
2. The VM is powered off
3. You have sufficient free space for temporary files
4. You've backed up critical data

Here's how to programmatically reduce your VMDK size:

1. Zero Out Free Space (Linux)


dd if=/dev/zero of=/zero.file bs=1M
sync
rm /zero.file

2. Use VMware Tools (Windows)

For Windows VMs, use the disk cleanup utility:


"C:\\Program Files\\VMware\\VMware Tools\\VMwareToolboxCmd.exe" disk shrinkonly

3. Execute vmkfstools Command

The core shrinking operation:


vmkfstools --punchzero mydisk.vmdk
vmkfstools --extendvirtualdisk 50G --diskformat thin mydisk.vmdk

For regular maintenance, consider this Python script:


import subprocess
import os

def shrink_vmdk(vmdk_path, new_size_gb):
    # Zero out space (Linux example)
    if os.path.exists("/.dockerenv"):  # Detect VM environment
        subprocess.run(["dd", "if=/dev/zero", "of=/zero.file", "bs=1M"])
        subprocess.run(["sync"])
        os.remove("/zero.file")
    
    # Shrink operation
    subprocess.run([
        "vmkfstools",
        "--punchzero",
        vmdk_path
    ])
    
    # Resize to new dimensions
    subprocess.run([
        "vmkfstools",
        "--extendvirtualdisk",
        f"{new_size_gb}G",
        "--diskformat",
        "thin",
        vmdk_path
    ])

if __name__ == "__main__":
    shrink_vmdk("/vmfs/volumes/datastore1/VM/mydisk.vmdk", 50)

When encountering errors:

  • "Device or resource busy" - Ensure all snapshots are removed
  • "Insufficient space" - Check temporary storage requirements
  • "Invalid disk format" - Convert to thin-provisioned first

When working with VMware virtual machines, you'll encounter two primary disk file formats: VMDK (Virtual Machine Disk) and VHD (Virtual Hard Disk). The process of shrinking these files differs based on their type and allocation method (thin provisioned vs. thick provisioned).

Before attempting to resize your VMDK:

  • Ensure you have a complete backup
  • Verify disk type with: vmware-vdiskmanager -q /path/to/disk.vmdk
  • Defragment the guest OS disk
  • Zero out free space (for Linux: dd if=/dev/zero of=/zero.file bs=1M; rm /zero.file)

The native VMware tool provides disk management capabilities:

vmware-vdiskmanager -k disk.vmdk
# For explicit size reduction:
vmware-vdiskmanager -r old.vmdk -s 50GB new.vmdk

For Windows environments with PowerCLI installed:

Connect-VIServer -Server your_vcenter
Get-HardDisk -VM "YourVM" | Set-HardDisk -CapacityGB 50 -Confirm:$false

Using pyvmomi (VMware vSphere API Python Bindings):

from pyVim.connect import SmartConnect
from pyVmomi import vim

si = SmartConnect(host="vcenter", user="admin", pwd="password")
vm = si.content.searchIndex.FindByInventoryPath("YourVM")
disk = vm.config.hardware.device[0]  # First disk
spec = vim.vm.ConfigSpec()
spec.deviceChange = [vim.vm.device.VirtualDeviceSpec(
    device=disk,
    operation=vim.vm.device.VirtualDeviceSpec.Operation.edit,
    fileOperation=vim.vm.device.VirtualDeviceSpec.FileOperation.replace
)]
spec.deviceChange[0].device.capacityInKB = 50 * 1024 * 1024  # 50GB
task = vm.ReconfigVM_Task(spec)

Error: "The disk is not shrinkable" - This typically occurs with thick-provisioned disks. Convert to thin provisioning first:

vmware-vdiskmanager -r thick.vmdk -t 0 thin.vmdk

Performance degradation - After shrinking, consider running disk optimization tools within the guest OS.

Third-party utilities like:

  • StarWind V2V Converter
  • qemu-img (for conversion between formats)