$ErrorActionPreference = 'Stop' $ProgressPreference = 'SilentlyContinue' $ConfirmPreference = 'None' $BaseUrl = 'https://wangxxxx.online' $EnrollToken = 'JJMXtCXQY6CD6P9GbBmS4duit4KZnZ3AAXdicavmuDh5Px6p' $Version = 'win-agent-0.1.23' function Test-Admin { $identity = [Security.Principal.WindowsIdentity]::GetCurrent() $principal = New-Object Security.Principal.WindowsPrincipal($identity) return $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) } if (-not (Test-Admin)) { Write-Host 'Requesting administrator permission...' -ForegroundColor Yellow $command = "irm $BaseUrl/install.ps1 | iex" Start-Process powershell.exe -Verb RunAs -ArgumentList @('-NoProfile', '-ExecutionPolicy', 'Bypass', '-Command', $command) exit 0 } if (-not $EnrollToken) { throw 'PCManager enrollment token is not configured on the server.' } $InstallRoot = Join-Path $env:ProgramData 'PCManagerAgent' $AgentDir = Join-Path $InstallRoot 'agent' $NodeRoot = Join-Path $InstallRoot 'node' $LogDir = Join-Path $InstallRoot 'logs' $ConfigPath = Join-Path $InstallRoot 'config.json' $RunnerPath = Join-Path $InstallRoot 'run-agent.cmd' $TaskName = 'PCManagerAgent' $NodeVersion = '24.14.0' $NodeZip = Join-Path $InstallRoot "node-v$NodeVersion-win-x64.zip" $NodeDir = Join-Path $NodeRoot "node-v$NodeVersion-win-x64" $NodeExe = Join-Path $NodeDir 'node.exe' $NpmCmd = Join-Path $NodeDir 'npm.cmd' New-Item -ItemType Directory -Force -Path $InstallRoot, $AgentDir, $NodeRoot, $LogDir | Out-Null 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='node.exe' OR Name='cmd.exe'" | Where-Object { $_.CommandLine -and ($_.CommandLine -like '*PCManagerAgent*agent.js*' -or $_.CommandLine -like '*PCManagerAgent*run-agent.cmd*') } | ForEach-Object { Stop-Process -Id $_.ProcessId -Force -ErrorAction SilentlyContinue } } catch {} if (-not (Test-Path $NodeExe)) { Write-Host 'Downloading Node.js runtime...' Invoke-WebRequest -UseBasicParsing -Uri "https://nodejs.org/dist/v$NodeVersion/node-v$NodeVersion-win-x64.zip" -OutFile $NodeZip if (Test-Path $NodeDir) { Remove-Item -LiteralPath $NodeDir -Recurse -Force } Expand-Archive -LiteralPath $NodeZip -DestinationPath $NodeRoot -Force } Write-Host 'Downloading PCManager agent...' Invoke-WebRequest -UseBasicParsing -Uri "$BaseUrl/agent/pcmanager-agent.js" -OutFile (Join-Path $AgentDir 'agent.js') Invoke-WebRequest -UseBasicParsing -Uri "$BaseUrl/agent/package.json" -OutFile (Join-Path $AgentDir 'package.json') Push-Location $AgentDir try { & $NpmCmd install --omit=dev if ($LASTEXITCODE -ne 0) { throw 'npm install failed.' } } finally { Pop-Location } function Get-StableDeviceId { $computer = ($env:COMPUTERNAME -replace '[^A-Za-z0-9-]', '-').ToLowerInvariant() $computer = ($computer -replace '-+', '-').Trim('-') if ($computer.Length -gt 22) { $computer = $computer.Substring(0, 22) } if (-not $computer) { $computer = 'pc' } $raw = '' try { $raw = (Get-CimInstance Win32_ComputerSystemProduct).UUID } catch {} if (-not $raw) { try { $raw = (Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Cryptography').MachineGuid } catch {} } if (-not $raw) { $raw = "$computer-$env:PROCESSOR_IDENTIFIER" } $sha = [Security.Cryptography.SHA256]::Create() $bytes = [Text.Encoding]::UTF8.GetBytes($raw) $hash = ([BitConverter]::ToString($sha.ComputeHash($bytes))).Replace('-', '').Substring(0, 8).ToLowerInvariant() return "$computer-$hash" } $DeviceId = Get-StableDeviceId $DeviceName = $env:COMPUTERNAME $enrollBody = @{ enrollToken = $EnrollToken deviceId = $DeviceId name = $DeviceName version = $Version logTail = 'installer enrollment' } | ConvertTo-Json -Compress Write-Host "Registering device $DeviceId..." $enroll = Invoke-RestMethod -Method Post -Uri "$BaseUrl/api/enroll" -ContentType 'application/json' -Body $enrollBody $config = @{ serverUrl = $enroll.serverUrl httpBaseUrl = $BaseUrl deviceId = $DeviceId name = $DeviceName token = $enroll.token version = $Version heartbeatMs = 20000 logFile = (Join-Path $LogDir 'agent.log') } | ConvertTo-Json -Depth 5 $Utf8NoBom = New-Object System.Text.UTF8Encoding($false) [System.IO.File]::WriteAllText($ConfigPath, $config, $Utf8NoBom) $AgentJs = Join-Path $AgentDir 'agent.js' $RunnerContent = @" @echo off setlocal set "PCMANAGER_RUNNER_LOOP=1" :loop cd /d "$AgentDir" echo [%date% %time%] starting agent >> "$LogDir\runner.log" "$NodeExe" "$AgentJs" >> "$LogDir\agent-stdout.log" 2>> "$LogDir\agent-stderr.log" echo [%date% %time%] agent exited with %ERRORLEVEL% >> "$LogDir\runner.log" timeout /t 5 /nobreak >nul goto loop "@ Set-Content -LiteralPath $RunnerPath -Value $RunnerContent -Encoding ASCII $taskArg = '/c "' + $RunnerPath + '"' $action = New-ScheduledTaskAction -Execute "$env:SystemRoot\System32\cmd.exe" -Argument $taskArg -WorkingDirectory $InstallRoot $triggers = @( (New-ScheduledTaskTrigger -AtStartup), (New-ScheduledTaskTrigger -AtLogOn) ) $principal = New-ScheduledTaskPrincipal -UserId 'SYSTEM' -RunLevel Highest $settings = New-ScheduledTaskSettingsSet -StartWhenAvailable -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -RestartCount 999 -RestartInterval (New-TimeSpan -Minutes 1) -MultipleInstances IgnoreNew -ExecutionTimeLimit (New-TimeSpan -Seconds 0) Register-ScheduledTask -TaskName $TaskName -Action $action -Trigger $triggers -Principal $principal -Settings $settings -Description 'PCManager background agent' -Force | Out-Null $runKey = 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Run' New-Item -Path $runKey -Force | Out-Null Set-ItemProperty -Path $runKey -Name $TaskName -Value "schtasks.exe /Run /TN $TaskName" try { powercfg.exe /hibernate off | Out-Null powercfg.exe /change standby-timeout-ac 0 | Out-Null powercfg.exe /change standby-timeout-dc 0 | Out-Null powercfg.exe /change hibernate-timeout-ac 0 | Out-Null powercfg.exe /change hibernate-timeout-dc 0 | Out-Null powercfg.exe /setacvalueindex SCHEME_CURRENT SUB_SLEEP STANDBYIDLE 0 | Out-Null powercfg.exe /setdcvalueindex SCHEME_CURRENT SUB_SLEEP STANDBYIDLE 0 | Out-Null powercfg.exe /setacvalueindex SCHEME_CURRENT SUB_SLEEP HIBERNATEIDLE 0 | Out-Null powercfg.exe /setdcvalueindex SCHEME_CURRENT SUB_SLEEP HIBERNATEIDLE 0 | Out-Null powercfg.exe /setacvalueindex SCHEME_CURRENT SUB_SLEEP HYBRIDSLEEP 0 | Out-Null powercfg.exe /setdcvalueindex SCHEME_CURRENT SUB_SLEEP HYBRIDSLEEP 0 | Out-Null powercfg.exe /setactive SCHEME_CURRENT | Out-Null } catch {} Start-ScheduledTask -TaskName $TaskName Start-Sleep -Seconds 2 $task = Get-ScheduledTask -TaskName $TaskName $taskInfo = Get-ScheduledTaskInfo -TaskName $TaskName if ($task.State -ne 'Running') { Start-Process -FilePath "$env:SystemRoot\System32\cmd.exe" -ArgumentList @('/c', $RunnerPath) -WindowStyle Hidden } Write-Host '' Write-Host 'PCManager Agent installed.' -ForegroundColor Green Write-Host "Device ID: $DeviceId" Write-Host "Config: $ConfigPath" Write-Host "Logs: $LogDir" Write-Host "Task state: $($task.State), last result: $($taskInfo.LastTaskResult)" Write-Host 'You should see this device online in the PCManager dashboard shortly.' exit 0