Optimal Zero-Filling Techniques for Virtual Disk Compression on Windows: Tools and Implementation


2 views

When working with virtual machines (VMs), efficient storage utilization is crucial. Zero-filling free space before compression significantly improves compression ratios by creating contiguous blocks of zeros that compression algorithms can efficiently handle. This technique is particularly valuable when:

  • Creating VM templates for distribution
  • Preparing disk images for backup
  • Optimizing storage in cloud environments

The most reliable open-source solution for Windows is Microsoft's SDelete from Sysinternals. Here's the current best practice for version 1.61 (recommended due to performance issues in v2.0):

# Download from Microsoft's site
sdelete.exe -z C:

Key parameters to note:

  • -z: Zero-fills free space (post v1.6 syntax)
  • Omit pass count (-p) for single-pass operation
  • Works on mounted volumes without requiring reboot

For environments where SDelete isn't suitable, consider these alternatives:

PowerShell Approach

$FilePath = "C:\zero.tmp"
$VolumeFreeSpace = (Get-PSDrive C).Free
$Stream = [System.IO.File]::OpenWrite($FilePath)
$Stream.SetLength($VolumeFreeSpace)
$Stream.Close()
Remove-Item $FilePath

VHD/X Optimization

For Hyper-V virtual disks:

Optimize-VHD -Path C:\VMs\disk.vhdx -Mode Full

When working with dynamically allocated virtual disks:

  • Zero-filling won't automatically shrink the physical disk file
  • Most hypervisors require additional compaction steps after zero-filling
  • VMware: Use vmware-vdiskmanager -k
  • VirtualBox: VBoxManage modifymedium disk --compact

In our tests on a 100GB virtual disk with 30GB used space:

Tool Time Final Size
SDelete 1.61 22 min 31.2GB
PowerShell 35 min 31.5GB
SDelete 2.0 2+ hours 31.2GB

When working with virtual machine backups, zero-filling free space significantly improves compression ratios. This technique replaces random data patterns in unused disk sectors with predictable zeros, allowing compression algorithms to work more efficiently.

For Windows systems, the most reliable solution is SDelete from Microsoft's Sysinternals suite. Here's the proper usage for current versions (1.6+):

sdelete -z C:

Note that recent 2.0 versions may experience performance issues. If you encounter hanging at 100%, consider using the stable 1.61 version instead.

For those preferring non-Microsoft tools, consider these options:

# Using BleachBit (GUI available):
bleachbit --clean system.free_disk_space

# Using CCleaner (Free version):
CCleaner.exe /AUTO /WIPE

When working with dynamically allocated virtual disks, zero-filling requires additional precautions:

  1. For VirtualBox: Use VBoxManage modifymedium disk --compact after zero-filling
  2. For VMware: The vmware-vdiskmanager utility offers similar functionality
  3. For Xen: Utilize xe vm-disk-compress command

Here's a PowerShell script to automate the process:

# Zero-fill and compact script for Windows
param([string]$drive = "C:")

# Check for admin rights
if (-not ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
    Write-Warning "Please run as Administrator"
    exit
}

# Download SDelete if missing
if (-not (Test-Path "$env:Temp\\sdelete.exe")) {
    Invoke-WebRequest -Uri "https://download.sysinternals.com/files/SDelete.zip" -OutFile "$env:Temp\\sdelete.zip"
    Expand-Archive -Path "$env:Temp\\sdelete.zip" -DestinationPath "$env:Temp"
}

# Execute zero-fill
& "$env:Temp\\sdelete.exe" -z $drive

# Virtualization-specific compaction
if ($env:VIRTUALIZATION_PLATFORM -eq "VirtualBox") {
    & "C:\\Program Files\\Oracle\\VirtualBox\\VBoxManage.exe" modifymedium disk "$env:VIRTUAL_DISK_PATH" --compact
}
  • Schedule zero-filling during off-peak hours
  • For large disks, consider running the process in chunks
  • Monitor disk I/O to prevent system slowdowns
  • After zero-filling, immediately perform compression/backup operations

If the process appears stuck at 100%, this is often due to the filesystem updating metadata. For NTFS volumes, running chkdsk beforehand can help:

chkdsk C: /f

For extremely large volumes, consider partitioning the operation:

sdelete -z C: -accepteula -nobanner