Windows服务器如何迁移到新主机?系统、应用与数据迁移步骤

老服务器跑了五年,硬盘开始报 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 与回滚预案

  1. 提前降低 DNS TTL。迁移前 24 小时把相关 A 记录 TTL 改成 60 秒,切换时才能快速生效。
  2. 选业务低峰窗口,提前公告,确认数据库无长事务与定时任务。
  3. 停止源机上的应用服务(Stop-Website、net stop),避免切换期间产生新数据。
  4. 执行最后一次增量同步,用 robocopy /L 先试运行确认差异为零。
  5. 修改 DNS 记录或切换 IP。改 IP 的方式:ncpa.cpl → 网卡属性 → IPv4;或 New-NetIPAddress。
  6. 刷新 DNS 缓存:客户端 ipconfig /flushdns,服务端确认记录已更新。
  7. 验证:服务状态、端口监听、应用健康检查、日志有无报错、证书是否正常。
  8. 保留源机 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,第一次迁移可能要花两天,第二次半天就能完成,而且心里有底。