(+351) 21 24 10006  ·  info@bconcepts.pt
Carnaxide, Lisboa

Cómo sincronizar dos carpetas en PowerShell: paso a paso

João Barros 19 de July de 2026 3 min de lectura

Aprende a sincronizar dos carpetas en PowerShell para mantener una copia de seguridad coherente y reducir transferencias innecesarias. Esta guía muestra cómo comparar, copiar solo archivos nuevos o modificados y registrar operaciones, útil para copias locales y migraciones sencillas.

Requisitos previos

  • PowerShell 5.1 o PowerShell 7+ instalado.
  • Permisos de lectura en la carpeta de origen y de escritura en la carpeta de destino.
  • Espacio suficiente en disco en la carpeta de destino.

Paso 1: Estructura básica y variables

Empieza por definir rutas y opciones. Usa una variable $WhatIf para ejecutar un dry-run sin copiar archivos — muy útil para probar.

$Source = 'C:\Fonte'
$Destination = 'D:\Backup'
$LogFile = 'C:\Backup\sync.log'
$WhatIf = $true   # Mudar para $false para executar a cópia

# Garantir que a pasta destino existe
if (-not (Test-Path $Destination)) {
    New-Item -ItemType Directory -Path $Destination -Force | Out-Null
}

Paso 2: Script para sincronizar dos carpetas (copia incremental)

El principio es simple: enumerar archivos en $Source, calcular la ruta relativa y comparar con el archivo correspondiente en $Destination. Se copia solo cuando el archivo no existe o ha sido modificado (tamaño o fecha).

$sourceFiles = Get-ChildItem -Path $Source -File -Recurse
foreach ($s in $sourceFiles) {
    $rel = $s.FullName.Substring($Source.Length).TrimStart('\')
    $destPath = Join-Path $Destination $rel
    $destDir = Split-Path $destPath -Parent

    if (-not (Test-Path $destDir)) {
        if ($WhatIf) { Write-Output "Would create folder: $destDir" }
        else { New-Item -ItemType Directory -Path $destDir -Force | Out-Null }
    }

    $copy = $true
    if (Test-Path $destPath) {
        $d = Get-Item $destPath
        if ($s.Length -eq $d.Length -and $s.LastWriteTime -le $d.LastWriteTime) { $copy = $false }
    }

    if ($copy) {
        if ($WhatIf) { Write-Output "Would copy: $rel" }
        else { Copy-Item -Path $s.FullName -Destination $destPath -Force }
    }
}

Paso 3: Registro y manejo de errores

Registrar operaciones ayuda a auditar el proceso. Añade Try/Catch para capturar fallos y escribe entradas en el archivo de registro.

foreach ($s in $sourceFiles) {
    $rel = $s.FullName.Substring($Source.Length).TrimStart('\')
    $destPath = Join-Path $Destination $rel
    $destDir = Split-Path $destPath -Parent

    try {
        if (-not (Test-Path $destDir)) {
            if ($WhatIf) { Write-Output "Would create folder: $destDir" }
            else { New-Item -ItemType Directory -Path $destDir -Force | Out-Null }
        }

        $copy = $true
        if (Test-Path $destPath) {
            $d = Get-Item $destPath
            if ($s.Length -eq $d.Length -and $s.LastWriteTime -le $d.LastWriteTime) { $copy = $false }
        }

        if ($copy) {
            if ($WhatIf) { Write-Output "Would copy: $rel" }
            else {
                Copy-Item -Path $s.FullName -Destination $destPath -Force
                $entry = "{0} COPIED {1}" -f (Get-Date -Format s), $rel
                Add-Content -Path $LogFile -Value $entry
            }
        }
    }
    catch {
        $err = "{0} ERROR {1} - $_" -f (Get-Date -Format s), $rel
        Add-Content -Path $LogFile -Value $err
    }
}

Paso 4: Opcional — eliminar archivos que han desaparecido en el origen

Si quieres que el destino refleje exactamente el origen (sincronización bidireccional no es este ejemplo), elimina archivos en el destino que ya no existen en el origen. Haz siempre un dry-run primero.

# Cuidado: esta acción borra archivos en el destino
$destFiles = Get-ChildItem -Path $Destination -File -Recurse
foreach ($d in $destFiles) {
    $rel = $d.FullName.Substring($Destination.Length).TrimStart('\')
    $sourcePath = Join-Path $Source $rel
    if (-not (Test-Path $sourcePath)) {
        if ($WhatIf) { Write-Output "Would remove: $rel" }
        else { Remove-Item -Path $d.FullName -Force }
    }
}

Verificar el resultado

Para confirmar que la sincronización funcionó: 1) ejecuta el script con $WhatIf = $true y verifica los mensajes; 2) ejecuta con $WhatIf = $false en un pequeño conjunto de archivos; 3) consulta el $LogFile para registros de copias/errores; 4) valida tamaños y fechas entre $Source y $Destination con Get-ChildItem.

Conclusión

Sincronizar dos carpetas en PowerShell es una solución simple y controlable para copias locales y migraciones. A partir de este esqueleto puedes añadir filtros por extensión, paralelismo con Start-Job o integración con herramientas de compresión. Consejo: prueba siempre con $WhatIf = $true antes de borrar archivos en producción — ¿prefieres conservar versiones antiguas o un historial de copias?