Rollback-XiaoshuLegacySyncBridge.ps1 2.4 KB

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