一、自动化巡检脚本(Check-RecoveryStatus.ps1)
功能定位
定期检查 Windows 11 设备的恢复功能状态(系统还原、文件历史记录、WinRE 可用性),发现异常(如还原点不足、备份超时)自动记录告警日志,支持批量部署到域内设备。
脚本代码(可直接复制运行)
<#
.SYNOPSIS
Windows 11恢复功能自动化巡检脚本
.DESCRIPTION
检查系统还原启用状态、还原点数量、文件历史记录备份状态、WinRE可用性
.REQUIREMENTS
1. Windows 11 企业版/专业版(22H2及以上)
2. 管理员权限运行
3. 域内设备需能访问日志共享路径(可选)
#>
# -------------------------- 配置区(用户可修改)--------------------------
$LogPath = "D:\IT_Logs" # 本地日志路径(若不存在自动创建)
$LogFileName = "Recovery_Check_$(Get-Date -Format 'yyyyMMdd').log" # 日志文件名(含日期)
$MinRestorePoints = 3 # 最小还原点数量(低于此值告警)
$MaxBackupAge = 24 # 文件历史记录最大备份间隔(小时,超此时长告警)
$NASLogPath = "\\NAS01\IT_Logs" # 日志同步到NAS路径(可选,留空则不同步)
# -------------------------------------------------------------------------
# 1. 权限检查(必须管理员运行)
If (-not ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) {
Write-Host "错误:需以管理员权限运行!" -ForegroundColor Red
Exit 1
}
# 2. 创建日志目录
If (-not (Test-Path $LogPath)) { New-Item -Path $LogPath -ItemType Directory -Force | Out-Null }
$FullLogPath = Join-Path $LogPath $LogFileName
# 3. 日志写入函数
Function Write-Log {
Param($Message, $Type)
$Time = Get-Date -Format 'yyyy-MM-dd HH:mm:ss'
Switch ($Type) {
"Info" { $Content = "[$Time][INFO] $Message"; Write-Host $Content -ForegroundColor Green }
"Warn" { $Content = "[$Time][WARN] $Message"; Write-Host $Content -ForegroundColor Yellow }
"Error" { $Content = "[$Time][ERROR] $Message"; Write-Host $Content -ForegroundColor Red }
}
Add-Content -Path $FullLogPath -Value $Content
}
# 4. 检查系统还原状态
Write-Log "=== 开始检查系统还原状态 ===" "Info"
Try {
# 获取系统还原配置(C盘)
$RestoreConfig = Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\SystemRestore" -ErrorAction Stop
$C driveProtect = (Get-ComputerRestorePoint | Where-Object { $_.VolumeName -eq "C:" }).Count
# 检查系统还原是否启用
If ($RestoreConfig.DisableSR -eq 1) {
Write-Log "系统还原未启用(C盘),需检查组策略同步!" "Error"
} Else {
Write-Log "系统还原已启用(C盘)" "Info"
# 检查还原点数量
If ($CdriveProtect -lt $MinRestorePoints) {
Write-Log "C盘还原点数量不足(当前:$CdriveProtect,最小要求:$MinRestorePoints),建议手动创建还原点!" "Warn"
} Else {
Write-Log "C盘还原点数量正常(当前:$CdriveProtect)" "Info"
# 显示最近3个还原点
$RecentPoints = Get-ComputerRestorePoint | Sort-Object -Property CreationTime -Descending | Select-Object -First 3
ForEach ($Point in $RecentPoints) {
Write-Log "最近还原点:$($Point.Description)(创建时间:$($Point.CreationTime))" "Info"
}
}
}
} Catch {
Write-Log "检查系统还原失败:$($_.Exception.Message)" "Error"
}
# 5. 检查文件历史记录状态
Write-Log "`n=== 开始检查文件历史记录状态 ===" "Info"
Try {
# 获取文件历史记录配置
$FHConfig = Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\FileHistory\Configuration" -ErrorAction Stop
$LastBackupTime = Get-WmiObject -Namespace "root\cimv2\mdm\dmmap" -Class "MDM_FileHistory" -ErrorAction Stop | Select-Object -ExpandProperty LastBackupTime
# 检查文件历史记录是否启用
If ($FHConfig.Enabled -eq 0) {
Write-Log "文件历史记录未启用,需检查组策略!" "Error"
} Else {
Write-Log "文件历史记录已启用(备份目标:$($FHConfig.BackupTarget))" "Info"
# 检查最近备份时间
If (-not $LastBackupTime) {
Write-Log "未检测到历史备份记录,可能首次配置未备份!" "Warn"
} Else {
$BackupAge = (Get-Date - $LastBackupTime).TotalHours
If ($BackupAge -gt $MaxBackupAge) {
Write-Log "最近备份超时(上次备份:$LastBackupTime,间隔:$([Math]::Round($BackupAge,1))小时,最大允许:$MaxBackupAge小时)" "Warn"
} Else {
Write-Log "最近备份正常(上次备份:$LastBackupTime,间隔:$([Math]::Round($BackupAge,1))小时)" "Info"
}
}
}
} Catch {
Write-Log "检查文件历史记录失败:$($_.Exception.Message)" "Error"
}
# 6. 检查WinRE可用性
Write-Log "`n=== 开始检查WinRE状态 ===" "Info"
Try {
$WinREStatus = cmd /c "ReAgentC /info" 2>&1
If ($WinREStatus -match "WinRE 状态:.*已启用") {
Write-Log "WinRE已启用(恢复分区:$($WinREStatus -match '恢复映像位置:.*' | Out-String))" "Info"
} Else {
Write-Log "WinRE未启用,需执行命令修复:ReAgentC /enable" "Error"
}
} Catch {
Write-Log "检查WinRE失败:$($_.Exception.Message)" "Error"
}
# 7. 同步日志到NAS(可选)
If ($NASLogPath -and (Test-Path $NASLogPath)) {
Try {
Copy-Item -Path $FullLogPath -Destination $NASLogPath -Force
Write-Log "`n日志已同步到NAS(路径:$NASLogPath)" "Info"
} Catch {
Write-Log "日志同步NAS失败:$($_.Exception.Message)" "Warn"
}
} ElseIf ($NASLogPath -and (-not (Test-Path $NASLogPath))) {
Write-Log "`nNAS日志路径不存在($NASLogPath),跳过同步" "Warn"
}
Write-Log "`n=== 巡检完成,日志路径:$FullLogPath ===" "Info"
使用说明
- 参数配置:修改脚本开头「配置区」变量(如LogPath设为企业实际日志路径,NASLogPath填 NAS 共享路径)。
- 运行方式:
-
- 手动运行:右键 PowerShell→「以管理员身份运行」→执行.\Check-RecoveryStatus.ps1。
-
- 域批量部署:通过 Intune 或组策略 “启动脚本” 推送,设置为每日凌晨 3 点自动运行。
- 日志查看:本地日志存于D:\IT_Logs(可修改),NAS 同步日志便于集中管理,异常项标红 / 黄,一目了然。
二、自动化备份脚本(Auto-BackupRecovery.ps1)
功能定位
自动执行系统映像备份(全量)、文件历史记录完整性校验,清理旧备份(按保留天数),支持故障自动重试,适配企业级定期备份需求。
脚本代码(可直接复制运行)
<#
.SYNOPSIS
Windows 11恢复功能自动化备份脚本
.DESCRIPTION
1. 执行系统映像备份到NAS
2. 校验文件历史记录备份完整性
3. 清理超期旧备份(系统映像+文件历史记录)
.REQUIREMENTS
1. Windows 11 企业版/专业版(22H2及以上)
2. 管理员权限运行
3. 备份目标NAS路径可访问且有读写权限
#>
# -------------------------- 配置区(用户可修改)--------------------------
$LogPath = "D:\IT_Logs" # 本地日志路径
$BackupTarget = "\\NAS01\SystemBackup" # 系统映像备份目标(NAS路径)
$FHBackupTarget = "\\NAS01\Backup" # 文件历史记录备份目标(需与组策略配置一致)
$BackupRetentionDays = 30 # 备份保留天数(超期自动删除)
$MaxRetryCount = 2 # 备份失败重试次数
$LogFileName = "Recovery_Backup_$(Get-Date -Format 'yyyyMMdd').log"
# -------------------------------------------------------------------------
# 1. 权限检查与日志初始化
If (-not ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) {
Write-Host "错误:需以管理员权限运行!" -ForegroundColor Red
Exit 1
}
If (-not (Test-Path $LogPath)) { New-Item -Path $LogPath -ItemType Directory -Force | Out-Null }
$FullLogPath = Join-Path $LogPath $LogFileName
# 2. 日志写入函数(同巡检脚本)
Function Write-Log {
Param($Message, $Type)
$Time = Get-Date -Format 'yyyy-MM-dd HH:mm:ss'
Switch ($Type) {
"Info" { $Content = "[$Time][INFO] $Message"; Write-Host $Content -ForegroundColor Green }
"Warn" { $Content = "[$Time][WARN] $Message"; Write-Host $Content -ForegroundColor Yellow }
"Error" { $Content = "[$Time][ERROR] $Message"; Write-Host $Content -ForegroundColor Red }
}
Add-Content -Path $FullLogPath -Value $Content
}
# 3. 检查备份目标可用性
Write-Log "=== 开始备份前检查 ===" "Info"
$BackupAvailable = $true
# 检查系统映像备份目标
If (-not (Test-Path $BackupTarget)) {
Write-Log "系统映像备份目标不可达($BackupTarget),请检查NAS连接!" "Error"
$BackupAvailable = $false
}
# 检查文件历史记录备份目标
If (-not (Test-Path $FHBackupTarget)) {
Write-Log "文件历史记录备份目标不可达($FHBackupTarget),请检查NAS权限!" "Error"
$BackupAvailable = $false
}
If (-not $BackupAvailable) {
Write-Log "备份目标不可用,终止备份流程!" "Error"
Exit 1
}
# 4. 执行系统映像备份(全量,含C盘关键分区)
Write-Log "`n=== 开始执行系统映像备份 ===" "Info"
$BackupSuccess = $false
$RetryCount = 0
While ($RetryCount -le $MaxRetryCount -and -not $BackupSuccess) {
Try {
$BackupName = "Win11_SysImage_$(Get-Date -Format 'yyyyMMdd_HHmmss')"
$BackupPath = Join-Path $BackupTarget $BackupName
# 执行系统映像备份(wbAdmin命令,静默模式)
cmd /c "wbAdmin start backup -backupTarget:$BackupTarget -include:C: -allCritical -quiet -backupName:$BackupName" 2>&1
$ExitCode = $LASTEXITCODE
If ($ExitCode -eq 0) {
Write-Log "系统映像备份成功(路径:$BackupPath)" "Info"
$BackupSuccess = $true
} Else {
Throw "wbAdmin命令执行失败(退出码:$ExitCode)"
}
} Catch {
$RetryCount++
If ($RetryCount -le $MaxRetryCount) {
Write-Log "备份失败($($_.Exception.Message)),第$RetryCount次重试(共$MaxRetryCount次)" "Warn"
Start-Sleep -Seconds 60 # 重试前等待60秒
} Else {
Write-Log "备份失败(已重试$MaxRetryCount次),请手动检查wbAdmin日志!" "Error"
}
}
}
# 5. 校验文件历史记录备份完整性
Write-Log "`n=== 开始校验文件历史记录备份 ===" "Info"
Try {
# 获取当前用户的文件历史记录备份目录(按用户名隔离)
$UserName = $env:USERNAME
$UserFHPath = Join-Path $FHBackupTarget $UserName
If (-not (Test-Path $UserFHPath)) {
Write-Log "当前用户($UserName)无文件历史记录备份目录,可能首次备份未完成!" "Warn"
} Else {
# 检查最近备份文件(.edb数据库文件,文件历史记录核心)
$FHDBFile = Get-ChildItem -Path $UserFHPath -Recurse -Filter "Catalog1.edb" | Sort-Object LastWriteTime -Descending | Select-Object -First 1
If (-not $FHDBFile) {
Write-Log "未找到文件历史记录数据库文件,备份可能损坏!" "Error"
} Else {
$FHLastWrite = $FHDBFile.LastWriteTime
$FH Age = (Get-Date - $FHLastWrite).TotalHours
If ($FH Age -le 24) { # 24小时内有更新视为正常
Write-Log "文件历史记录备份正常(最近更新:$FHLastWrite,间隔:$([Math]::Round($FHAge,1))小时)" "Info"
} Else {
Write-Log "文件历史记录备份超时(最近更新:$FHLastWrite,间隔:$([Math]::Round($FHAge,1))小时)" "Warn"
# 触发一次文件历史记录立即备份
Write-Log "尝试触发立即备份..." "Info"
Start-Process -FilePath "fhmanagew.exe" -ArgumentList "/backupnow" -NoNewWindow -Wait
Write-Log "立即备份命令已执行,建议后续检查结果" "Info"
}
}
}
} Catch {
Write-Log "文件历史记录校验失败:$($_.Exception.Message)" "Error"
}
# 6. 清理超期旧备份(系统映像+文件历史记录)
Write-Log "`n=== 开始清理超期旧备份 ===" "Info"
$ExpireDate = (Get-Date).AddDays(-$BackupRetentionDays)
# 清理系统映像旧备份
$OldSysBackups = Get-ChildItem -Path $BackupTarget -Directory | Where-Object { $_.Name -match "Win11_SysImage_" -and $_.CreationTime -lt $ExpireDate }
If ($OldSysBackups.Count -gt 0) {
ForEach ($OldBackup in $OldSysBackups) {
Try {
Remove-Item -Path $OldBackup.FullName -Recurse -Force -ErrorAction Stop
Write-Log "已删除超期系统映像备份:$($OldBackup.Name)(创建时间:$($OldBackup.CreationTime))" "Info"
} Catch {
Write-Log "删除超期备份失败($($OldBackup.Name)):$($_.Exception.Message)" "Warn"
}
}
} Else {
Write-Log "无超期系统映像备份(保留天数:$BackupRetentionDays天)" "Info"
}
# 清理文件历史记录旧备份(按修改时间)
$OldFHBackups = Get-ChildItem -Path $FHBackupTarget -Recurse -File | Where-Object { $_.LastWriteTime -lt $ExpireDate }
If ($OldFHBackups.Count -gt 0) {
$OldFHSize = ($OldFHBackups | Measure-Object -Property Length -Sum).Sum / 1GB
$OldFHBackups | Remove-Item -Force -ErrorAction SilentlyContinue
Write-Log "已删除超期文件历史记录备份(共$($OldFHBackups.Count)个文件,约$([Math]::Round($OldFHSize,2))GB)" "Info"
} Else {
Write-Log "无超期文件历史记录备份" "Info"
}
Write-Log "`n=== 备份与清理流程完成,日志路径:$FullLogPath ===" "Info"
使用说明
- 参数配置:重点修改「配置区」的BackupTarget(系统映像备份 NAS 路径)和FHBackupTarget(需与组策略中文件历史记录备份路径一致)。
- 运行方式:
-
- 手动测试:管理员 PowerShell 执行.\Auto-BackupRecovery.ps1,观察日志确认备份是否成功。
-
- 定时任务:在 Windows 任务计划程序中创建任务,设置 “每日凌晨 2 点” 运行,触发器设为 “唤醒计算机运行此任务”,确保设备通电。
- 关键注意事项:
-
- 系统映像备份需至少 100GB 空闲空间(根据 C 盘占用调整),NAS 需开启 SMB 共享并给域用户 “完全控制” 权限。
-
- 备份清理会删除超期文件,建议先在测试环境验证保留天数(如先设为 7 天测试),避免误删重要备份。
三、脚本部署与运维建议
1. 域环境批量部署
- 通过 Intune 推送:
-
- 登录 Intune 控制台→「设备→Windows→电源 Shell 脚本」→上传两个脚本。
-
- 配置脚本运行权限为 “管理员”,分配给 “Windows 11 设备” 组。
-
- 巡检脚本设为 “每日运行”,备份脚本设为 “每周日凌晨运行”(避免业务时段占用资源)。
- 通过组策略启动脚本:
-
- 域控制器打开「组策略管理」→编辑目标 GPO→「计算机配置→Windows 设置→脚本(启动 / 关机)」。
-
- 将脚本复制到域控制器SysVol\domain.com\Scripts路径,在 “关机脚本” 中添加备份脚本(避免开机占用资源),“启动脚本” 添加巡检脚本。
2. 常见问题排查
|
问题现象 |
可能原因 |
解决方案 |
|
脚本运行提示 “权限不足” |
未以管理员身份运行 |
右键 PowerShell→“以管理员身份运行”,或在任务计划中勾选 “使用最高权限运行” |
|
备份失败提示 “无法访问备份目标” |
NAS 共享权限不足 |
给域用户组分配 NAS 备份目录的 “完全控制” 权限,测试net use \\NAS01\Backup是否能连接 |
|
巡检脚本未检测到还原点 |
组策略未同步成功 |
客户端执行gpupdate /force强制同步,检查组策略是否链接到正确 OU |
|
清理旧备份时删除失败 |
文件被占用(如正在备份) |
调整清理时间(如备份完成 1 小时后再清理),或在脚本中添加-ErrorAction SilentlyContinue忽略占用文件 |
3. 脚本维护
- 定期更新:每季度检查一次脚本兼容性(如 Windows 11 更新后 wbAdmin 命令是否变化),更新后重新推送。
- 日志审计:每周查看 NAS 集中日志,统计备份成功率(目标 99% 以上),对连续失败的设备安排人工排查。
- 参数优化:根据企业实际情况调整备份保留天数(如核心设备保留 60 天,普通设备保留 30 天)。