$ErrorActionPreference = 'Stop' $ProgressPreference = 'SilentlyContinue' [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 $BaseUrl = 'https://station.dmstech.tech' $AgentVersion = '2026-07-29-v10-oi-setuptools-pin' Write-Host 'RAC Station - installation/reparation Agent V4 Windows + Open Interpreter' -ForegroundColor Cyan Write-Host 'Cet agent donne un acces distant admin a cette machine. Continuez seulement avec autorisation.' -ForegroundColor Yellow $dir = Join-Path $env:ProgramData 'RACStation' New-Item -ItemType Directory -Force -Path $dir | Out-Null $configPath = Join-Path $dir 'config.json' $statePath = Join-Path $dir 'state.json' $token = [Environment]::GetEnvironmentVariable('RAC_ENROLLMENT_TOKEN','Process') if (Test-Path $statePath) { Write-Host 'Etat agent existant detecte: reparation/mise a jour sans nouveau token.' -ForegroundColor Green } else { if ([string]::IsNullOrWhiteSpace($token)) { $token = Read-Host 'Collez le token d enrollement fourni par votre administrateur' } if ([string]::IsNullOrWhiteSpace($token)) { throw 'Token manquant' } } $taskName = 'RACStationAgent' try { Stop-ScheduledTask -TaskName $taskName -ErrorAction SilentlyContinue } catch {} try { Unregister-ScheduledTask -TaskName $taskName -Confirm:$false -ErrorAction SilentlyContinue } catch {} try { Get-CimInstance Win32_Process -Filter "Name='powershell.exe'" | Where-Object { $_.CommandLine -like '*RACStation*agent.ps1*' } | ForEach-Object { Stop-Process -Id $_.ProcessId -Force -ErrorAction SilentlyContinue } } catch {} Invoke-WebRequest -UseBasicParsing "$BaseUrl/agent.ps1" -OutFile (Join-Path $dir 'agent.ps1') Write-Host 'Preparation Open Interpreter sur cette machine...' -ForegroundColor Cyan $oiLog = Join-Path $dir 'open-interpreter-install.log' $venvDir = Join-Path $dir 'oi-venv' $oiCmd = Join-Path $dir 'interpreter.cmd' try { $ErrorActionPreference = 'Continue' "=== RAC Open Interpreter Python 3.11 ensure $(Get-Date -Format o) ===" | Out-File -Append $oiLog function Test-OIImport([string]$Py) { if (!(Test-Path $Py)) { return $false } $out = & $Py -c 'import sys; print(sys.version); import interpreter; print("OPEN_INTERPRETER_IMPORT_OK")' 2>&1 $out | Out-File -Append $oiLog return ($LASTEXITCODE -eq 0 -and (($out -join "`n") -match 'OPEN_INTERPRETER_IMPORT_OK')) } $venvPy = Join-Path $venvDir 'Scripts\python.exe' if (Test-Path $venvPy) { try { & $venvPy -m pip install --force-reinstall 'setuptools<81' 2>&1 | Out-File -Append $oiLog } catch {} } if (Test-OIImport $venvPy) { Set-Content -Encoding ASCII -Path $oiCmd -Value @('@echo off', ('"' + $venvPy + '" -m interpreter %*')) Write-Host "Open Interpreter deja pret. Commande: $oiCmd" -ForegroundColor Green } else { Write-Host 'Open Interpreter absent/KO: installation Python 3.11 dediee...' -ForegroundColor Yellow Remove-Item $venvDir -Recurse -Force -ErrorAction SilentlyContinue $py311Exe = Join-Path $dir 'python-3.11.9-installer.exe' try { Invoke-WebRequest -UseBasicParsing 'https://www.python.org/ftp/python/3.11.9/python-3.11.9-amd64.exe' -OutFile $py311Exe -TimeoutSec 300 $p = Start-Process -FilePath $py311Exe -ArgumentList '/quiet','InstallAllUsers=1','PrependPath=1','Include_pip=1','Include_launcher=1' -Wait -PassThru "Python 3.11 installer exit=$($p.ExitCode)" | Out-File -Append $oiLog } catch { $_ | Out-File -Append $oiLog } $env:Path = [Environment]::GetEnvironmentVariable('Path','Machine') + ';' + [Environment]::GetEnvironmentVariable('Path','User') $created = $false try { & py -3.11 -m venv $venvDir 2>&1 | Out-File -Append $oiLog; if ($LASTEXITCODE -eq 0) { $created = $true } } catch { $_ | Out-File -Append $oiLog } if (-not $created) { try { & python -m venv $venvDir 2>&1 | Out-File -Append $oiLog; if ($LASTEXITCODE -eq 0) { $created = $true } } catch { $_ | Out-File -Append $oiLog } } if (!(Test-Path $venvPy)) { throw "Venv Python 3.11 non cree: $venvPy" } Write-Host 'Installation/reparation Open Interpreter automatique...' -ForegroundColor Cyan & $venvPy -m pip install --upgrade pip wheel 2>&1 | Out-File -Append $oiLog & $venvPy -m pip install --force-reinstall 'setuptools<81' 2>&1 | Out-File -Append $oiLog & $venvPy -m pip install --no-cache-dir --prefer-binary 'open-interpreter==0.4.3' 'litellm<1.70' 2>&1 | Out-File -Append $oiLog $pipCode = $LASTEXITCODE if ($pipCode -ne 0) { 'Install open-interpreter==0.4.3 failed; retry latest prefer-binary.' | Out-File -Append $oiLog & $venvPy -m pip install --no-cache-dir --prefer-binary open-interpreter 2>&1 | Out-File -Append $oiLog $pipCode = $LASTEXITCODE } if ($pipCode -ne 0) { throw "pip install open-interpreter failed exit=$pipCode" } if (!(Test-OIImport $venvPy)) { 'Import KO: reinstall setuptools<81 then retry.' | Out-File -Append $oiLog & $venvPy -m pip install --force-reinstall 'setuptools<81' 2>&1 | Out-File -Append $oiLog if (!(Test-OIImport $venvPy)) { throw 'Open Interpreter installe mais import Python KO' } } Set-Content -Encoding ASCII -Path $oiCmd -Value @('@echo off', ('"' + $venvPy + '" -m interpreter %*')) Write-Host "Open Interpreter installe automatiquement. Commande: $oiCmd" -ForegroundColor Green } } catch { try { $_.Exception.ToString() | Out-File -Append $oiLog } catch {} Write-Host "Open Interpreter non pret malgre tentative automatique. Agent RAC continue. Log: $oiLog" -ForegroundColor Yellow Write-Host "Blocage probable: dependance pip/Open Interpreter incompatible. Lance: Get-Content '$oiLog' -Tail 160" -ForegroundColor Yellow } if (!(Test-Path $configPath)) { @{ baseUrl=$BaseUrl; enrollmentToken=$token; installedAt=(Get-Date).ToString('o'); agentVersion=$AgentVersion } | ConvertTo-Json -Depth 10 | Set-Content -Encoding UTF8 $configPath } else { try { $cfg = Get-Content $configPath -Raw -Encoding UTF8 | ConvertFrom-Json $cfg.baseUrl = $BaseUrl if ($token) { $cfg.enrollmentToken = $token } $cfg.agentVersion = $AgentVersion $cfg.updatedAt = (Get-Date).ToString('o') $cfg | ConvertTo-Json -Depth 10 | Set-Content -Encoding UTF8 $configPath } catch { @{ baseUrl=$BaseUrl; enrollmentToken=$token; installedAt=(Get-Date).ToString('o'); agentVersion=$AgentVersion } | ConvertTo-Json -Depth 10 | Set-Content -Encoding UTF8 $configPath } } if ($token) { Remove-Item $statePath -Force -ErrorAction SilentlyContinue } # Enrolement immediat pendant l'installation: la machine apparait dans RAC sans attendre la tache planifiee. try { if (!(Test-Path $statePath)) { Write-Host 'Enrolement RAC immediat...' -ForegroundColor Cyan $cfgNow = Get-Content $configPath -Raw -Encoding UTF8 | ConvertFrom-Json if ([string]::IsNullOrWhiteSpace([string]$cfgNow.enrollmentToken)) { throw 'Token enrollement absent dans config.json' } $osCaption = 'Windows'; $osVersion=''; $lastBoot='' try { $os = Get-CimInstance Win32_OperatingSystem $osCaption = $os.Caption $osVersion = $os.Version $lastBoot = ([Management.ManagementDateTimeConverter]::ToDateTime($os.LastBootUpTime)).ToString('o') } catch {} $inv = @{ agentVersion=$AgentVersion; powershell=$PSVersionTable.PSVersion.ToString(); serviceMode='ScheduledTask'; programData=$dir; osVersion=$osVersion; lastBoot=$lastBoot } $body = @{ enrollmentToken=$cfgNow.enrollmentToken; hostname=$env:COMPUTERNAME; os=$osCaption; arch=$env:PROCESSOR_ARCHITECTURE; user=$env:USERNAME; inventory=$inv } | ConvertTo-Json -Depth 12 -Compress $enr = Invoke-RestMethod -Method Post -Uri "$BaseUrl/api/agent/enroll" -ContentType 'application/json; charset=utf-8' -Body $body -TimeoutSec 60 -Headers @{ 'X-Agent-Version'=$AgentVersion } @{ machineId=$enr.machineId; agentToken=$enr.agentToken; pollSeconds=$enr.pollSeconds; enrolledAt=(Get-Date).ToString('o'); agentVersion=$AgentVersion } | ConvertTo-Json -Depth 10 | Set-Content -Encoding UTF8 $statePath Add-Content -Encoding UTF8 -Path (Join-Path $dir 'agent.log') -Value "$(Get-Date -Format o) enrolled immediate $($enr.machineId)" Write-Host "Machine enrolee immediatement: $($enr.machineId)" -ForegroundColor Green } } catch { try { Add-Content -Encoding UTF8 -Path (Join-Path $dir 'agent.log') -Value "$(Get-Date -Format o) immediate enroll error: $($_.Exception.ToString())" } catch {} Write-Host "Enrolement immediat echoue. Voir agent.log: $($_.Exception.Message)" -ForegroundColor Yellow } $action = New-ScheduledTaskAction -Execute 'powershell.exe' -Argument "-NoProfile -ExecutionPolicy Bypass -File `"$dir\agent.ps1`"" $triggerBoot = New-ScheduledTaskTrigger -AtStartup $triggerMinute = New-ScheduledTaskTrigger -Once -At (Get-Date).AddMinutes(1) try { $triggerMinute.Repetition.Interval = 'PT1M'; $triggerMinute.Repetition.Duration = 'P3650D' } catch { Write-Host 'Info: repetition trigger non disponible.' -ForegroundColor Yellow } $principal = New-ScheduledTaskPrincipal -UserId 'SYSTEM' -RunLevel Highest $settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -StartWhenAvailable -MultipleInstances IgnoreNew -ExecutionTimeLimit (New-TimeSpan -Days 0) -RestartCount 999 -RestartInterval (New-TimeSpan -Minutes 1) Register-ScheduledTask -TaskName $taskName -Action $action -Trigger @($triggerBoot,$triggerMinute) -Principal $principal -Settings $settings -Force | Out-Null Start-ScheduledTask -TaskName $taskName Start-Sleep -Seconds 12 Write-Host "Agent RAC installe/repare et demarre. Tache planifiee: $taskName" -ForegroundColor Green Write-Host "Version: $AgentVersion" -ForegroundColor Gray Write-Host "Log local: $dir\agent.log" -ForegroundColor Gray Write-Host "Etat local apres demarrage:" -ForegroundColor Cyan try { Get-ScheduledTask -TaskName $taskName | Get-ScheduledTaskInfo | Format-List | Out-String | Write-Host } catch {} if (Test-Path $statePath) { Write-Host "Machine enrolee localement. State:" -ForegroundColor Green try { Get-Content $statePath -Raw | Write-Host } catch {} } else { Write-Host "ATTENTION: state.json absent, la machine n'est pas encore enrolee. Dernier log agent:" -ForegroundColor Yellow } try { Get-Content (Join-Path $dir 'agent.log') -Tail 100 | Write-Host } catch { Write-Host "agent.log absent ou illisible" -ForegroundColor Yellow } Write-Host "Diagnostic manuel si besoin:" -ForegroundColor Cyan Write-Host "Get-ScheduledTask -TaskName $taskName | Get-ScheduledTaskInfo" Write-Host "Get-Content '$dir\agent.log' -Tail 120" Write-Host "Get-Content '$dir\open-interpreter-install.log' -Tail 120"