“服务器有备份吗?”“有的,去年做过一次。”——这段对话在真实运维现场并不好笑。硬盘会坏、勒索病毒会加密、误删的 DELETE 不带 WHERE。真正让人安心的不是“备份过”,而是“每天凌晨两点自动跑,跑完有校验,上周刚演练恢复成功”。
Windows Server 自带一套足够好用的备份体系:Windows Server Backup(WSB)+ 卷影复制服务(VSS)+ 任务计划程序(Task Scheduler)。本文从备份策略设计讲起,给出 wbadmin 命令行配置、任务计划程序定时、robocopy 与数据库备份脚本,以及恢复演练的完整落地方案。
一、先定策略:不做备份规划的配置都是耍流氓
在敲任何命令之前,先回答三个问题:能丢多少数据(RPO,恢复点目标)、多久必须恢复(RTO,恢复时间目标)、备份放哪(保留与异地)。老板口中的“不能丢数据”落到工程上,就是每天一次全量 + 每小时一次增量/日志备份。
| 备份类型 | 备份内容 | 空间占用 | 恢复速度 | 典型频率 |
|---|---|---|---|---|
| 全量备份(Full) | 选定卷/目录的全部数据 | 最大 | 最快(只需一个备份集) | 每日或每周一次 |
| 增量备份(Incremental) | 上次任意备份以来的变化 | 最小 | 最慢(需链式还原) | 每 15 分钟 ~ 每小时 |
| 差异备份(Differential) | 上次全量以来的变化 | 中等 | 中等(全量 + 最近差异) | 每日多次 |
| 系统状态(System State) | 注册表、引导文件、AD/ SYSVOL、COM+ 数据库、证书服务 | 数 GB | 需配合系统恢复 | 随全量一起 |
| 裸机恢复(Bare Metal) | 系统卷 + 系统状态 + 关键卷 | 最大 | 可直接还原到新硬件 | 每周一次 |
业界通用的 3-2-1 原则:至少 3 份副本、使用 2 种不同介质、其中 1 份异地存放。对中小企业,落地版本通常是:本机 D 盘一份(快速恢复)+ NAS/SAN 一份(日常)+ 云对象存储一份(异地,防勒索)。勒索病毒会加密本机和局域网共享,所以异地那一份必须走不同凭据或不可变存储(Object Lock / WORM)。
还有一个被反复验证的教训:备份目标不能和源数据在同一块物理磁盘上。盘一坏,源和备份一起没。
二、Windows Server Backup 与 wbadmin 命令行
Windows Server Backup 是内置角色功能(Server Core 也支持),命令行工具是 wbadmin。先安装功能:
# PowerShell 安装(含命令行工具与 MMC 管理单元) Install-WindowsFeature -Name Windows-Server-Backup -IncludeManagementTools # 确认安装结果 Get-WindowsFeature -Name Windows-Server-Backup | Select-Object Name, InstallState
REM 老系统(Server 2008 R2)用 servermanagercmd 或 ocsetup servermanagercmd -install Backup-Features
2.1 一次性全量备份
REM 语法:wbadmin start backup -backupTarget:<目标> -include:<卷> [-allCritical] [-systemState] -quiet wbadmin start backup -backupTarget:E: -include:C:,D: -allCritical -quiet REM 只做系统状态备份(域控、证书服务器必做) wbadmin start systemstatebackup -backupTarget:E: -quiet REM 查看备份进度(另开窗口) wbadmin get status REM 列出已有备份版本 wbadmin get versions
参数含义:-allCritical 包含所有关键卷(系统卷、启动卷、AD 数据库所在卷等),等价于图形界面的“裸机恢复”;-systemState 包含系统状态;-quiet 免确认,脚本里必加;-vssFull 使用完整卷影复制(会更新存档位,影响其他增量备份产品,多备份软件共存时要小心)。
2.2 用 wbadmin 内置的定时备份
WSB 自带调度能力,一条命令即可注册每日计划任务。但要注意:这种方式一天只能配一次,且目标为整块专用磁盘时会格式化该盘。
REM 每天 02:00 和 14:00 自动备份 C、D 盘到 E 盘 wbadmin enable backup -addtarget:E: -schedule:02:00,14:00 -include:C:,D: -allCritical -systemState -quiet REM 查看当前已配置的计划 wbadmin get schedule REM 取消计划(注意:会同时删除该目标的备份) wbadmin disable backup
三、任务计划程序:更灵活的定时方案
当内置调度不够用时(多时间点、多策略、跑自定义脚本、发通知),就用任务计划程序(taskschd.msc)。图形界面路径:开始 → Windows 管理工具 → 任务计划程序 → 创建任务(注意选“创建任务”而不是“创建基本任务”,前者才有权限与重试选项)。
3.1 CMD 方式:schtasks
REM 创建每日 02:00 执行的备份任务,以 SYSTEM 最高权限运行 schtasks /create /tn "DailyFullBackup" /tr "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -NoProfile -ExecutionPolicy Bypass -File C:\Scripts\backup.ps1" /sc daily /st 02:00 /ru SYSTEM /rl HIGHEST /f REM 每 4 小时增量备份一次 schtasks /create /tn "HourlyCopy" /tr "C:\Scripts\hourly.cmd" /sc hourly /mo 4 /ru SYSTEM /rl HIGHEST /f REM 查看任务 schtasks /query /tn "DailyFullBackup" /v /fo list REM 手动触发一次(验证配置是否正确,强烈建议) schtasks /run /tn "DailyFullBackup" REM 查看最近运行结果 schtasks /query /tn "DailyFullBackup" /fo LIST /v | findstr "上次运行时间 上次结果" REM 删除任务 schtasks /delete /tn "DailyFullBackup" /f
3.2 PowerShell 方式:Register-ScheduledTask
# 推荐:用对象方式创建,可读性远好于 schtasks $action = New-ScheduledTaskAction -Execute "PowerShell.exe" ` -Argument "-NoProfile -ExecutionPolicy Bypass -File C:\Scripts\backup.ps1" $trigger = New-ScheduledTaskTrigger -Daily -At 02:00 $principal = New-ScheduledTaskPrincipal -UserId "SYSTEM" ` -LogonType ServiceAccount -RunLevel Highest $settings = New-ScheduledTaskSettingsSet ` -ExecutionTimeLimit (New-TimeSpan -Hours 6) ` -RestartCount 3 -RestartInterval (New-TimeSpan -Minutes 10) ` -StartWhenAvailable -DontStopIfGoingOnBatteries ` -AllowStartIfOnBatteries Register-ScheduledTask -TaskName "DailyFullBackup" ` -Action $action -Trigger $trigger -Principal $principal ` -Settings $settings -Force # 查询任务与最近运行状态 Get-ScheduledTask -TaskName "DailyFullBackup" Get-ScheduledTaskInfo -TaskName "DailyFullBackup" | Select-Object LastRunTime, LastTaskResult, NextRunTime, NumberOfMissedRuns
配置要点:
- 用 SYSTEM 还是专用账号? 本机备份用 SYSTEM 最简单;要写网络共享(NAS)就必须用域账号,并勾选“不管用户是否登录都要运行”+ 保存密码,且该账号需对共享有写权限。
- LastTaskResult = 0 才是成功;
0x41301表示任务正在运行,0x1通常是脚本异常退出。返回码要看清楚,不要只看“上次运行时间”。 - 开启历史记录:任务计划程序默认关闭历史,右键“启用所有任务历史记录”,排查时才有依据。
四、脚本化备份:文件、数据库与归档
生产环境很少只靠 wbadmin。典型组合是:wbadmin 做系统/卷级保护,robocopy 做文件同步,数据库自带工具做逻辑备份,最后统一归档压缩。
4.1 robocopy 文件同步
REM /MIR 镜像(会删除目标端多余文件,慎用)、/R:3 /W:5 重试、/XD 排除目录、/NP 不显示进度、/LOG 输出日志 robocopy D:\Data \\nas\backup\Data /MIR /R:3 /W:5 /NP /LOG:D:\logs\robocopy.log /XD "D:\Data\tmp" "D:\Data\cache" REM 只复制不删除(更安全的选择) robocopy D:\Data \\nas\backup\Data /E /COPY:DAT /R:3 /W:5 /NP /LOG+:D:\logs\robocopy.log REM 按日期归档:复制近 7 天修改过的文件 robocopy D:\Data \\nas\backup\Incremental /E /MAXAGE:7 /R:2 /W:3 /NP
robocopy 退出码是需要特别注意的地方——0 到 7 都表示成功,8 及以上才是失败。用 if errorlevel 8 判断,不要写 if errorlevel 1。
| 退出码 | 含义 | 处理 |
|---|---|---|
| 0 | 无文件被复制,源与目标一致 | 正常 |
| 1 | 成功复制了一个或多个文件 | 正常 |
| 2 | 检测到目标端多余文件(配合 /PURGE 说明已删除) | 正常 |
| 3 | 1 + 2 | 正常 |
| 4 | 部分文件不匹配 | 正常 |
| 5 / 6 / 7 | 组合状态 | 正常 |
| 8 及以上 | 复制失败(权限、路径不存在、网络中断) | 告警并排查 |
4.2 数据库备份(SQL Server 示例)
REM sqlcmd 执行 T-SQL 备份,COMPRESSION 压缩、INIT 覆盖同名文件 sqlcmd -S localhost -E -Q "BACKUP DATABASE [AppDB] TO DISK='D:\bak\AppDB_Full.bak' WITH COMPRESSION, INIT, STATS=10" REM 事务日志备份(完整恢复模式下,控制日志文件增长的关键) sqlcmd -S localhost -E -Q "BACKUP LOG [AppDB] TO DISK='D:\bak\AppDB_Log.trn' WITH COMPRESSION, NOINIT" REM 验证备份集可用性(只校验不还原) sqlcmd -S localhost -E -Q "RESTORE VERIFYONLY FROM DISK='D:\bak\AppDB_Full.bak'"
4.3 组合成一个完整备份脚本
# C:\Scripts\backup.ps1
$ErrorActionPreference = "Stop"
$date = Get-Date -Format "yyyyMMdd_HHmm"
$dest = "\\nas\backup\$env:COMPUTERNAME\$date"
$log = "C:\Logs\backup_$date.log"
New-Item -ItemType Directory -Path $dest -Force | Out-Null
# 1. 数据库备份
sqlcmd -S localhost -E -Q "BACKUP DATABASE [AppDB] TO DISK='D:\bak\AppDB_$date.bak' WITH COMPRESSION, INIT"
# 2. 文件同步
robocopy D:\Data "$dest\Data" /E /R:3 /W:5 /NP /LOG+:$log
if ($LASTEXITCODE -ge 8) { throw "robocopy failed with exit code $LASTEXITCODE" }
# 3. 系统状态
wbadmin start systemstatebackup -backupTarget:E: -quiet
# 4. 清理 30 天前的备份
Get-ChildItem "\\nas\backup\$env:COMPUTERNAME" -Directory |
Where-Object { $_.CreationTime -lt (Get-Date).AddDays(-30) } |
Remove-Item -Recurse -Force
# 5. 结果通知(可替换为企业微信/钉钉 Webhook)
if ($?) { Write-EventLog -LogName Application -Source "BackupScript" -EntryType Information -EventId 100 -Message "Backup OK: $dest" }
五、恢复演练:备份有效的唯一证明
没有演练过的备份等于没有备份。至少每季度做一次真实恢复,验证 RTO 是否达标。wbadmin 的恢复命令:
REM 1. 列出可用版本 wbadmin get versions REM 2. 展开某个版本,看里面有哪些可恢复项 wbadmin get items -version:08/15/2025-02:00 REM 3. 恢复单个文件/目录到指定位置(不要直接覆盖原位置) wbadmin start recovery -version:08/15/2025-02:00 -itemtype:File -items:D:\Data\config.xml -recoveryTarget:D:\Restore -quiet REM 4. 恢复整个卷 wbadmin start recovery -version:08/15/2025-02:00 -itemtype:Volume -items:D: -recoveryTarget:D: -quiet REM 5. 系统状态恢复(域控需先重启进 DSRM,加 -authsysvol 做权威还原) wbadmin start systemstaterecovery -version:08/15/2025-02:00 -quiet REM 6. 清理损坏的备份编目 wbadmin delete catalog
裸机恢复的操作路径:用 Windows Server 安装介质启动 → 选择“修复计算机” → 疑难解答 → 系统映像恢复 → 选择备份位置。这一步建议实际走一遍,因为现场往往卡在“找不到网卡驱动导致连不上 NAS”。
六、配置步骤清单
- 明确 RPO / RTO,确定备份类型、频率与保留周期(写在文档里,让业务方确认)。
- 规划备份目标:独立本地磁盘 + NAS + 异地/云,确保不与源数据同盘。
Install-WindowsFeature Windows-Server-Backup安装角色功能。- 用
wbadmin start backup手动跑一次全量,确认成功并记下耗时(作为 RTO 依据)。 - 编写备份脚本,包含数据库备份、文件同步、退出码判断、日志记录、失败通知。
- 用
schtasks /create或Register-ScheduledTask注册计划任务,设置 SYSTEM/域账号 + 最高权限 + 重试策略。 schtasks /run手动触发一次,确认LastTaskResult = 0。- 配置保留清理逻辑,避免备份盘自己被写满。
- 配置监控:磁盘余量告警 + 任务失败告警 + 备份文件新鲜度检查(超过 25 小时无新备份即告警)。
- 每季度执行一次真实恢复演练,记录耗时并更新文档。
小结与避坑建议
Windows 服务器设置自动备份,核心三件套是 wbadmin 做系统级保护、robocopy 做文件同步、任务计划程序做编排。策略上遵循 3-2-1,至少保证一份异地副本,工程上把“备份成功”和“备份可恢复”当成两件事分别验证。
实战中最容易踩的坑:
- 只看任务“已运行”,不看返回码。任务跑完了但脚本报错退出,这是最普遍的假成功。一定要检查
LastTaskResult = 0和日志内容。 - robocopy 退出码判断写错。
if errorlevel 1会把正常复制误判为失败;正确写法是if errorlevel 8。 - 用域账号跑计划任务但改了密码。密码变更后任务静默失败,建议使用组托管服务账号(gMSA)或至少在改密流程里加上任务更新步骤。
- 备份脚本权限不足写网络共享。SYSTEM 账号访问网络共享时身份是计算机账号(
DOMAIN\SERVER$),需要在 NAS 上给计算机账号授权。 - 忘记清理旧备份。备份盘写满后新备份全部失败,而告警可能只监控了源盘。保留周期和清理逻辑必须一开始就写进脚本。
- 域控的系统状态恢复有特殊性。需要进目录服务还原模式(DSRM),还原后视情况做权威还原(
-authsysvol),否则可能出现 SYSVOL 复制异常。 - 勒索病毒防护。确保异地备份使用独立凭据,或开启对象存储的不可变(WORM)特性,否则加密会顺着共享一路传到备份。
企业QQ咨询




