param( [Parameter(Mandatory = $true)][string]$DeviceToken, [Parameter(Mandatory = $true)][Guid]$DeviceID ) $ErrorActionPreference = "Stop" $baseURL = "https://www.51ddns.com/downloads" $identity = [Security.Principal.WindowsIdentity]::GetCurrent() $principal = [Security.Principal.WindowsPrincipal]$identity if (-not $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) { throw "请以管理员身份运行 PowerShell。" } $architecture = if ($env:PROCESSOR_ARCHITECTURE -eq "ARM64") { "arm64" } else { "amd64" } $temporaryRoot = Join-Path ([IO.Path]::GetTempPath()) ("51ddns-install-" + [Guid]::NewGuid().ToString("N")) $archive = Join-Path $temporaryRoot "51ddns-agent.zip" try { New-Item -ItemType Directory -Force -Path $temporaryRoot | Out-Null $manifest = Invoke-RestMethod -UseBasicParsing -Uri "$baseURL/manifest.json" $matches = @($manifest | Where-Object { [string]$_.os -ceq "windows" -and [string]$_.arch -ceq $architecture }) if ($matches.Count -ne 1) { throw "公开版本清单中没有唯一的 Windows $architecture 安装包。" } $release = $matches[0] $filename = [string]$release.file $expectedHash = [string]$release.sha256 $expectedBytes = [long]$release.bytes if ($filename -notmatch "^51ddns-agent_[0-9]+\.[0-9]+\.[0-9]+_windows_${architecture}\.zip$") { throw "公开版本清单中的文件名无效。" } if ($expectedHash -notmatch '^[a-f0-9]{64}$' -or $expectedBytes -le 0) { throw "公开版本清单中的校验信息无效。" } $url = "$baseURL/$filename" Invoke-WebRequest -UseBasicParsing -Uri $url -OutFile $archive if ((Get-Item -LiteralPath $archive).Length -ne $expectedBytes) { throw "安装包文件长度校验失败,已停止安装。" } $actualHash = (Get-FileHash -Algorithm SHA256 -LiteralPath $archive).Hash.ToLowerInvariant() if ($actualHash -ne $expectedHash) { throw "安装包 SHA-256 校验失败,已停止安装。" } Expand-Archive -LiteralPath $archive -DestinationPath $temporaryRoot -Force & (Join-Path $temporaryRoot "install.ps1") -Token $DeviceToken -DeviceID $DeviceID Write-Output "一键部署完成。可在任务计划程序中查看 51DDNS Agent。" } finally { if (Test-Path -LiteralPath $temporaryRoot) { Remove-Item -LiteralPath $temporaryRoot -Recurse -Force } }