Page 1 of 1

Restoring zero byte files from a backup

Posted: 2021-Jul-25, 11:15 am
by MigrationUser
29 Aug 2008 19:01
Simon Sheppard


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.

Code: Select all

$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.

note
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.

----------------------------

#16 Aug 2009 02:54
audiogalaxy


very useful example, thanks!

(sorry for my bad english)

----------------------------

#02 Nov 2009 22:11
arenas


hello many thnx for this script !

how can i create n batch with posh?

- timer
- run the script
- ftp upload

i have to use IE?
many tnx

----------------------------

#02 Nov 2009 22:28
Simon Sheppard


- timer
- run the script

start-sleep (or just setup a scheduled task to run powershell.exe)

- ftp upload

You can run FTP right from the powershell command line just as in CMD
https://ss64.com/nt/ftp.html