# GSP Windows Agent Rollback - PowerShell Script # This script lets an admin restore a previous agent version from backup #Requires -RunAsAdministrator param( [string]$InstallPath = "C:\GSP" ) $Script:AgentDir = Join-Path $InstallPath "Agent" $Script:BackupDir = Join-Path $InstallPath "backups\agent" $Script:LogsDir = Join-Path $InstallPath "logs" $Script:RollbackLogFile = Join-Path $Script:LogsDir "rollback.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:RollbackLogFile -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 List-Backups { Log-Message "Listing available backups..." if (-not (Test-Path $Script:BackupDir)) { Write-Host "No backups directory found" return @() } $backups = Get-ChildItem -Path $Script:BackupDir -Directory | Sort-Object Name -Descending if ($backups.Count -eq 0) { Write-Host "No backups available" return @() } Write-Host "" Write-Host "Available backups:" -ForegroundColor Green $backupList = @() $index = 1 foreach ($backup in $backups) { $path = $backup.FullName $created = $backup.CreationTime $size = (Get-ChildItem -Path $path -Recurse | Measure-Object -Property Length -Sum).Sum / 1MB Write-Host " [$index] $($backup.Name) (created: $created, size: $([math]::Round($size, 2)) MB)" $backupList += $backup.FullName $index++ } return $backupList } function Select-Backup { param([array]$BackupList) if ($BackupList.Count -eq 0) { Write-Host "ERROR: No backups available" return $null } if ($BackupList.Count -eq 1) { Write-Host "" $response = Read-Host "Only one backup available. Restore it? (Y/N)" if ($response -eq "Y" -or $response -eq "y") { return $BackupList[0] } else { return $null } } Write-Host "" $choice = Read-Host "Select backup number (1-$($BackupList.Count)) or 'Q' to quit" if ($choice -eq "Q" -or $choice -eq "q") { return $null } if ($choice -match '^\d+$' -and [int]$choice -ge 1 -and [int]$choice -le $BackupList.Count) { return $BackupList[[int]$choice - 1] } else { Write-Host "Invalid selection" return $null } } function Stop-Agent { Log-Message "Stopping agent..." try { Stop-ScheduledTask -TaskName "GSP Windows Agent" -ErrorAction SilentlyContinue Log-Message "Scheduled task stopped" Start-Sleep -Seconds 2 Get-Process bash,perl -ErrorAction SilentlyContinue | ForEach-Object { try { Stop-Process -Id $_.Id -Force Log-Message "Killed: $($_.Name) (PID: $($_.Id))" } catch { # Already gone } } return $true } catch { Log-Message "WARNING stopping agent: $_" -IsError $true return $false } } function Restore-Backup { param([string]$BackupPath) Log-Message "Restoring from backup: $BackupPath" try { # Stop agent Stop-Agent # Preserve current Cfg if user wants $preserveCfg = $false Write-Host "" $response = Read-Host "Preserve current Cfg folder? (Y/N, default: Y)" if ($response -ne "N" -and $response -ne "n") { $preserveCfg = $true } $currentCfg = Join-Path $Script:AgentDir "OGP64\OGP\Cfg" $tempCfg = Join-Path $env:TEMP "gsp_preserve_cfg" if ($preserveCfg -and (Test-Path $currentCfg)) { Log-Message "Preserving current Cfg folder" if (Test-Path $tempCfg) { Remove-Item $tempCfg -Recurse -Force } Copy-Item -Path $currentCfg -Destination $tempCfg -Recurse -Force } # Remove current installation Log-Message "Removing current agent directory" if (Test-Path $Script:AgentDir) { Remove-Item -Path $Script:AgentDir -Recurse -Force } # Restore backup Log-Message "Copying backup to $Script:AgentDir" Copy-Item -Path $BackupPath -Destination $Script:AgentDir -Recurse -Force # Restore preserved Cfg if ($preserveCfg -and (Test-Path $tempCfg)) { Log-Message "Restoring preserved Cfg folder" $targetCfg = Join-Path $Script:AgentDir "OGP64\OGP\Cfg" if (Test-Path $targetCfg) { Remove-Item -Path $targetCfg -Recurse -Force } Copy-Item -Path $tempCfg -Destination $targetCfg -Recurse -Force Remove-Item -Path $tempCfg -Recurse -Force } # Start the task Log-Message "Starting agent" try { Start-ScheduledTask -TaskName "GSP Windows Agent" -ErrorAction SilentlyContinue } catch { Log-Message "WARNING: Could not start scheduled task" } 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 Rollback" Log-Message "=========================================" Log-Message "Install Path: $InstallPath" Log-Message "Backup Directory: $Script:BackupDir" Log-Message "" if (-not (Test-Administrator)) { Log-Message "ERROR: This script must be run as Administrator" -IsError $true exit 1 } if (-not (Test-Path $Script:LogsDir)) { New-Item -ItemType Directory -Path $Script:LogsDir -Force | Out-Null } # List available backups $backupList = List-Backups if ($backupList.Count -eq 0) { Write-Host "" Write-Host "No backups available for rollback" -ForegroundColor Yellow Read-Host "Press Enter to close this window" exit 0 } # Select a backup $selectedBackup = Select-Backup $backupList if (-not $selectedBackup) { Write-Host "Rollback cancelled" exit 0 } # Confirm restore Write-Host "" Write-Host "Selected: $selectedBackup" -ForegroundColor Yellow $confirm = Read-Host "Restore this backup? (Y/N)" if ($confirm -ne "Y" -and $confirm -ne "y") { Write-Host "Rollback cancelled" exit 0 } # Perform rollback if (Restore-Backup $selectedBackup) { Log-Message "" Log-Message "=========================================" Log-Message "Rollback Complete!" Log-Message "=========================================" Write-Host "" Write-Host "Rollback successful. Agent has been restored." -ForegroundColor Green Write-Host "Log file: $Script:RollbackLogFile" } else { Log-Message "" Log-Message "=========================================" Log-Message "Rollback Failed!" Log-Message "=========================================" Write-Host "" Write-Host "Rollback failed. Check the log for details." -ForegroundColor Red Write-Host "Log file: $Script:RollbackLogFile" } Write-Host "" Read-Host "Press Enter to close this window" } Main