老服务器跑了五年,硬盘开始报 SMART 警告;机房要搬迁;云上要换更高配的机型——于是有了“把这台 Windows 服务器搬到新主机”的需求。这件事的难点从来不是“拷文件”,而是如何在不中断业务、不丢配置、不留隐患的前提下完成切换,并且随时能回滚。
本文先给出迁移方案选型(整机镜像 / 系统级 / 应用级),然后是一份完整的迁移前盘点清单,接着分别讲 wbadmin 裸机恢复、DISM 映像、robocopy 数据迁移、IIS 与 SQL 的应用迁移做法,最后是切换、验证与回滚。
一、方案选型:三种迁移路径
| 方案 | 做法 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|---|
| 整机镜像(P2V / V2V) | disk2vhd 或厂商工具把整盘打成 VHD/映像,新机直接挂载 | 硬件换代、上云、虚拟化整合 | 最省事,配置零丢失 | 驱动不兼容可能蓝屏 0x7B;会带入历史垃圾 |
| 系统级迁移 | wbadmin 裸机恢复 或 DISM 捕获/应用映像 | 同代硬件、同版本系统 | 系统状态完整,含注册表与角色 | 目标盘需重新分区,需处理引导 |
| 应用级重建 | 新机干净装系统,逐个装角色、迁移数据与配置 | 跨大版本升级、想顺便做标准化 | 最干净,可解决历史遗留问题 | 耗时最长,配置遗漏风险高 |
经验判断:同版本、同代硬件优先整机镜像;跨硬件平台或要升级系统版本,走应用级重建。域控制器(AD DS)不建议用整机镜像迁移,正确做法是新建域控、复制目录后再降级旧域控。
二、迁移前:盘点比动手重要
迁移出问题的原因,八成是“漏了某个东西”。把下面这份盘点结果存成文档,迁移后逐条核对。
# 1. 角色与功能清单
Get-WindowsFeature | Where-Object Installed | Select-Object Name, DisplayName | Export-Csv C:\mig\features.csv -NoTypeInformation
# 2. 网络配置(IP、网关、DNS、网卡名)
Get-NetIPConfiguration | Format-List
Get-DnsClientServerAddress | Format-Table InterfaceAlias, ServerAddresses
ipconfig /all > C:\mig\ipconfig.txt
# 3. 磁盘与卷
Get-Volume | Format-Table -AutoSize
Get-Partition | Select-Object DiskNumber, PartitionNumber, DriveLetter, Size | Format-Table -AutoSize
# 4. 共享
Get-SmbShare | Select-Object Name, Path, Description | Export-Csv C:\mig\shares.csv -NoTypeInformation
net share > C:\mig\netshare.txt
# 5. 服务(重点关注非微软自带的服务)
Get-Service | Where-Object { $_.Status -eq 'Running' } | Select-Object Name, DisplayName, StartType |
Export-Csv C:\mig\services.csv -NoTypeInformation
# 6. 计划任务
Get-ScheduledTask | Where-Object { $_.State -ne 'Disabled' -and $_.TaskPath -notlike '\Microsoft\*' } |
Select-Object TaskName, TaskPath, State | Export-Csv C:\mig\tasks.csv -NoTypeInformation
schtasks /query /fo LIST /v > C:\mig\schtasks.txt
# 7. 证书、驱动、补丁、本地账号
Get-ChildItem cert:\LocalMachine\My | Select-Object Subject, Thumbprint, NotAfter
driverquery /v /fo csv > C:\mig\drivers.csv
Get-HotFix | Sort-Object InstalledOn -Descending | Select-Object -First 20 | Export-Csv C:\mig\hotfix.csv -NoTypeInformation
Get-LocalUser | Select-Object Name, Enabled, LastLogon
Get-LocalGroup | Select-Object Name
REM 导出防火墙规则、网络配置、IIS 配置 netsh advfirewall export "C:\mig\fwrules.wfw" netsh -c interface dump > C:\mig\netcfg.txt %windir%\system32\inetsrv\appcmd list site /config /xml > C:\mig\iis_sites.xml %windir%\system32\inetsrv\appcmd list apppool /config /xml > C:\mig\iis_pools.xml
还要额外记录:应用连接字符串里的数据库地址、第三方 Agent 的授权信息、License 与激活状态、定时任务里写的账号密码、hosts 文件、磁盘映射(net use)。
REM 查看激活状态(迁移后常需重新激活) slmgr /dlv slmgr /xpr
三、方案一:整机镜像迁移(disk2vhd / VHD)
Sysinternals 的 disk2vhd 可以在线把正在运行的系统卷打成 VHD/VHDX,无需停机。生成的 VHD 挂载到 Hyper-V 或上传到云平台即可启动。
REM disk2vhd 命令行用法(体积较大的系统盘耗时较长) disk2vhd64.exe C: D: E:\mig\server01.vhdx REM 挂载 VHD 做离线检查(确认没有坏文件) dism /mount-image /imagefile:E:\mig\server01.vhdx /index:1 /mountdir:C:\mount
关键风险是存储控制器驱动:原机用的 RAID 卡驱动在新机上不存在,启动会直接蓝屏 0x0000007B INACCESSIBLE_BOOT_DEVICE。规避办法有两个:一是迁移前在原机安装目标平台的标准驱动(如 Hyper-V 的 vmbus、storvsc);二是先挂载 VHD 到临时机,用 DISM 离线注入驱动:
REM 离线注入驱动到已挂载的映像 dism /image:C:\mount /add-driver /driver:D:\drivers\viostor.inf /forceunsigned dism /image:C:\mount /add-driver /driver:D:\drivers /recurse REM 卸载并提交 dism /unmount-image /mountdir:C:\mount /commit
如果目标机是全新裸机,也可以用 sysprep 做通用化(会重置 SID、机器名、驱动,需要重新加域):C:\Windows\System32\Sysprep\sysprep.exe /generalize /oobe /shutdown。注意:sysprep 会重置很多配置,域控、SQL Server、Exchange 等角色不支持 sysprep。
四、方案二:系统级迁移(wbadmin / DISM)
4.1 用 wbadmin 做裸机恢复
这是微软官方支持的同版本迁移方式:在源机做“裸机恢复”备份,在新机上从安装介质启动并恢复。
REM 源机:备份系统状态 + 关键卷到外置存储或网络共享 wbadmin start backup -backupTarget:\\nas\mig -include:C:,D: -allCritical -systemState -quiet REM 备份到网络共享时注意:同一路径会被后续备份覆盖,不同机器用不同子目录 wbadmin start backup -backupTarget:\\nas\mig$\server01 -include:C:,D: -allCritical -quiet REM 查看备份版本,记下 version 标识符 wbadmin get versions
新机恢复步骤:用同版本 Windows Server 安装介质启动 → 修复计算机 → 疑难解答 → 系统映像恢复 → 选择网络位置或外置盘上的备份 → 若目标是不同硬件,勾选“只还原系统驱动器”并按需格式化分区。恢复完成后安装新硬件驱动。
4.2 用 DISM 捕获与应用映像
更灵活的做法是在 WinPE 下捕获 WIM 映像,再应用到新机磁盘,最后用 bcdboot 重建引导。
REM 在 WinPE 下捕获系统卷(源盘为 C:,映像存外置盘 D:) dism /capture-image /imagefile:D:\mig\server01.wim /capturedir:C:\ /name:"Server01-OS" /description:"migration" /compress:max /checkintegrity REM 新机:分区后应用映像到 W: diskpart REM select disk 0 > clean > convert gpt > create partition efi size=100 > format fs=fat32 quick > assign letter=S REM create partition msr size=16 > create partition primary > format fs=ntfs quick > assign letter=W > exit dism /apply-image /imagefile:D:\mig\server01.wim /index:1 /applydir:W:\ /checkintegrity REM 重建引导(UEFI 用 /f UEFI,Legacy BIOS 用 /f BIOS) bcdboot W:\Windows /s S: /f UEFI REM 离线注入新硬件驱动 dism /image:W:\ /add-driver /driver:D:\drivers /recurse
五、方案三:应用级迁移(推荐给要升级的场景)
新机装干净系统 → 装角色 → 迁数据 → 迁配置 → 切流量。这是最可控的方式。
5.1 数据迁移:robocopy 保留 ACL
REM 首次全量:保留安全描述符、所有者、审核信息、时间戳 robocopy D:\Data \\newserver\D$\Data /E /COPYALL /SEC /SECFIX /TIMFIX /R:3 /W:5 /MT:32 /LOG:C:\mig\robocopy_full.log /NP /XD "D:\Data\tmp" REM 增量补差(切换窗口内执行,通常只需几分钟) robocopy D:\Data \\newserver\D$\Data /E /COPYALL /SEC /R:1 /W:1 /MT:32 /XO /LOG:C:\mig\robocopy_diff.log /NP REM 使用备份模式绕过 NTFS 权限限制(管理员运行,可读取无权限文件) robocopy D:\Data \\newserver\D$\Data /E /COPYALL /B /R:2 /W:2 /LOG:C:\mig\robocopy_b.log REM 校验:对比文件数与总大小 robocopy D:\Data \\newserver\D$\Data /L /E /NP /LOG:C:\mig\robocopy_list.log
参数说明:/COPYALL 等价于 /COPY:DATSOU(数据、属性、时间戳、安全 ACL、所有者、审核信息),迁移共享目录时必须加,否则目标端权限全丢;/MT:32 多线程能显著提速;/L 是试运行,只列出不实际操作,用来校验很安全。
REM 单独备份与还原 NTFS 权限(robocopy 之外的双保险) icacls D:\Data /save C:\mig\acl_data.txt /T /C icacls D:\Data /restore C:\mig\acl_data.txt /T /C
5.2 IIS 站点迁移
REM 源机导出 %windir%\system32\inetsrv\appcmd list site /config /xml > C:\mig\sites.xml %windir%\system32\inetsrv\appcmd list apppool /config /xml > C:\mig\pools.xml REM 新机导入(先确保物理路径已 robocopy 到位) %windir%\system32\inetsrv\appcmd add apppool /in < C:\mig\pools.xml %windir%\system32\inetsrv\appcmd add site /in < C:\mig\sites.xml REM 或用 Web Deploy 整站同步(需两端安装 Web Deploy) msdeploy -verb:sync -source:webserver,computername=oldserver -dest:webserver,computername=newserver -enableLink:AppPoolExtension -whatif msdeploy -verb:sync -source:webserver,computername=oldserver -dest:webserver,computername=newserver -enableLink:AppPoolExtension
REM 迁移证书(导出 pfx,含私钥) certutil -exportpfx -p "P@ssw0rd" My 1a2b3c4d5e6f cert.pfx REM 新机导入 certutil -importpfx -p "P@ssw0rd" cert.pfx NoRoot
5.3 SQL Server 迁移
REM 备份-还原法(最通用) sqlcmd -S OLDSERVER -E -Q "BACKUP DATABASE [AppDB] TO DISK='\\nas\mig\AppDB.bak' WITH COMPRESSION, INIT, COPY_ONLY" sqlcmd -S NEWSERVER -E -Q "RESTORE FILELISTONLY FROM DISK='\\nas\mig\AppDB.bak'" sqlcmd -S NEWSERVER -E -Q "RESTORE DATABASE [AppDB] FROM DISK='\\nas\mig\AppDB.bak' WITH MOVE 'AppDB' TO 'E:\Data\AppDB.mdf', MOVE 'AppDB_log' TO 'F:\Log\AppDB.ldf', RECOVERY" sqlcmd -S NEWSERVER -E -Q "RESTORE VERIFYONLY FROM DISK='\\nas\mig\AppDB.bak'"
登录后记:SQL Server 登录名(Login)不会随数据库一起迁移,孤立用户(orphaned user)会导致应用连不上。用微软官方 sp_help_revlogin 脚本在源机生成登录名创建脚本(含 SID 和密码哈希),在新机执行,再用 sp_change_users_login 或 ALTER USER ... WITH LOGIN = ... 修复映射。
REM 修复孤立用户 sqlcmd -S NEWSERVER -E -Q "USE [AppDB]; EXEC sp_change_users_login 'Report'" sqlcmd -S NEWSERVER -E -Q "USE [AppDB]; ALTER USER appuser WITH LOGIN = appuser"
5.4 配置还原
REM 还原网络配置与防火墙规则 netsh -f C:\mig\netcfg.txt netsh advfirewall import "C:\mig\fwrules.wfw" REM 还原共享(注册表方式,导 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer\Shares) reg export "HKLM\SYSTEM\CurrentControlSet\Services\LanmanServer\Shares" C:\mig\shares.reg /y reg import C:\mig\shares.reg net stop server && net start server REM 还原 hosts copy C:\Windows\System32\drivers\etc\hosts \\newserver\C$\Windows\System32\drivers\etc\hosts
六、切换:DNS、IP 与回滚预案
- 提前降低 DNS TTL。迁移前 24 小时把相关 A 记录 TTL 改成 60 秒,切换时才能快速生效。
- 选业务低峰窗口,提前公告,确认数据库无长事务与定时任务。
- 停止源机上的应用服务(
Stop-Website、net stop),避免切换期间产生新数据。 - 执行最后一次增量同步,用
robocopy /L先试运行确认差异为零。 - 修改 DNS 记录或切换 IP。改 IP 的方式:
ncpa.cpl→ 网卡属性 → IPv4;或New-NetIPAddress。 - 刷新 DNS 缓存:客户端
ipconfig /flushdns,服务端确认记录已更新。 - 验证:服务状态、端口监听、应用健康检查、日志有无报错、证书是否正常。
- 保留源机 7 天不下线,确认无误后再回收,这是唯一的低成本保险。
# 切换后验证脚本
Get-Service | Where-Object { $_.Status -ne 'Running' -and $_.StartType -eq 'Automatic' }
Get-NetTCPConnection -State Listen | Sort-Object LocalPort |
Select-Object LocalAddress, LocalPort, OwningProcess
Test-NetConnection newserver.contoso.com -Port 443
Test-NetConnection newserver.contoso.com -Port 80
# 检查最近错误日志
Get-WinEvent -FilterHashtable @{LogName='System','Application'; Level=1,2; StartTime=(Get-Date).AddHours(-2)} -MaxEvents 30 |
Select-Object TimeCreated, LogName, Id, ProviderName, Message
回滚条件要提前写死:例如“切换后 30 分钟内核心接口成功率低于 99%”即回滚。回滚动作就是把 DNS 或 IP 改回源机,因为源机一直在线,通常几分钟即可恢复。
小结与避坑建议
Windows 服务器迁移到新主机,技术难点不在工具,而在完整盘点 + 充分演练 + 可回滚。小型环境推荐“wbadmin 裸机恢复”;要升级系统或清理历史包袱,就用“干净安装 + robocopy 迁数据 + appcmd 迁配置”的应用级方案;上云或虚拟化整合用 disk2vhd 打镜像,但一定先解决存储驱动问题。
最容易翻车的地方:
- 忘记迁移 ACL。robocopy 不加
/COPYALL,权限全部丢失,共享访问集体报“拒绝访问”,而且当时不一定能发现。切换后务必抽查几个目录的icacls。 - SQL 登录名没迁。数据库还原成功但应用连不上,八成是孤立用户。用 sp_help_revlogin 提前处理。
- 存储控制器驱动不匹配导致 0x7B 蓝屏。镜像迁移前先注入目标平台驱动,或先在原机预装。
- 没提前降 TTL。TTL 是 3600 秒时,切换后部分地区要一小时才能访问到新机,白白延长故障时间。
- 迁移当天还在写数据。必须停服或进入只读窗口,否则增量永远追不上。数据库可用日志传送/镜像方式缩短窗口。
- 域控不要用镜像迁。USN 回滚会导致目录不一致,属于灾难级故障。正确做法是新建域控再降级旧的。
- 迁移完立刻下线旧机。至少保留 7 天,很多隐藏依赖(定时任务、备份脚本、外部回调)会在一周后才暴露。
- 别忘许可证与激活。硬件变化可能触发重新激活,KMS 环境确认能联系到 KMS 服务器,MAK 环境确认激活次数够用。
把盘点清单、迁移脚本、验证脚本和回滚预案合成一份 Runbook,第一次迁移可能要花两天,第二次半天就能完成,而且心里有底。
企业QQ咨询




