
Necesito utilizar copias de seguridad para reemplazar archivos dañados en una carpeta compartida. Todos los archivos corruptos tienen un tamaño fijo = 1 KB y tienen configurada la marca de archivo. Básicamente, me gustaría reemplazar archivos en la carpeta de destino con archivos de copias de seguridad solo si el archivo de destino es <= 1 KB y/o tiene configurada la marca de archivo.
Robocopy parece una posible herramienta para esto, pero no veo una opción para condicionarlo al archivo de destino. Otra herramienta que parece que podría hacer esto es Powershell, pero no estoy familiarizado con ella.
¿Cómo puedo lograr esto con cualquiera de los programas?
Respuesta1
La solución Powershell puede informar y/o restaurar archivos corruptos:
# Use full paths!
$Backup = '\\server\backup'
$Corrupted = 'c:\broken_folder'
# Path for log file, can be relative
$LogFile = '.\Restore.log'
# If this variable is set to true, no files will be copied
$ReportOnly = $true
# Remove log file, if exist
if(Test-Path -Path $LogFile -PathType Leaf)
{
Remove-Item -Path $LogFile -Force
}
# Get all files in directory, recursive
$Corrupted | Get-ChildItem -Recurse |
# Select files with archive attribute: $_.Mode -like '*a*'
# And size less or equal to 1KB: ($_.Length / 1KB) -le 1 . Less fancy way: $_.Length -le 1024
# Ignore folders: -not $_.PsIsContainer
#
# In PS 3.0 and higher Get-ChildItem has less cryptic way to get folders and specify attributes:
# http://www.powershellmagazine.com/2012/08/27/pstip-how-to-get-only-files-the-powershell-3-0-way
Where-Object {($_.Mode -like '*a*') -and (($_.Length / 1KB) -le 1) -and (-not $_.PsIsContainer)} |
ForEach-Object {
# Output log record to pipeline, Tee-Object will catch it later
"Found corrupted file: $($_.FullName)"
# Replace current file path with path fo this file in backup folder
$NewFile = $_.FullName -replace [regex]::Escape($Corrupted), $Backup
if(Test-Path -Path $NewFile -PathType Leaf)
{
# Output log record to pipeline, Tee-Object will catch it later
"Found corresponding file from backup: $NewFile"
}
else
{
# Output log record to pipeline, Tee-Object will catch it later
"Failed to find corresponding file from backup: $NewFile"
return
}
if(-not $ReportOnly)
{
# Output log record to pipeline, Tee-Object will catch it later
"Restoring file from backup: $NewFile -> $($_.FullName)"
# Remove corrupted file
Remove-Item -Path $_.FullName -Force
# Copy file from backup
Copy-Item -Path $NewFile -Destination $_.FullName -Force
}
} | Tee-Object -FilePath $LogFile -Append # Send log to screen and file
Respuesta2
Robocopy tiene los parámetros que necesitas. Por ejemplo:
/A :: copia solo archivos con el atributo Archivo establecido.
/M :: copia solo archivos con el atributo Archivo y restablecelo.
/MAX:n :: Tamaño máximo de archivo: excluye archivos de más de n bytes.
/MIN:n :: Tamaño mínimo de archivo: excluye archivos de menos de n bytes.
Aquí hay una lista de todos los comandos: https://wmoore.wordpress.com/2009/09/01/robocopy-command-line-switches/