Automatizando backups no Windows com PowerShell e robocopy

1. Introdução ao backup automatizado no Windows

A perda de dados é um dos problemas mais críticos que qualquer profissional de TI pode enfrentar. Seja por falha de hardware, erro humano, ataque de ransomware ou desastre natural, a ausência de backups confiáveis pode significar o fim de um negócio. Automatizar backups no Windows com PowerShell e robocopy oferece uma solução robusta, gratuita e nativa do sistema operacional.

O robocopy (Robust File Copy) é uma ferramenta de linha de comando presente em todas as versões modernas do Windows. Diferentemente do xcopy (obsoleto) e do File Explorer (lento e sem scripts), o robocopy oferece controle granular sobre cópias, retentativas automáticas em caso de falha de rede, suporte a cópia de atributos de segurança e logs detalhados. O PowerShell, por sua vez, adiciona lógica de programação, tratamento de erros e agendamento flexível.

Esta combinação é ideal para backups de pastas locais, compartilhamentos de rede, servidores de arquivos e até mesmo migrações de dados entre servidores. Com um script bem construído, você pode ter backups consistentes, incrementais e auditáveis sem custo adicional de licenciamento.

2. Preparando o ambiente: requisitos e configurações iniciais

Antes de começar, verifique se o PowerShell e o robocopy estão disponíveis no seu sistema. Em qualquer Windows 10, Windows 11, Windows Server 2016 ou superior, ambos já vêm instalados. Para confirmar, abra o PowerShell como Administrador e execute:

Get-Command robocopy
Get-Host | Select-Object Version

O robocopy deve retornar informações do comando, e a versão do PowerShell deve ser 5.1 ou superior (idealmente PowerShell 7+ para recursos modernos).

Permissões são cruciais: a conta que executará o backup precisa de acesso de leitura à origem e acesso de escrita ao destino. Para backups de pastas do sistema (C:\Windows, C:\Users), execute o script como Administrador. Para backups de rede, a conta deve ter permissões no compartilhamento remoto.

Boas práticas de estrutura de diretórios:
- Origem: mantenha pastas organizadas (Documentos, Projetos, BancoDeDados)
- Destino: crie uma estrutura com data/hora, por exemplo: D:\Backups\2025-03-28_1630\
- Evite usar a unidade do sistema (C:) como destino de backup

3. Comandos essenciais do robocopy para backups

O robocopy possui dezenas de parâmetros, mas para backups os mais importantes são:

  • /MIR: espelha a origem no destino (remove arquivos no destino que não existem mais na origem)
  • /E: copia subdiretórios, incluindo vazios
  • /COPYALL: copia todos os atributos (dados, timestamps, atributos NTFS, ACLs, owner)
  • /R:3: número de retentativas em caso de falha (padrão 1 milhão, limite para 3)
  • /W:5: tempo de espera entre retentativas em segundos
  • /LOG+:caminho: adiciona log ao final de um arquivo existente
  • /NP: não mostra progresso (útil para logs limpos)
  • /TEE: exibe saída no console e no log simultaneamente

Exemplo prático de comando robocopy executado diretamente no PowerShell:

robocopy "C:\MeusDocumentos" "D:\Backups\MeusDocumentos" /MIR /COPYALL /R:3 /W:5 /LOG+:D:\Logs\backup.log /NP

4. Construindo um script PowerShell de backup completo

Agora vamos construir um script robusto que inclui variáveis, timestamp, tratamento de erros e logs. Salve como BackupAutomatico.ps1:

# Script de Backup Automatizado com PowerShell e Robocopy
# Autor: Seu Nome
# Data: $(Get-Date -Format "yyyy-MM-dd")

param(
    [string]$Origem = "C:\DadosImportantes",
    [string]$DestinoBase = "D:\Backups",
    [int]$Retentativas = 3,
    [int]$Espera = 5
)

# Gerar timestamp para nome da pasta e log
$DataHora = Get-Date -Format "yyyy-MM-dd_HHmmss"
$Destino = Join-Path -Path $DestinoBase -ChildPath $DataHora
$LogDir = Join-Path -Path $DestinoBase -ChildPath "Logs"
$LogFile = Join-Path -Path $LogDir -ChildPath "Backup_$DataHora.log"

# Criar diretórios se não existirem
if (-not (Test-Path $Destino)) { New-Item -ItemType Directory -Path $Destino -Force | Out-Null }
if (-not (Test-Path $LogDir)) { New-Item -ItemType Directory -Path $LogDir -Force | Out-Null }

# Início do backup
Write-Host "Iniciando backup em $(Get-Date)" -ForegroundColor Green

