How to zero fill a virtual disk's free space on windows for better compression?

Solution 1:

On windows use the sysinternals tool sdelete to zero out all the empty space. The command you want would look like this sdelete -z c:.

Usage: sdelete [-p passes] [-s] [-q]  ...  
sdelete [-p passes] [-z|-c] [drive letter] ...  
-a         Remove Read-Only attribute.  
-c         Clean free space.  
-p passes  Specifies number of overwrite passes (default is 1).  
-q         Don't print errors (Quiet).  
-s or -r   Recurse subdirectories.  
-z         Zero free space (good for virtual disk optimization).

For Linux I suggest you use zerofree.

Solution 2:

Windows already has a built-in command line tool that does this: CIPHER. See its /W option.

So the complete command would be: cipher /w:c: (replace c: with actual drive letter)

(it writes zeroes to the unused space, then 0xff, so you have to watch it and stop it with ctrl-c when it begins to write 0xff - not ideal, but it is free and already available in Windows since XP at least)

Solution 3:

fsutil isn't open source, but is does ship with Windows and therefore doesn't cost anything extra. I used it to zero the free space on an empty WD 250 GB 7200 RPM drive (F:). Here's what I ran from the command line:

fsutil volume diskfree f:

Which showed this report:

Total # of free bytes        : 249899469856
Total # of bytes             : 249997291520
Total # of avail free bytes  : 249899469856

I used Total # of avail free bytes in the following commands:

fsutil file createnew F:\clear 249899469856
fsutil file setvaliddata F:\clear 249899469856
fsutil file setzerodata offset=0 length=249899469856 F:\clear
del f:\clear

It took about 4 hours to write 250GB of zeros.

Solution 4:

SDelete will not zero out the space for compaction of a virtual disk. SDelete starts by zeroing free space, but then fills it with 0xff and then random bytes See How to prepare a Virtual Server 2005 virtual hard disk file to send to Microsoft Product Support Services For how to set up a VHD for compaction

Precompact.exe can be difficult to find for some reason. I found a seperate downloadable copy here. However if you have windows virtual PC you can also get it from %programfiles(x86)%\Windows Virtual PC\Integration Components\Precompact.iso

Solution 5:

I too had been looking for a way of using Cipher to only write 0x00 then exit when starting to write 0xFF to the free space. This will allow the maximum free space to be compressed. I have come up with the following basic PowerShell job

replace d:\ with the required drive

Function CipherFreeSpace
    $cipherjob = @()
    $Job = start-job -ScriptBlock {cipher /w:d:\ }
    while ($cipherjob -notcontains "Writing 0xFF")
        Write-host "." -nonewline 
        Start-Sleep 2
        $cipherjob += $job | Receive-Job 
    $Job | Stop-Job | Remove-Job -Force

Regards Simon