198 lines
9.4 KiB
PowerShell
198 lines
9.4 KiB
PowerShell
# ============================================================================
|
|
# EasyBot Windows Agent — One-Line Installer
|
|
# ============================================================================
|
|
#
|
|
# Usage:
|
|
# powershell -ExecutionPolicy Bypass -c "irm https://raw.githubusercontent.com/pyptechnologies/easybot-windows-agent/main/install.ps1 | iex"
|
|
#
|
|
# Then configure:
|
|
# $env:EASYBOT_SERVER = "wss://your-server.com/ws/windows-agent"
|
|
# $env:EASYBOT_TOKEN = "eb_wag_..."
|
|
# easybot-windows-agent
|
|
#
|
|
# ============================================================================
|
|
|
|
$ErrorActionPreference = "Stop"
|
|
$InstallDir = "$env:ProgramData\EasyBot\WindowsAgent"
|
|
$ServiceName = "EasyBotWindowsAgent"
|
|
$PythonMinVersion = [version]"3.11.0"
|
|
|
|
Write-Host ""
|
|
Write-Host "========================================" -ForegroundColor Cyan
|
|
Write-Host " EasyBot Windows Agent Installer v1.0" -ForegroundColor Cyan
|
|
Write-Host "========================================" -ForegroundColor Cyan
|
|
Write-Host ""
|
|
|
|
# ── Check admin ──────────────────────────────────────────────────────────────
|
|
|
|
$isAdmin = ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
|
|
if (-not $isAdmin) {
|
|
Write-Host "[!] This installer requires administrator privileges." -ForegroundColor Yellow
|
|
Write-Host " Please run PowerShell as Administrator and try again." -ForegroundColor Yellow
|
|
exit 1
|
|
}
|
|
|
|
# ── Check Python ─────────────────────────────────────────────────────────────
|
|
|
|
Write-Host "[1/5] Checking Python..." -ForegroundColor White
|
|
$pythonCmd = $null
|
|
foreach ($cmd in @("python", "python3", "py -3")) {
|
|
try {
|
|
$ver = & $cmd.Split()[0] $cmd.Split()[1..99] --version 2>&1
|
|
if ($ver -match "Python (\d+\.\d+\.\d+)") {
|
|
$pyVer = [version]$Matches[1]
|
|
if ($pyVer -ge $PythonMinVersion) {
|
|
$pythonCmd = $cmd
|
|
Write-Host " Found Python $pyVer" -ForegroundColor Green
|
|
break
|
|
}
|
|
}
|
|
} catch {}
|
|
}
|
|
|
|
if (-not $pythonCmd) {
|
|
Write-Host " Python >= 3.11 not found. Installing via winget..." -ForegroundColor Yellow
|
|
try {
|
|
winget install Python.Python.3.12 --accept-source-agreements --accept-package-agreements --silent
|
|
# Refresh PATH
|
|
$env:Path = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path", "User")
|
|
$pythonCmd = "python"
|
|
Write-Host " Python installed successfully" -ForegroundColor Green
|
|
} catch {
|
|
Write-Host "[X] Failed to install Python. Please install Python 3.11+ manually." -ForegroundColor Red
|
|
Write-Host " https://www.python.org/downloads/" -ForegroundColor Gray
|
|
exit 1
|
|
}
|
|
}
|
|
|
|
# ── Create install directory ─────────────────────────────────────────────────
|
|
|
|
Write-Host "[2/5] Creating install directory..." -ForegroundColor White
|
|
New-Item -ItemType Directory -Path $InstallDir -Force | Out-Null
|
|
Write-Host " $InstallDir" -ForegroundColor Gray
|
|
|
|
# ── Install Python package from Gitea ────────────────────────────────────────
|
|
|
|
Write-Host "[3/5] Installing easybot-windows-agent from repository..." -ForegroundColor White
|
|
$repoZip = "$env:TEMP\easybot-windows-agent.zip"
|
|
$repoExtract = "$env:TEMP\easybot-windows-agent"
|
|
$repoUrl = "https://repo.pyp.ar/public-pull/easybot-windows-agent/archive/main.zip"
|
|
|
|
# Download and extract
|
|
if (Test-Path $repoExtract) { Remove-Item $repoExtract -Recurse -Force }
|
|
Write-Host " Downloading from repository..." -ForegroundColor Gray
|
|
Invoke-WebRequest -Uri $repoUrl -OutFile $repoZip -UseBasicParsing
|
|
Expand-Archive -Path $repoZip -DestinationPath $repoExtract -Force
|
|
|
|
# Find the extracted folder (Gitea names it easybot-windows-agent/)
|
|
$pkgDir = Get-ChildItem -Path $repoExtract -Directory | Select-Object -First 1
|
|
|
|
# Temporarily allow errors (pip writes warnings to stderr which PowerShell treats as errors)
|
|
$ErrorActionPreference = "Continue"
|
|
|
|
# pip install from local directory
|
|
Write-Host " Installing package..." -ForegroundColor Gray
|
|
& $pythonCmd.Split()[0] $pythonCmd.Split()[1..99] -m pip install --force-reinstall --no-deps $pkgDir.FullName 2>&1 | ForEach-Object {
|
|
if ($_ -match "Successfully installed") { Write-Host " $_" -ForegroundColor Green }
|
|
}
|
|
|
|
# Install dependencies
|
|
Write-Host " Installing dependencies..." -ForegroundColor Gray
|
|
& $pythonCmd.Split()[0] $pythonCmd.Split()[1..99] -m pip install "websockets>=12.0,<14" "uiautomation>=2.0" "pyautogui>=0.9" "pywinauto>=0.6" "Pillow>=10.0" 2>&1 | Out-Null
|
|
|
|
$ErrorActionPreference = "Stop"
|
|
|
|
# Cleanup
|
|
Remove-Item $repoZip -Force -ErrorAction SilentlyContinue
|
|
Remove-Item $repoExtract -Recurse -Force -ErrorAction SilentlyContinue
|
|
Write-Host " Package installed successfully" -ForegroundColor Green
|
|
|
|
# ── Configure environment ────────────────────────────────────────────────────
|
|
|
|
Write-Host "[4/5] Configuration..." -ForegroundColor White
|
|
|
|
$configFile = "$InstallDir\config.env"
|
|
if (Test-Path $configFile) {
|
|
Write-Host " Existing config found at $configFile" -ForegroundColor Gray
|
|
} else {
|
|
# Use env vars if already set, otherwise prompt
|
|
$server = if ($env:EASYBOT_SERVER) { $env:EASYBOT_SERVER } else { Read-Host " Enter EasyBot server URL (e.g., wss://app.example.com/ws/windows-agent)" }
|
|
$token = if ($env:EASYBOT_TOKEN) { $env:EASYBOT_TOKEN } else { Read-Host " Enter authentication token (eb_wag_...)" }
|
|
|
|
Write-Host " Server: $server" -ForegroundColor Gray
|
|
Write-Host " Token: $($token.Substring(0, [Math]::Min(12, $token.Length)))..." -ForegroundColor Gray
|
|
|
|
@"
|
|
EASYBOT_SERVER=$server
|
|
EASYBOT_TOKEN=$token
|
|
LOG_LEVEL=INFO
|
|
"@ | Set-Content -Path $configFile -Encoding UTF8
|
|
|
|
Write-Host " Config saved to $configFile" -ForegroundColor Green
|
|
}
|
|
|
|
# ── Install as Scheduled Task (runs in user session for desktop access) ──────
|
|
|
|
Write-Host "[5/5] Installing as Scheduled Task (user session)..." -ForegroundColor White
|
|
|
|
$TaskName = "EasyBotWindowsAgent"
|
|
|
|
# Remove old nssm service if present
|
|
$nssmPath = "$InstallDir\nssm.exe"
|
|
$ErrorActionPreference = "Continue"
|
|
if (Test-Path $nssmPath) {
|
|
& $nssmPath stop $ServiceName 2>&1 | Out-Null
|
|
& $nssmPath remove $ServiceName confirm 2>&1 | Out-Null
|
|
}
|
|
# Remove old scheduled task if present
|
|
schtasks /delete /tn $TaskName /f 2>&1 | Out-Null
|
|
$ErrorActionPreference = "Stop"
|
|
|
|
# Find Python executable
|
|
$pythonExe = & $pythonCmd.Split()[0] $pythonCmd.Split()[1..99] -c "import sys; print(sys.executable)"
|
|
|
|
# Build a launcher script that loads config.env and runs the agent
|
|
$launcherScript = "$InstallDir\start-agent.ps1"
|
|
@"
|
|
# EasyBot Windows Agent Launcher
|
|
`$configFile = "$InstallDir\config.env"
|
|
if (Test-Path `$configFile) {
|
|
Get-Content `$configFile | ForEach-Object {
|
|
if (`$_ -match "^([^#=]+)=(.*)$") {
|
|
[System.Environment]::SetEnvironmentVariable(`$Matches[1], `$Matches[2], "Process")
|
|
}
|
|
}
|
|
}
|
|
& "$pythonExe" -m easybot_windows_agent.main *>> "$InstallDir\agent.log"
|
|
"@ | Set-Content -Path $launcherScript -Encoding UTF8
|
|
|
|
# Create scheduled task: runs at logon, highest privileges, restarts on failure
|
|
$action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-NoProfile -WindowStyle Hidden -ExecutionPolicy Bypass -File `"$launcherScript`""
|
|
$trigger = New-ScheduledTaskTrigger -AtLogOn
|
|
$settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -RestartInterval (New-TimeSpan -Minutes 1) -RestartCount 999 -StartWhenAvailable
|
|
$principal = New-ScheduledTaskPrincipal -UserId $env:USERNAME -RunLevel Highest -LogonType Interactive
|
|
|
|
Register-ScheduledTask -TaskName $TaskName -Action $action -Trigger $trigger -Settings $settings -Principal $principal -Force | Out-Null
|
|
Write-Host " Scheduled task created: $TaskName" -ForegroundColor Green
|
|
|
|
# Start it now
|
|
Start-ScheduledTask -TaskName $TaskName
|
|
Write-Host " Agent started!" -ForegroundColor Green
|
|
|
|
Write-Host ""
|
|
Write-Host "========================================" -ForegroundColor Cyan
|
|
Write-Host " Installation Complete!" -ForegroundColor Cyan
|
|
Write-Host "========================================" -ForegroundColor Cyan
|
|
Write-Host ""
|
|
Write-Host " Install dir: $InstallDir" -ForegroundColor Gray
|
|
Write-Host " Config file: $configFile" -ForegroundColor Gray
|
|
Write-Host " Log file: $InstallDir\agent.log" -ForegroundColor Gray
|
|
Write-Host " Task: $TaskName" -ForegroundColor Gray
|
|
Write-Host ""
|
|
Write-Host " Commands:" -ForegroundColor White
|
|
Write-Host " schtasks /query /tn $TaskName # Check status" -ForegroundColor Gray
|
|
Write-Host " Stop-ScheduledTask -TaskName $TaskName # Stop agent" -ForegroundColor Gray
|
|
Write-Host " Start-ScheduledTask -TaskName $TaskName # Start agent" -ForegroundColor Gray
|
|
Write-Host " schtasks /delete /tn $TaskName /f # Uninstall" -ForegroundColor Gray
|
|
Write-Host ""
|