How-to: Restore selected (zero byte) files from a backup

Here's an example of using Powershell to restore a group of files from a backup.

This was used to patch up one of our file servers after some lovely 'enterprise' software decided to start randomly truncating files. We suddenly found ourselves with thousands of empty (zero byte) files split across different directories with unpredictable file dates. Simply restoring a backup of everything was not an option, as 90% of the files were OK and we don't want to overwrite the non-zero files with old copies.

First we restored a tape backup of everything to a separate folder. Then the script below was used to find each zero byte file, retrieve the matching file from the backup folder and copy it to a third, temporary destination, recreating directories in the new destination as needed.

With this done we could check the right files had been copied and then robocopy them all back onto the live server.

$usersRoot = '\\server1\t$\Users\'
$backupRoot = '\\server1\t$\backup\'
$destinationRoot = '\\server1\t$\new\'

Get-ChildItem -LiteralPath $usersRoot -Force -Recurse `
    | Where-Object {$_.length -eq 0 -and (-not $_.PSIsContainer)} `
    | ForEach-Object {
        # Identify the destination folder
        $destinationFolder = $_.PSParentPath.Replace("$usersRoot","$destinationRoot")
        #
        # Identify the backup file to copy
        $FileToCopy = $_.PSPath.Replace("$usersRoot","$backupRoot")
        #
        # If the backup file is also 0 bytes then skip it
        Get-Item -LiteralPath $FileToCopy | Where-Object {$_.length -ne 0} | ForEach-Object {
        #
        # If the destination folder does not exist, create it
        if (-not (Test-Path -LiteralPath $destinationFolder)) {
            New-Item -ItemType Directory -Path $destinationFolder | Out-Null
        }
        Copy-Item -LiteralPath $FileToCopy -Destination $destinationFolder
        }
    }

This script will pass through the directory structure once, copying files as it goes.
Each fully qualified file name must be less than 260 characters.
Each directory name must be less than 248 characters.

My first attempt at this was to try Robocopy with /max:0 /L to list all the zero byte files, unfortunately /max:0 did not return any files, so it was PowerShell to the rescue.

Examples

Assuming the script above is saved in the current directory as restorefiles.ps1

PS C:\> ./restorefiles.ps1

“It is not enough merely to call for freedom, democracy and human rights. There has to be a united determination to persevere in the struggle, to make sacrifices in the name of enduring truths, to resist the corrupting influences of desire, ill will, ignorance and fear” ~ Aung San Suu Kyi

Related PowerShell Cmdlets

Copy-Item - Copy an item from one location to another.
ROBOCOPY - Robust File and Folder Copy.


 
Copyright © 1999-2026 SS64.com
Some rights reserved