param (
[string]$NodeId = "",
[string]$AuthToken = "",
[string]$HubUrl = "",
[string]$GrpcUrl = ""
)
$ErrorActionPreference = "Stop"
Write-Host "==========================================" -ForegroundColor Cyan
Write-Host " CORTEX AGENT WINDOWS BOOTSTRAP " -ForegroundColor Cyan
Write-Host "==========================================" -ForegroundColor Cyan
# 1. Check Python installation (defensively avoid Microsoft Store alias)
$pythonValid = $false
try {
$out = python --version 2>&1
if ($out -like "*Python *") { $pythonValid = $true }
} catch { }
if (!$pythonValid) {
Write-Host "[!] Python not found or invalid. Installing via winget..." -ForegroundColor Yellow
winget install -e --id Python.Python.3.12 --accept-package-agreements --accept-source-agreements
# Refresh PATH
$env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User")
}
# 2. Verify Python version
$pyVer = python --version
Write-Host "[*] Found $pyVer"
# 3. Create working directory
$workDir = "C:\CortexAgent"
if (!(Test-Path $workDir)) {
New-Item -ItemType Directory -Path $workDir
}
Set-Location $workDir
# 4. Download agent code from Hub (Matching Linux pattern)
if ((-not $HubUrl) -or (-not $AuthToken)) {
Write-Host "[!] Hub details missing. Will prompt for them later after basic setup." -ForegroundColor Yellow
} else {
Write-Host "[*] Fetching agent source from Hub..." -ForegroundColor Cyan
$baseUrl = $HubUrl.Split(":")[0]
if ($HubUrl.Contains("http")) {
$downloadUrl = "$HubUrl/api/v1/agent/download"
} else {
$downloadUrl = "http://$baseUrl:8002/api/v1/agent/download"
}
$tarPath = Join-Path $workDir "agent.tar.gz"
$headers = @{"X-Agent-Token" = $AuthToken}
try {
Invoke-WebRequest -Uri $downloadUrl -Headers $headers -OutFile $tarPath
Write-Host "[+] Download complete. Extracting..." -ForegroundColor Green
# Windows 10+ has tar.exe built-in. Fallback to Expand-Archive if needed.
if (Get-Command tar -ErrorAction SilentlyContinue) {
tar -xzf $tarPath --strip-components=1
} else {
Write-Warning "tar.exe not found. Attempting Expand-Archive (may not support tar.gz natively without 7-Zip/etc)."
# Note: PowerShell's Expand-Archive usually only likes .zip.
# We recommend users have tar or we provide a zip endpoint.
}
Remove-Item $tarPath
} catch {
Write-Warning "Failed to download code directly: $_"
Write-Host "[!] Please ensure agent-node source is manually placed at $workDir" -ForegroundColor Yellow
}
}
# 5. Setup Virtual Environment
Write-Host "[*] Creating Virtual Environment..."
python -m venv venv
.\venv\Scripts\Activate.ps1
# 6. Install Dependencies
Write-Host "[*] Installing Dependencies..."
python -m pip install --upgrade pip
python -m pip install -r requirements.txt
python -m pip install pywinpty pypiwin32 # Windows-specific requirements
# 7. Environment Setup
Write-Host "------------------------------------------"
Write-Host " Enter Agent Configuration Details:"
if (-not $NodeId) { $NodeId = Read-Host " AGENT_NODE_ID (e.g. pc-node-1)" }
if (-not $AuthToken) { $AuthToken = Read-Host " AGENT_AUTH_TOKEN" }
if (-not $HubUrl) { $HubUrl = Read-Host " HUB_URL (e.g. http://192.168.68.140:8002)" }
if (-not $GrpcUrl) { $GrpcUrl = Read-Host " GRPC_ENDPOINT (e.g. 192.168.68.140:50051)" }
$envFile = @"
AGENT_NODE_ID=$NodeId
AGENT_AUTH_TOKEN=$AuthToken
AGENT_HUB_URL=$HubUrl
GRPC_ENDPOINT=$GrpcUrl
AGENT_TLS_ENABLED=false
PYTHONUTF8=1
"@
$envFile | Out-File -FilePath ".env" -Encoding ascii
# 8. Test Execution
Write-Host "[*] Bootstrap complete. You can now run the agent with:" -ForegroundColor Green
Write-Host " .\venv\Scripts\python.exe src\agent_node\main.py" -ForegroundColor Yellow
# 9. Optional Service Registration
$installService = Read-Host "Would you like to register this as a startup task? (y/n)"
if ($installService -eq "y") {
Write-Host "[*] Registering Scheduled Task..."
python install_service.py --name "CortexAgent" --run
}
# 10. Security & Firewall Check
Write-Host "------------------------------------------"
Write-Host "[*] Checking Windows Firewall status..." -ForegroundColor Cyan
$profiles = Get-NetFirewallProfile
$disabled = $profiles | Where-Object { $_.Enabled -eq "False" }
if ($disabled) {
Write-Host "[!] Warning: One or more Firewall profiles are DISABLED." -ForegroundColor Yellow
$enable = Read-Host "Would you like to ENABLE the Windows Firewall now? (y/n)"
if ($enable -eq "y") {
Set-NetFirewallProfile -Profile Domain,Public,Private -Enabled True
Write-Host "[+] Windows Firewall enabled." -ForegroundColor Green
}
}
# Add rule for Python communication
Write-Host "[*] Adding firewall exception for agent communication..."
$pythonPath = (Get-Command python).Source
if ($pythonPath) {
New-NetFirewallRule -DisplayName "Cortex Agent Communication" -Direction Outbound -Program $pythonPath -Action Allow -Description "Allows Cortex Agent to reach the Hub" -ErrorAction SilentlyContinue
New-NetFirewallRule -DisplayName "Cortex Agent Communication" -Direction Inbound -Program $pythonPath -Action Allow -Description "Allows Cortex Agent Mesh Communication" -Profile Any -ErrorAction SilentlyContinue
}
Write-Host "=========================================="
Write-Host " DONE! Check the Hub for node status. " -ForegroundColor Cyan
Write-Host "=========================================="