try {
    $Argumentos = @(
        $Origem,
        $Destino,
        "/MIR",
        "/COPYALL",
        "/R:$Retentativas",
        "/W:$Espera",
        "/LOG+:$LogFile",
        "/NP",
        "/TEE"
    )

    $Resultado = Start-Process -FilePath "robocopy.exe" -ArgumentList $Argumentos -Wait -PassThru -NoNewWindow

    if ($Resultado.ExitCode -ge 8) {
        throw "Erro crítico no robocopy. Código de saída: $($Resultado.ExitCode)"
    }

    Write-Host "Backup concluído com sucesso! Código: $($Resultado.ExitCode)" -ForegroundColor Green
}
catch {
    Write-Host "Falha no backup: $_" -ForegroundColor Red
    # Registrar no Event Log do Windows
    Write-EventLog -LogName Application -Source "BackupScript" -EntryType Error -EventId 1001 -Message $_
    exit 1
}

5. Agendamento automático com o Task Scheduler

Para executar o script diariamente sem intervenção manual, use o Agendador de Tarefas. Você pode criar a tarefa manualmente ou via PowerShell:

$Acao = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-NoProfile -ExecutionPolicy Bypass -File `"C:\Scripts\BackupAutomatico.ps1`""
$Gatilho = New-ScheduledTaskTrigger -Daily -At "03:00AM"
$Config = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -StartWhenAvailable
$Principal = New-ScheduledTaskPrincipal -UserId "SYSTEM" -LogonType ServiceAccount -RunLevel Highest

Register-ScheduledTask -TaskName "BackupDiarioDados" -Action $Acao -Trigger $Gatilho -Settings $Config -Principal $Principal

Isso cria uma tarefa que roda como SYSTEM (máximas permissões) às 3h da manhã, mesmo se o computador estiver na bateria.

6. Recursos avançados: backup incremental e exclusões

Para backups incrementais (apenas arquivos modificados nos últimos N dias), use:

robocopy $Origem $Destino /MIR /COPYALL /MAXAGE:7 /R:3 /W:5

/MAXAGE:7 copia apenas arquivos modificados nos últimos 7 dias. /MINAGE:7 faz o oposto (arquivos mais antigos que 7 dias).

Para excluir pastas ou arquivos específicos:

robocopy $Origem $Destino /MIR /XD "Temp" "Cache" /XF "*.tmp" "*.log" /R:3 /W:5

/XD exclui diretórios, /XF exclui arquivos por padrão (pode usar curingas).

Para backup de múltiplas origens em um destino centralizado:

$Origens = @("C:\Documentos", "C:\Projetos", "\\Servidor\Compartilhado")
foreach ($Orig in $Origens) {
    $PastaNome = $Orig -replace '[\\:]', '_'
    $DestinoFinal = Join-Path $Destino $PastaNome
    robocopy $Orig $DestinoFinal /MIR /COPYALL /R:3 /W:5
}

7. Monitoramento e notificações do backup

Notificações por e-mail são essenciais para equipes de TI. Exemplo com Send-MailMessage:

$SmtpServer = "smtp.seuemail.com"
$De = "backup@empresa.com"
$Para = "admin@empresa.com"
$Assunto = "Backup - $(Get-Date -Format 'yyyy-MM-dd') - $Status"
$Corpo = "Backup da origem $Origem para $Destino concluído em $(Get-Date).`nCódigo de saída: $CodigoSaida"

Send-MailMessage -SmtpServer $SmtpServer -From $De -To $Para -Subject $Assunto -Body $Corpo

Para auditoria em CSV:

$Registro = [PSCustomObject]@{
    Data = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
    Origem = $Origem
    Destino = $Destino
    Status = if ($CodigoSaida -lt 8) {"Sucesso"} else {"Falha"}
    Codigo = $CodigoSaida
}
$Registro | Export-Csv -Path "$DestinoBase\Auditoria.csv" -Append -NoTypeInformation

8. Boas práticas e solução de problemas comuns

  • Teste em ambiente de homologação: nunca execute scripts novos diretamente em produção. Crie pastas de teste com dados não críticos.
  • Permissões negadas: verifique se a conta de execução tem acesso completo à origem e destino. Para pastas de rede, use net use para mapear unidade com credenciais.
  • Caminhos de rede inacessíveis: adicione verificação com Test-Connection antes do backup.
  • Desempenho: para grandes volumes, use /MT:8 (multithread, 8 threads) para acelerar. Limpe logs antigos com script de retenção de 30 dias.
  • Solução de problemas comuns:
  • Erro "Access Denied": execute como Administrador ou ajuste permissões NTFS
  • Código de saída 16: erro grave, verifique logs detalhados
  • Backup muito lento: reduza /R e /W, aumente /MT

Referências