$ErrorActionPreference = "Stop" # === 由 CertCenter 生成 === $Domain = "{{ domain }}" $BaseUrl = "{{ base_url }}" $Token = "{{ token }}" $CertDir = "{{ cert_dir }}" $CheckCmd = "{{ check_cmd }}" $ReloadCmd = "{{ reload_cmd }}" # =========================== $EncodedDomain = [System.Uri]::EscapeDataString($Domain) $TmpDir = "$env:TEMP\cert-sync-$($Domain -replace '[*\.]','_')" $VersionFile = "$CertDir\.version" New-Item -ItemType Directory -Force -Path $CertDir, $TmpDir | Out-Null $headers = @{ Authorization = "Bearer $Token" } # 跳过 TLS 证书验证(CertCenter 初期可能使用自签证书) [System.Net.ServicePointManager]::ServerCertificateValidationCallback = { $true } # 1. 检查版本 $remote = (Invoke-WebRequest -Uri "$BaseUrl/api/version?domain=$EncodedDomain" -Headers $headers -UseBasicParsing -SkipCertificateCheck).Content.Trim() $local = if (Test-Path $VersionFile) { (Get-Content $VersionFile).Trim() } else { "0" } if ($remote -eq $local) { exit 0 } # 2. 下载证书 Invoke-WebRequest -Uri "$BaseUrl/api/cert/fullchain?domain=$EncodedDomain" -Headers $headers -OutFile "$TmpDir\fullchain.pem" -UseBasicParsing -SkipCertificateCheck Invoke-WebRequest -Uri "$BaseUrl/api/cert/private?domain=$EncodedDomain" -Headers $headers -OutFile "$TmpDir\private.key" -UseBasicParsing -SkipCertificateCheck # 3. 备份旧证书 Copy-Item "$CertDir\fullchain.pem" "$CertDir\fullchain.pem.bak" -ErrorAction SilentlyContinue Copy-Item "$CertDir\private.key" "$CertDir\private.key.bak" -ErrorAction SilentlyContinue # 4. 原子替换 Move-Item "$TmpDir\fullchain.pem" "$CertDir\fullchain.pem" -Force Move-Item "$TmpDir\private.key" "$CertDir\private.key" -Force # 5. 校验 & 重载 try { Invoke-Expression $CheckCmd $remote | Out-File -NoNewline -Encoding ascii $VersionFile Invoke-Expression $ReloadCmd Write-Host "[$(Get-Date -Format o)] updated: $Domain -> $remote" } catch { Move-Item "$CertDir\fullchain.pem.bak" "$CertDir\fullchain.pem" -Force -ErrorAction SilentlyContinue Move-Item "$CertDir\private.key.bak" "$CertDir\private.key" -Force -ErrorAction SilentlyContinue Write-Error "[$(Get-Date -Format o)] FAILED: $Domain, rolled back" exit 1 }