Rollback-XiaoshuLegacySyncBridge.ps1 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. [CmdletBinding(SupportsShouldProcess = $true)]
  2. param(
  3. [Parameter(Mandatory = $true)]
  4. [string]$BackupPath,
  5. [string]$ApplicationPoolName = 'XiaoshuLegacySync',
  6. [string]$PhysicalPath = 'C:\inetpub\xiaoshu-sync',
  7. [Parameter(Mandatory = $true)]
  8. [string]$HealthUrl
  9. )
  10. $ErrorActionPreference = 'Stop'
  11. Set-StrictMode -Version Latest
  12. function Assert-Administrator {
  13. $identity = [Security.Principal.WindowsIdentity]::GetCurrent()
  14. $principal = [Security.Principal.WindowsPrincipal]::new($identity)
  15. if (-not $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
  16. throw '请使用“以管理员身份运行”的 PowerShell 执行回滚。'
  17. }
  18. }
  19. Assert-Administrator
  20. Import-Module WebAdministration
  21. $resolvedBackupPath = (Resolve-Path -LiteralPath $BackupPath).Path
  22. if (-not (Test-Path -LiteralPath (Join-Path $resolvedBackupPath 'Xiaoshu.LegacySyncBridge.dll'))) {
  23. throw '回滚目录不是有效的同步桥备份:缺少 Xiaoshu.LegacySyncBridge.dll。'
  24. }
  25. if (-not (Test-Path "IIS:\AppPools\$ApplicationPoolName")) {
  26. throw "IIS 应用池不存在:$ApplicationPoolName"
  27. }
  28. $timestamp = Get-Date -Format 'yyyyMMdd-HHmmss'
  29. $failedPath = "$PhysicalPath.failed-$timestamp"
  30. if ($PSCmdlet.ShouldProcess($PhysicalPath, "从 $resolvedBackupPath 回滚小树旧系统同步桥")) {
  31. Stop-WebAppPool -Name $ApplicationPoolName -ErrorAction SilentlyContinue
  32. if (Test-Path -LiteralPath $PhysicalPath) {
  33. Copy-Item -LiteralPath $PhysicalPath -Destination $failedPath -Recurse -Force
  34. Remove-Item -LiteralPath $PhysicalPath -Recurse -Force
  35. }
  36. New-Item -ItemType Directory -Path $PhysicalPath -Force | Out-Null
  37. Copy-Item -Path (Join-Path $resolvedBackupPath '*') -Destination $PhysicalPath -Recurse -Force
  38. & 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
  39. Start-WebAppPool -Name $ApplicationPoolName
  40. $healthy = $false
  41. foreach ($attempt in 1..12) {
  42. try {
  43. $health = Invoke-RestMethod -Uri $HealthUrl -Method Get -TimeoutSec 10
  44. if ($health.status -eq 'ok' -and $health.service -eq 'xiaoshu-legacy-sync' -and $health.version -eq 'v1') { $healthy = $true; break }
  45. } catch {
  46. Start-Sleep -Seconds 2
  47. }
  48. }
  49. if (-not $healthy) {
  50. throw "文件已回滚,但健康检查没有通过:$HealthUrl。当前失败版本保存在 $failedPath。"
  51. }
  52. Write-Host "同步桥回滚完成:$resolvedBackupPath"
  53. Write-Host "回滚前版本保留在:$failedPath"
  54. }