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

Como sincronizar duas pastas em PowerShell: passo a passo

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

Aprende a sincronizar duas pastas em PowerShell para manter um backup coerente e reduzir transferências desnecessárias. Este guia mostra como comparar, copiar apenas ficheiros novos ou alterados e registar operações, útil para backups locais e migrações simples.

Pré-requisitos

  • PowerShell 5.1 ou PowerShell 7+ instalado.
  • Permissões de leitura na pasta de origem e de escrita na pasta de destino.
  • Espaço suficiente em disco na pasta de destino.

Passo 1: Estrutura básica e variáveis

Começa por definir caminhos e opções. Usa uma variável $WhatIf para executar um dry-run sem copiar ficheiros — muito útil para testar.

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

Passo 2: Script para sincronizar duas pastas (cópia incremental)

O princípio é simples: enumerar ficheiros em $Source, calcular o caminho relativo e comparar com o ficheiro correspondente em $Destination. Copia-se apenas quando o ficheiro não existe ou foi alterado (tamanho ou data).

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

Passo 3: Registo e tratamento de erros

Registar operações ajuda a auditar o processo. Adiciona Try/Catch para capturar falhas e grava entradas no ficheiro de registo.

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
    }
}

Passo 4: Opcional — remover ficheiros que desapareceram na origem

Se pretendes que o destino reflita exactamente a origem (two-way sync não é este exemplo), elimina ficheiros no destino que já não existem na origem. Faz sempre um dry-run primeiro.

# Cuidado: esta ação apaga ficheiros no 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 o resultado

Para confirmar que a sincronização funcionou: 1) executa o script com $WhatIf = $true e verifica as mensagens; 2) executa com $WhatIf = $false num pequeno conjunto de ficheiros; 3) confere o $LogFile para registos de cópias/erros; 4) valida tamanhos e datas entre $Source e $Destination com Get-ChildItem.

Conclusão

Sincronizar duas pastas em PowerShell é uma solução simples e controlável para backups locais e migrações. A partir deste esqueleto podes adicionar filtros por extensão, paralelismo com Start-Job ou integração com ferramentas de compressão. Dica: testa sempre com $WhatIf = $true antes de apagar ficheiros em produção — preferes manter versões antigas ou um histórico de backups?