For years, I've used VMware Workstation for software testing, technical support, and application virtualization. I've learned that over the course of many cycles of use-particularly OS upgrades-the real disk space that a virtual disk uses can grow well beyond its virtual space, possibly degrading performance. The VMware Workstation graphical tools can't always recapture this space, but you can clean up bloated disks by using a specific procedure and some downloadable VMware tools.
No Snapshots or Linked Clones
Let's start with an important caveat. If you're using snapshots or linked clones in VMware Workstation, then do not use the procedures that I outline here. Virtual machines (VMs) that run from a snapshot or a linked clone run from virtual disks that are overlays for the original VM. If you attempt to defragment the original VM or a clone, you add a great deal of complexity, ensuring that you'll actually experience worse performance. Overlays already minimize the amount of space that's used for virtual disks; you're likely to increase the amount of space that's taken for the cloned disk.
Note that it's OK to use the techniques in this article to clean up what VMware calls full clones. A full clone is created from a complete copy of the original source VM but is not tied to it. If you aren't certain whether a VMware machine is a clone, snapshot, or source, then look at the machine details in VMware Workstation. Clones and snapshots explicitly mention the clone or snapshot source, as Figure 1 shows. The machine in Figure 2 is unlinked and simply shows the VMware Workstation version.
Do I Need to Defragment My Virtual Disks?
Fragmentation-related performance and size issues for a virtual disk vary, based on multiple factors. I use two simple rules of thumb.
First, if I think I see a significant performance loss in a VM, then the machine might need cleanup. Second, I compare the size of the Virtual Machine Disk Format (VMDK) file in which the disk resides to the amount of space that the VM internally reports is used for the drive. This comparison will not work as a measure if your VMware disks use preallocated space. Fixed disks still benefit from defragmentation, but the VMDK file will always be the maximum possible size for the VM disk.
To find the space that the file uses directly, right-click the VM in the VMware Favorites list, and choose Settings from the context menu. In the Virtual Machine Settings window that opens (as Figure 3 shows), select the hard disk under the Device column on the left (under the Hardware tab). Then, look in the Capacity area in the right half of the window. The Current size value shows the current size of the file on disk. Next, boot the guest OS and find the amount of space that it claims is in use. If the guest OS reports a significantly smaller usage than is listed for the VMDK file, you'll probably benefit from defragmenting and shrinking the disk.
Step 1: Clean Up from the Guest OS
The first step is to defragment the disk from within the guest OS. This is probably a good time to perform general maintenance such as OS and application updates. (When performed, these updates immediately cause some fragmentation and increase used space.) After defragmentation, shut down the VM.
Step 2: Use VMware Tools to Defragment and Shrink
Although VMware Workstation has options for mounting and shrinking a virtual disk via the Utilities button in the Virtual Machine Settings window, these options rarely have a significant effect on the virtual disk size. For example, I had a Windows 2000 Professional VMDK file with lots of slack space. The Win2K guest reported that it was using only 2.31GB of space, but the disk file took up 6.6GB. Using the GUI tools did not reduce the space requirements on the disk. Instead, I recommend that you use VMware's downloadable command-line tools, vmware-vdiskmanager and vmware-mount, to radically shrink the disks.
To begin, you need to get the tools from the VMware website. You'll need to register with VMware, and then search for the tool download. On Windows 7 running VMware Workstation 7.1, I use the VMware Virtual Disk Development Kit (VDDK), which includes both tools. Install the VDDK, and make sure to take note of the folder in which the VDDK is installed. On 32-bit Windows systems, that folder is typically something like C:\program files\vmware\vmware virtual disk development kit\bin; on 64-bit Windows systems, it will be something like C:\program files (x86)\vmware\vmware virtual disk development kit\bin. Now you're ready to start:
1. Use an account with administrative privileges to open a command prompt.
2. Use the command
to set your current directory to the VDDK folder, as the code at callout A in Listing 1 shows. This step ensures that the VMware tools-and more importantly, their supporting DLLs-are at the front of the command search path. If you're running 64-bit Windows, I strongly advise performing this step as instructed, even if you think you know a better way. If other paths are searched first, the VMware virtual disk-mounting tool, vmware-mount, frequently fails.
3. Defragment the virtual disk file by using the VMware tools. At the command prompt, run the command
with the -d (for defragment) option and the complete path to the virtual disk file. The code at callout B in Listing 1 shows this command for a VMDK file at E:\win2k pro\w2kprodisk1.vmdk.
4. At this point, you need to map the file as a disk, by using vmware-mount. You must specify an unused drive letter and the path to the VMDK file. The code at callout C in Listing 1 maps drive Z to the W2kProDisk1.vmdk file.
5. To prepare the disk for shrinking, use the command
with the -p (for prepare) option and the drive letter of the drive on which the VMDK file is mounted, not the path to the VMDK file. Using the wrong drive letter is the second source of problems for first attempts at disk shrinking; this is the only point at which you depend on a drive letter. The code at callout D in Listing 1 shows the correct procedure for a file that you've mounted as disk Z. You'll receive a continuously updated percentile display that tells you about the progress in wiping the disk. What's being wiped isn't the disk as a whole, but the blank space in the file.
6. Next, unmount the disk by using the command
as shown at callout E in Listing 1. With this command, "d" is for "dismount."
7. Finally, shrink the VMDK file by using the command
as shown at callout F in Listing 1. Here, "k" is a mnemonic for the word "shrink"; the letter "s" is used for another option.
At this point, you're finished. The technique can be extremely effective. The Win2K disk file that I mentioned earlier-the one that took up 6.65GB of space when the guest OS was using only 2.3GB of space-shrank to only 2.32GB. You can repeat this process for each guest OS that's taking excessive space.
Step 3: Defragment the Host Disk
As a final step to improve performance, from the hosting OS, defragment the physical disk on which the VMs reside. If you have performance or space problems because of fragmentation of guest drives, this step should resolve the problem.
Automating Disk Shrink
Although I find it simplest to perform guest OS maintenance manually when needed, the VMware disk defragmentation and shrinking operations can be automated easily. (They work from the command line anyway.)
The batch file ShrinkVmdk.cmd can be downloaded to automate step 2 of the previous process. The one assumption that this file makes is that drive Z is unused; if this isn't true, you'll want to modify the line
near the top of the batch file, to point to a free drive letter.
After you've installed the VDDK, you can start an elevated command-line window and run the script with the complete path to the VMDK file that you need to defragment. Using the batch file, you can defragment the sample virtual disk file by using the command
shrinkvmdk "E:\Win2k Pro\W2kProDisk1.vmdk"
In my experience, VMware's virtual disks are generally trouble-free and don't regularly need significant cleanup. However, when you do find that a virtual disk is eating up excessive drive space, you can use this process to quickly resolve the problem.
Listing 1: ShrinkVmdk.cmd
:: WARNING - the next two lines are ONE line that wraps in print.
pushd "C:\Program Files (x86)\VMware\
VMware Virtual Disk Development Kit\bin"
# END Callout A
# BEGIN Callout B
vmware-vdiskmanager -d "e:\Win2k Pro\W2kProDisk1.vmdk"
# END Callout B
# BEGIN Callout C
vmware-mount Z: "e:\Win2k Pro\W2kProDisk1.vmdk"
# END Callout C
# BEGIN Callout D
:: Prepare using the drive letter, not the path.
vmware-vdiskmanager -p Z:
# END Callout D
# BEGIN Callout E
vmware-mount -d Z:
# END Callout E
# BEGIN Callout F
:: Now, shrink the VMDK file.
vmware-vdiskmanager -k "e:\Win2k Pro\W2kProDisk1.vmdk"
# END Callout F