| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263 |
- [CmdletBinding(SupportsShouldProcess = $true)]
- param(
- [Parameter(Mandatory = $true)]
- [string]$BackupPath,
- [string]$ApplicationPoolName = 'XiaoshuLegacySync',
- [string]$PhysicalPath = 'C:\inetpub\xiaoshu-sync',
- [Parameter(Mandatory = $true)]
- [string]$HealthUrl
- )
- $ErrorActionPreference = 'Stop'
- Set-StrictMode -Version Latest
- function Assert-Administrator {
- $identity = [Security.Principal.WindowsIdentity]::GetCurrent()
- $principal = [Security.Principal.WindowsPrincipal]::new($identity)
- if (-not $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
- throw '请使用“以管理员身份运行”的 PowerShell 执行回滚。'
- }
- }
- Assert-Administrator
- Import-Module WebAdministration
- $resolvedBackupPath = (Resolve-Path -LiteralPath $BackupPath).Path
- if (-not (Test-Path -LiteralPath (Join-Path $resolvedBackupPath 'Xiaoshu.LegacySyncBridge.dll'))) {
- throw '回滚目录不是有效的同步桥备份:缺少 Xiaoshu.LegacySyncBridge.dll。'
- }
- if (-not (Test-Path "IIS:\AppPools\$ApplicationPoolName")) {
- throw "IIS 应用池不存在:$ApplicationPoolName"
- }
- $timestamp = Get-Date -Format 'yyyyMMdd-HHmmss'
- $failedPath = "$PhysicalPath.failed-$timestamp"
- if ($PSCmdlet.ShouldProcess($PhysicalPath, "从 $resolvedBackupPath 回滚小树旧系统同步桥")) {
- Stop-WebAppPool -Name $ApplicationPoolName -ErrorAction SilentlyContinue
- if (Test-Path -LiteralPath $PhysicalPath) {
- Copy-Item -LiteralPath $PhysicalPath -Destination $failedPath -Recurse -Force
- Remove-Item -LiteralPath $PhysicalPath -Recurse -Force
- }
- New-Item -ItemType Directory -Path $PhysicalPath -Force | Out-Null
- Copy-Item -Path (Join-Path $resolvedBackupPath '*') -Destination $PhysicalPath -Recurse -Force
- & icacls.exe $PhysicalPath /inheritance:r /grant:r "SYSTEM:(OI)(CI)F" "Administrators:(OI)(CI)F" "IIS AppPool\${ApplicationPoolName}:(OI)(CI)RX" /T /C | Out-Null
- Start-WebAppPool -Name $ApplicationPoolName
- $healthy = $false
- foreach ($attempt in 1..12) {
- try {
- $health = Invoke-RestMethod -Uri $HealthUrl -Method Get -TimeoutSec 10
- if ($health.status -eq 'ok' -and $health.service -eq 'xiaoshu-legacy-sync' -and $health.version -eq 'v1') { $healthy = $true; break }
- } catch {
- Start-Sleep -Seconds 2
- }
- }
- if (-not $healthy) {
- throw "文件已回滚,但健康检查没有通过:$HealthUrl。当前失败版本保存在 $failedPath。"
- }
- Write-Host "同步桥回滚完成:$resolvedBackupPath"
- Write-Host "回滚前版本保留在:$failedPath"
- }
|