GSP-Agent-Windows/Installer/Update-GSP-WindowsAgent.ps1
2026-06-10 19:54:11 -04:00

341 lines
10 KiB
PowerShell

# GSP Windows Agent Updater - PowerShell Script
# This script updates an existing Git-managed agent installation
#Requires -RunAsAdministrator
param(
[string]$InstallPath = "C:\GSP",
[string]$GitBranch = "master"
)
$Script:AgentDir = Join-Path $InstallPath "Agent"
$Script:GitDir = Join-Path $InstallPath "tools\PortableGit"
$Script:BackupDir = Join-Path $InstallPath "backups\agent"
$Script:LogsDir = Join-Path $InstallPath "logs"
$Script:UpdateLogFile = Join-Path $Script:LogsDir "update.log"
function Log-Message {
param([string]$Message, [switch]$IsError = $false)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$logLine = "[$timestamp] $Message"
if ($IsError) {
Write-Host $logLine -ForegroundColor Red
} else {
Write-Host $logLine
}
Add-Content -Path $Script:UpdateLogFile -Value $logLine -Force
}
function Test-Administrator {
$currentUser = [Security.Principal.WindowsIdentity]::GetCurrent()
$principal = New-Object Security.Principal.WindowsPrincipal($currentUser)
return $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
}
function Stop-Agent {
Log-Message "Stopping agent..."
try {
# Try to stop the scheduled task
Stop-ScheduledTask -TaskName "GSP Windows Agent" -ErrorAction SilentlyContinue
Log-Message "Scheduled task stopped"
# Give it a moment to shut down gracefully
Start-Sleep -Seconds 2
# Kill any remaining bash/perl processes from the agent
Get-Process bash,perl -ErrorAction SilentlyContinue | ForEach-Object {
try {
Stop-Process -Id $_.Id -Force -ErrorAction SilentlyContinue
Log-Message "Killed remaining process: $($_.Name) (PID: $($_.Id))"
} catch {
# Process may already be gone
}
}
return $true
} catch {
Log-Message "WARNING stopping agent: $_" -IsError $true
return $false
}
}
function Backup-Agent {
Log-Message "Backing up current agent..."
try {
$backupName = "agent-backup-$(Get-Date -Format 'yyyyMMdd-HHmmss')"
$backupPath = Join-Path $Script:BackupDir $backupName
Log-Message "Backup destination: $backupPath"
Copy-Item -Path $Script:AgentDir -Destination $backupPath -Recurse -Force
Log-Message "Backup completed successfully"
return $backupPath
} catch {
Log-Message "ERROR creating backup: $_" -IsError $true
return $null
}
}
function Preserve-LocalFolders {
Log-Message "Preserving local configuration and runtime folders..."
$preserved = @{}
$preserveFolders = @("Cfg", "steamcmd", "screenlogs", "startups", "tmp", "shared")
try {
foreach ($folder in $preserveFolders) {
$folderPath = Join-Path $Script:AgentDir $folder
if (Test-Path $folderPath) {
$tempPath = Join-Path $env:TEMP "gsp_preserve_$folder"
if (Test-Path $tempPath) {
Remove-Item $tempPath -Recurse -Force
}
Copy-Item -Path $folderPath -Destination $tempPath -Recurse -Force
$preserved[$folder] = $tempPath
Log-Message " Preserved: $folder"
}
}
return $preserved
} catch {
Log-Message "ERROR preserving folders: $_" -IsError $true
return @{}
}
}
function Update-Repository {
Log-Message "Updating repository from Git..."
try {
$gitExe = Join-Path $Script:GitDir "cmd\git.exe"
if (-not (Test-Path $gitExe)) {
Log-Message "ERROR: git.exe not found at: $gitExe" -IsError $true
return $false
}
if (-not (Test-Path (Join-Path $Script:AgentDir ".git"))) {
Log-Message "ERROR: Agent directory is not a Git repository (.git folder not found)" -IsError $true
Log-Message "The agent must be installed with the Git-based installer to use this update script"
return $false
}
Log-Message "Running git fetch..."
$fetchProcess = Start-Process -FilePath $gitExe `
-ArgumentList "fetch", "origin" `
-Wait -PassThru -NoNewWindow -WorkingDirectory $Script:AgentDir
if ($fetchProcess.ExitCode -ne 0) {
Log-Message "ERROR: git fetch failed with code: $($fetchProcess.ExitCode)" -IsError $true
return $false
}
Log-Message "Running git reset to $GitBranch..."
$resetProcess = Start-Process -FilePath $gitExe `
-ArgumentList "reset", "--hard", "origin/$GitBranch" `
-Wait -PassThru -NoNewWindow -WorkingDirectory $Script:AgentDir
if ($resetProcess.ExitCode -ne 0) {
Log-Message "ERROR: git reset failed with code: $($resetProcess.ExitCode)" -IsError $true
return $false
}
Log-Message "Repository updated successfully"
return $true
} catch {
Log-Message "ERROR updating repository: $_" -IsError $true
return $false
}
}
function Restore-LocalFolders {
param([hashtable]$PreservedFolders)
Log-Message "Restoring preserved local folders..."
try {
foreach ($folder in $PreservedFolders.Keys) {
$tempPath = $PreservedFolders[$folder]
$targetPath = Join-Path $Script:AgentDir $folder
if (Test-Path $targetPath) {
Remove-Item -Path $targetPath -Recurse -Force
}
Copy-Item -Path $tempPath -Destination $targetPath -Recurse -Force
Remove-Item -Path $tempPath -Recurse -Force
Log-Message " Restored: $folder"
}
return $true
} catch {
Log-Message "ERROR restoring folders: $_" -IsError $true
return $false
}
}
function Validate-Agent {
Log-Message "Validating agent syntax..."
try {
$agentScript = Join-Path $Script:AgentDir "OGP64\OGP\ogp_agent.pl"
if (-not (Test-Path $agentScript)) {
Log-Message "WARNING: ogp_agent.pl not found, skipping syntax check"
return $true
}
# Try to run perl syntax check
$perlCheck = Start-Process -FilePath "perl.exe" `
-ArgumentList "-c", $agentScript `
-Wait -PassThru -NoNewWindow -ErrorAction SilentlyContinue
if ($perlCheck.ExitCode -ne 0) {
Log-Message "WARNING: Perl syntax check failed, but update may still be valid" -IsError $true
} else {
Log-Message "Perl syntax validation passed"
}
return $true
} catch {
Log-Message "WARNING: Could not validate agent syntax: $_" -IsError $true
return $true
}
}
function Start-Agent {
Log-Message "Starting agent..."
try {
Start-ScheduledTask -TaskName "GSP Windows Agent" -ErrorAction SilentlyContinue
Log-Message "Scheduled task started"
return $true
} catch {
Log-Message "WARNING: Could not start scheduled task immediately" -IsError $true
Log-Message "Agent will start at next system boot"
return $true
}
}
function Rollback-Update {
param([string]$BackupPath)
Log-Message "ROLLING BACK UPDATE..."
if (-not (Test-Path $BackupPath)) {
Log-Message "ERROR: Backup not found, cannot rollback" -IsError $true
return $false
}
try {
Log-Message "Restoring from backup: $BackupPath"
# Stop agent first
Stop-Agent | Out-Null
# Remove updated directory
if (Test-Path $Script:AgentDir) {
Remove-Item -Path $Script:AgentDir -Recurse -Force
}
# Restore backup
Copy-Item -Path $BackupPath -Destination $Script:AgentDir -Recurse -Force
# Restart agent
Start-Agent | Out-Null
Log-Message "Rollback completed successfully"
return $true
} catch {
Log-Message "ERROR during rollback: $_" -IsError $true
return $false
}
}
function Main {
Log-Message "========================================="
Log-Message "GSP Windows Agent Update"
Log-Message "========================================="
Log-Message "Install Path: $InstallPath"
Log-Message "Git Branch: $GitBranch"
Log-Message ""
# Check admin
if (-not (Test-Administrator)) {
Log-Message "ERROR: This script must be run as Administrator" -IsError $true
exit 1
}
# Verify directories exist
if (-not (Test-Path $Script:AgentDir)) {
Log-Message "ERROR: Agent not found at: $Script:AgentDir" -IsError $true
exit 1
}
if (-not (Test-Path $Script:GitDir)) {
Log-Message "ERROR: Portable Git not found at: $Script:GitDir" -IsError $true
exit 1
}
# Create logs directory if needed
if (-not (Test-Path $Script:LogsDir)) {
New-Item -ItemType Directory -Path $Script:LogsDir -Force | Out-Null
}
# Stop agent
Stop-Agent
# Create backup
$backupPath = Backup-Agent
if (-not $backupPath) {
Log-Message "FATAL: Could not create backup" -IsError $true
exit 1
}
# Preserve local folders
$preserved = Preserve-LocalFolders
# Update from Git
if (-not (Update-Repository)) {
Log-Message "FATAL: Update failed, rolling back..." -IsError $true
Rollback-Update $backupPath | Out-Null
exit 1
}
# Restore preserved folders
if ($preserved.Count -gt 0) {
if (-not (Restore-LocalFolders $preserved)) {
Log-Message "WARNING: Failed to restore all folders" -IsError $true
Rollback-Update $backupPath | Out-Null
exit 1
}
}
# Validate agent
Validate-Agent
# Start agent
Start-Agent
Log-Message ""
Log-Message "========================================="
Log-Message "Update Complete!"
Log-Message "========================================="
Log-Message "Agent has been updated successfully"
Log-Message "Backup location: $backupPath"
Log-Message "Log file: $Script:UpdateLogFile"
Log-Message ""
Log-Message "The agent will restart at the next opportunity"
Log-Message ""
Read-Host "Press Enter to close this window"
}
Main