Backup Windows Server com Task Scheduler: guia agendado completo
Configure backup automatizado no Windows Server usando Task Scheduler, robocopy e wbadmin. Pastas, banco SQL Server e rotação de mídia.
Backup automatizado em Windows Server não exige software pago nem agente proprietário. As ferramentas nativas — Task Scheduler, robocopy, wbadmin e o BACKUP DATABASE do SQL Server — cobrem 95% dos cenários de produção quando combinadas corretamente. Este tutorial mostra como construir uma rotina diária com rotação semanal, logs auditáveis e cobertura de arquivos, estado do sistema e bancos relacionais.
A persona aqui é o sysadmin Windows Server que herdou (ou está provisionando) uma máquina com pastas críticas, talvez um SQL Server, e precisa garantir RTO razoável sem depender de Veeam, Backup Exec ou outras suítes pagas. O foco é confiabilidade operacional: agendamento estável, falhas que avisam, logs que você consegue auditar dois meses depois.
Tempo estimado de execução: 30 a 45 minutos pra configurar o primeiro ciclo completo, incluindo teste de restauração. Validamos no Windows Server 2019 e 2022 — os comandos são idênticos. Em Windows Server 2016 funciona, mas algumas flags do robocopy têm comportamento diferente em paths longos.
Pré-requisitos
Windows Server 2019 ou 2022 com acesso administrativo local. Espaço em disco no destino igual ou maior que o dobro do volume de origem (pra dois ciclos de backup). Se for usar wbadmin, precisa instalar o recurso “Windows Server Backup” via Server Manager ou Install-WindowsFeature Windows-Server-Backup. Pra backup de SQL Server, sqlcmd instalado e usuário com permissão BACKUP DATABASE.
Windows Server 2019/2022 Service account dedicada 2x o tamanho da origem Windows-Server-Backup Antes de criar qualquer tarefa, prepare uma conta de serviço dedicada. Não use Administrador local nem sua conta pessoal — quando a senha trocar ou a conta for desativada, o backup para de rodar silenciosamente. Crie uma conta como svc_backup no grupo Administradores locais (ou grupo customizado com permissões específicas em produção), com senha forte e a flag “Senha nunca expira” marcada.
Estruturando o destino do backup
Antes de scripts e tarefas, defina o layout do destino. Improvisar isso depois quebra rotação e dificulta auditoria.
Crie a estrutura de pastas no destino — pode ser um disco secundário, compartilhamento de rede ou volume montado:
New-Item -Path "D:\Backup\Arquivos" -ItemType Directory
New-Item -Path "D:\Backup\SQL" -ItemType Directory
New-Item -Path "D:\Backup\SystemState" -ItemType Directory
New-Item -Path "D:\Backup\Logs" -ItemType DirectorySeparar arquivos, banco e estado do sistema em pastas distintas facilita rotação independente — você pode reter 7 dias de arquivos mas 30 dias de banco, por exemplo.
Aplique permissões NTFS restritivas no diretório raiz:
icacls "D:\Backup" /inheritance:r
icacls "D:\Backup" /grant:r "Administrators:(OI)(CI)F"
icacls "D:\Backup" /grant:r "svc_backup:(OI)(CI)F"
icacls "D:\Backup" /grant:r "SYSTEM:(OI)(CI)F"Backup contém dados sensíveis — limitar acesso à conta de serviço, SYSTEM e Administradores reduz superfície em caso de comprometimento de usuário comum.
Backup de pastas com robocopy
Robocopy é a ferramenta nativa pra cópia incremental confiável de arquivos. Diferente de xcopy ou copy, ele resume interrompido, mantém ACLs e tem retry configurável — pronto pra produção.
Crie o script C:\Scripts\backup-arquivos.ps1:
$origem = "C:\Dados"
$destino = "D:\Backup\Arquivos"
$logPath = "D:\Backup\Logs\arquivos-$(Get-Date -Format 'yyyy-MM-dd').log"
robocopy $origem $destino /MIR /COPYALL /R:3 /W:10 /MT:8 /LOG:$logPath /NP /TEE
$exitCode = $LASTEXITCODE
if ($exitCode -ge 8) {
Write-EventLog -LogName Application -Source "BackupScript" -EventId 1001 -EntryType Error -Message "Backup falhou com codigo $exitCode"
exit 1
}
exit 0Os parâmetros aqui importam. /MIR espelha origem no destino (apaga arquivos que sumiram). /COPYALL preserva permissões NTFS, timestamps, owner e auditoria. /R:3 /W:10 tenta 3 vezes com 10 segundos entre tentativas — equilibra robustez e tempo. /MT:8 paraleliza com 8 threads.
A flag /MIR apaga no destino tudo que não existe na origem. Se você apontar dois servidores pro mesmo destino sem subpastas separadas, cada execução vai apagar os arquivos do outro. Sempre use destino dedicado por máquina ou subpasta com nome do hostname.
Registre a fonte do Event Log uma vez (pra que Write-EventLog funcione):
New-EventLog -LogName Application -Source "BackupScript"Isso permite que o script escreva em Visualizador de Eventos > Aplicativos, integrando com sistemas de monitoração que leem o log do Windows.
Backup de banco SQL Server
Robocopy não consegue copiar arquivos .mdf/.ldf enquanto o SQL Server os mantém abertos. A solução nativa é o comando BACKUP DATABASE, que gera .bak consistente sem downtime.
Crie o script C:\Scripts\backup-sql.ps1:
$data = Get-Date -Format 'yyyy-MM-dd_HHmm'
$destino = "D:\Backup\SQL"
$bancos = @("MeuApp", "PortalCliente")
foreach ($db in $bancos) {
$arquivo = "$destino\$db-$data.bak"
$query = "BACKUP DATABASE [$db] TO DISK = '$arquivo' WITH COMPRESSION, CHECKSUM, INIT"
sqlcmd -S localhost -E -Q $query
if ($LASTEXITCODE -ne 0) {
Write-EventLog -LogName Application -Source "BackupScript" -EventId 1002 -EntryType Error -Message "Backup SQL falhou: $db"
}
}COMPRESSION reduz tamanho do .bak em 60-80% pra maioria dos workloads. CHECKSUM verifica integridade durante o backup — você descobre corrupção no momento certo, não na hora da restauração. INIT sobrescreve mídia anterior se o nome do arquivo coincidir.
Se uma rotina maior (full + differential) já existe pro SQL Server, adicione COPY_ONLY no WITH pra não interferir na cadeia de log. Sem isso, seu backup quebra o ponto de restauração diferencial da rotina principal.
Backup do estado do sistema com wbadmin
Pra restauração completa do servidor (incluindo registro, AD, IIS metabase), use wbadmin. Ele complementa robocopy e SQL — você raramente vai restaurar tudo, mas quando precisar, vai precisar muito.
Verifique que o recurso está instalado:
Install-WindowsFeature Windows-Server-Backup -IncludeManagementToolsSe já estava instalado, o comando retorna sem ação. Em servidores recém-provisionados, isso adiciona o backup completo + cmdlets PowerShell.
Crie script C:\Scripts\backup-systemstate.ps1:
$data = Get-Date -Format 'yyyy-MM-dd'
$destino = "D:\Backup\SystemState"
wbadmin start systemstatebackup -backupTarget:$destino -quiet
if ($LASTEXITCODE -ne 0) {
Write-EventLog -LogName Application -Source "BackupScript" -EventId 1003 -EntryType Error -Message "Backup SystemState falhou"
}Backup de estado do sistema captura registro, banco COM+, arquivos de boot e (em controladores de domínio) o AD inteiro. Roda em 5-15 minutos no servidor típico.
Agendando com Task Scheduler
Com os scripts prontos, agendamento via Task Scheduler garante execução não-interativa, com logging próprio e retry em caso de falha.
Abra Task Scheduler como Administrador (taskschd.msc) e crie tarefa via “Criar Tarefa” (não “Criar Tarefa Básica” — essa não expõe todas as opções).
Na aba Geral:
- Nome:
Backup Diario - Arquivos - Conta:
svc_backup(clique em “Alterar Usuário ou Grupo”) - Marque: “Executar quer o usuário esteja conectado ou não”
- Marque: “Executar com privilégios mais altos”
- Configurar pra: Windows Server 2022 (ou 2019)
Na aba Disparadores, adicione novo disparador:
- Iniciar tarefa: Em uma agenda
- Diariamente, às 02:00
- Marque “Habilitado”
Distribuir backups em horários diferentes (arquivos 02:00, SQL 03:00, system state 04:00) evita pico de I/O e contenção no destino.
Na aba Ações, adicione “Iniciar um programa”:
- Programa/script:
powershell.exe - Adicione argumentos:
-NoProfile -ExecutionPolicy Bypass -File "C:\Scripts\backup-arquivos.ps1"
-NoProfile pula carregamento de perfil PowerShell (mais rápido, mais previsível). -ExecutionPolicy Bypass evita bloqueio por política de execução restrita sem alterar configuração global.
Esse campo é o working directory, não o caminho do script. Path do script vai inteiro entre aspas dentro de -File "...". Confundir os dois é a causa #1 de tarefa que dispara mas o script nunca executa.
Na aba Configurações:
- Marque “Permitir que a tarefa seja executada sob demanda”
- Marque “Executar tarefa o quanto antes após início agendado perdido”
- Marque “Se a tarefa falhar, reiniciar a cada: 10 minutos / até: 3 vezes”
- “Interromper a tarefa se ela for executada por mais de: 4 horas”
Repita o processo pra backup-sql.ps1 (03:00) e backup-systemstate.ps1 (04:00, idealmente domingo só — system state é grande).
Rotação de backups antigos
Sem rotação, o destino enche em semanas. Robocopy /MIR resolve pro espelho de arquivos, mas SQL .bak e wbadmin acumulam.
Crie C:\Scripts\rotacao.ps1 pra apagar backups SQL com mais de 14 dias:
$limite = (Get-Date).AddDays(-14)
Get-ChildItem "D:\Backup\SQL\*.bak" | Where-Object { $_.LastWriteTime -lt $limite } | Remove-Item -Force
Get-ChildItem "D:\Backup\Logs\*.log" | Where-Object { $_.LastWriteTime -lt $limite } | Remove-Item -ForceAgende essa tarefa pra 05:00 diariamente. wbadmin tem rotação própria via -maxBackups: no start systemstatebackup.
Verificação
Agendar não basta — você precisa confirmar que o backup roda E restaura.
Pra confirmar execução:
Get-ScheduledTask -TaskName "Backup Diario - Arquivos" | Get-ScheduledTaskInfo
A saída mostra LastRunTime, LastTaskResult (0 = sucesso) e NextRunTime. Qualquer LastTaskResult diferente de 0 sinaliza falha — investigue no log de Eventos.
Pra teste real de restauração do SQL — esse é não-negociável, faça mensalmente:
sqlcmd -S localhost -E -Q "RESTORE DATABASE [MeuApp_TESTE] FROM DISK = 'D:\Backup\SQL\MeuApp-2026-05-29_0300.bak' WITH MOVE 'MeuApp' TO 'C:\Temp\MeuApp_TESTE.mdf', MOVE 'MeuApp_log' TO 'C:\Temp\MeuApp_TESTE.ldf', RECOVERY"
Backup nunca testado não é backup — é arquivo grande ocupando disco.
Resolução de problemas
Tarefa termina com 0x41306 (canceled by user)
Significa que a tarefa atingiu o “Interromper a tarefa se executada por mais de X” definido em Configurações. Aumente o limite ou investigue por que o backup está demorando além do esperado — pode ser disco lento, rede saturada ou volume crescente.
Robocopy retorna exit code 8 ou superior
Exit codes do robocopy são bitmask. Códigos 0-7 são sucesso (com avisos). 8+ indica erro real — arquivo bloqueado, permissão negada, destino sem espaço. Sempre checar $LASTEXITCODE -ge 8 no script, não -ne 0.
Tarefa não dispara mesmo com horário correto
Verifique se a conta de serviço tem o direito “Logon como tarefa em lote” (secpol.msc > Direitos de usuário > Logon como tarefa em lote). Sem isso, Task Scheduler não consegue iniciar processo na conta. Erro aparece como 0x4 ou “tarefa pronta” eternamente.
Próximos passos
Com a rotina diária estável, expanda em três direções: replicação do destino pra storage externo (não confie em disco local — incêndio apaga origem e backup junto), monitoração via Zabbix ou similar lendo o Event Log das tarefas, e exercícios trimestrais de restauração completa cronometrando RTO real.
Se você está colocando Windows Server em produção e quer infraestrutura com snapshots em nível de hipervisor complementando esse backup nativo, uma VPS Hostini já vem com volume principal em SSD NVMe e snapshots agendáveis — útil como segunda camada antes do desastre que ninguém quer enfrentar.
Perguntas frequentes
Posso usar wbadmin pra fazer backup só de pastas específicas em vez do volume inteiro?
Sim. O parâmetro `-include:` aceita lista de caminhos separados por vírgula, como `-include:C:\Dados,C:\Inetpub`. Isso evita gerar imagem do volume todo quando você só precisa de pastas específicas. O alvo (`-backupTarget:`) ainda precisa ser disco ou compartilhamento de rede com espaço suficiente.
O Task Scheduler dispara o job mas a tarefa termina com código 0x1 — o que olhar primeiro?
0x1 é genérico do Windows e quase sempre indica problema de permissão ou caminho inválido. Confirme se a opção "Executar com privilégios mais altos" está marcada, se a conta usada existe e não está bloqueada, e se o caminho do script ou executável não tem espaços não escapados. O log em `Eventos do Windows > Logs de Aplicativos e Serviços > Microsoft > Windows > TaskScheduler > Operational` mostra o erro real.
Robocopy mantém permissões NTFS e timestamps no backup?
Mantém quando você usa as flags `/COPYALL` (copia dados + atributos + timestamps + segurança + owner + auditoria) ou `/COPY:DAT` pra um subconjunto. Sem essas flags, robocopy copia só dados e atributos básicos, perdendo ACLs. Em servidores de arquivos com permissões granulares, `/COPYALL` é obrigatório.
Como faço rotação semanal mantendo só 7 backups diários sem stack de scripts complexos?
Robocopy não tem retenção nativa, mas você pode combinar com `forfiles /P D:\Backup /D -7 /C "cmd /c del @path"` num passo separado da tarefa agendada. Isso apaga qualquer arquivo com mais de 7 dias no destino. Pra wbadmin, use o parâmetro `-maxBackups:` ou versione manualmente por pasta com data.
Backup do SQL Server precisa parar o serviço ou pode rodar com o banco online?
Backup nativo via `BACKUP DATABASE` no SQL Server roda 100% online — é o método recomendado e gera arquivo `.bak` consistente sem downtime. Tentar copiar os arquivos `.mdf`/`.ldf` diretamente com robocopy enquanto o SQL Server está rodando vai falhar porque os arquivos estão em uso exclusivo.
Posso agendar o backup pra rodar mesmo quando ninguém está logado no servidor?
Sim — essa é a configuração padrão e recomendada pra produção. Na aba "Geral" da tarefa, selecione "Executar quer o usuário esteja conectado ou não" e forneça as credenciais da conta de serviço. Use uma conta dedicada com senha que não expira pra evitar quebra silenciosa do agendamento quando senhas trocam.