How to Zero Out a Drive in Windows: The Equivalent of /dev/zero for Secure Disk Wiping


4 views

When preparing storage devices in Linux, /dev/zero is the go-to solution for writing zeros to a drive. Windows administrators face a challenge when they need to perform similar operations, particularly when:

  • Preparing bootable USB drives
  • Securely wiping sensitive data
  • Ensuring clean slate before filesystem creation
  • Benchmarking storage performance

Windows doesn't have a direct /dev/zero device, but offers these built-in methods:

Using diskpart

diskpart
list disk
select disk X (replace X with your disk number)
clean
create partition primary
format fs=ntfs quick

PowerShell Approach

$drivenum = Read-Host "Enter disk number to zero"
$disk = Get-Disk -Number $drivenum
$disk | Clear-Disk -RemoveData -RemoveOEM -Confirm:$false
Initialize-Disk -Number $drivenum -PartitionStyle GPT

For more precise control similar to Linux's dd if=/dev/zero, consider these tools:

Using dd for Windows

dd if=\\?\Device\Null of=\\?\PhysicalDriveX bs=1M --progress

Where PhysicalDriveX is your target device (use diskpart to identify).

SDelete from Sysinternals

sdelete -z X:

For wiping free space, or:

sdelete -c X:

When preparing USB drives for Linux ISOs:

  1. Always verify the correct device number
  2. Consider writing zeros only to the first few MB for quick clearing:
    dd if=\\?\Device\Null of=\\?\PhysicalDriveX bs=1M count=10
  3. Use checksum verification after writing:
    certutil -hashfile yourimage.iso SHA256

For large drives, adjust block sizes for better performance:

dd if=\\?\Device\Null of=\\?\PhysicalDriveX bs=4M status=progress

Monitor progress with:

Get-Disk -Number X | Get-Partition | Get-Volume

When preparing to write a RHEL ISO to a USB drive on Windows, it's often necessary to completely wipe the drive first. Linux users typically use dd if=/dev/zero of=/dev/sdX for this purpose, but Windows lacks the familiar /dev/zero device.

Windows provides several ways to achieve similar functionality:

# Using diskpart (Command Prompt)
diskpart
> list disk
> select disk X (replace X with your USB disk number)
> clean
> create partition primary
> format fs=ntfs quick
> exit

For more precise control similar to dd:

# Using PowerShell (Admin rights required)
$drive = "\\.\PhysicalDriveX" # Replace X with your drive number
$stream = [IO.File]::OpenWrite($drive)
$buffer = [Byte[]]::new(1MB) # 1MB buffer of zeros
while ($true) {
    $stream.Write($buffer, 0, $buffer.Length)
}

For those who frequently work with drive operations:

# Using dd for Windows (from Chrysocome)
dd if=\\?\Device\HarddiskX\Partition0 of=\\?\Device\HarddiskY\Partition0 bs=1M --size --progress

Or using PowerShell with more control:

# PowerShell function to zero-fill
function Zero-FillDrive {
    param(
        [Parameter(Mandatory=$true)]
        [string]$DriveLetter,
        [int]$BufferSizeMB = 4
    )
    
    $drivePath = "\\.\" + $DriveLetter + ":"
    try {
        $fs = [System.IO.File]::OpenWrite($drivePath)
        $buffer = [byte[]]::new($BufferSizeMB * 1MB)
        $totalWritten = 0
        $stopwatch = [System.Diagnostics.Stopwatch]::StartNew()
        
        while ($true) {
            $fs.Write($buffer, 0, $buffer.Length)
            $totalWritten += $buffer.Length
            Write-Progress -Activity "Zero-filling drive" 
                -Status ("Written: {0} MB" -f ($totalWritten / 1MB)) 
                -PercentComplete (($totalWritten / $fs.Length) * 100)
        }
    }
    finally {
        if ($fs) { $fs.Close() }
        $stopwatch.Stop()
        Write-Host "Operation completed in $($stopwatch.Elapsed)"
    }
}

1. Always double-check the target drive - wiping the wrong disk can be disastrous
2. Some methods may require Administrator privileges
3. The operation may take significant time for large drives
4. Consider using \\?\PhysicalDriveX notation for raw disk access

For benchmarking different approaches:

# PowerShell performance test
Measure-Command {
    $stream = [IO.File]::OpenWrite("\\.\PhysicalDrive2")
    $buffer = [Byte[]]::new(4MB)
    for ($i=0; $i -lt 256; $i++) {
        $stream.Write($buffer, 0, $buffer.Length)
    }
    $stream.Close()
}