# VPS Monitor — Windows PC Agent # Sends system metrics to VPS Monitoring server # # Install: Run install_agent.ps1 # Manual: powershell -ExecutionPolicy Bypass -File vps_monitor_agent.ps1 param( [string]$ServerUrl = "", [string]$AgentName = "", [int]$Interval = 60 ) # Load config $ConfigPath = Join-Path $PSScriptRoot "agent_config.json" if (Test-Path $ConfigPath) { $config = Get-Content $ConfigPath | ConvertFrom-Json if (-not $ServerUrl) { $ServerUrl = $config.server_url } if (-not $AgentName) { $AgentName = $config.agent_name } if ($config.interval) { $Interval = $config.interval } } if (-not $ServerUrl -or -not $AgentName) { Write-Host "ERROR: server_url and agent_name required" -ForegroundColor Red Write-Host "Edit agent_config.json or pass -ServerUrl and -AgentName" exit 1 } Write-Host "================================================" -ForegroundColor Cyan Write-Host " VPS Monitor — PC Agent" -ForegroundColor Cyan Write-Host " Server: $ServerUrl" -ForegroundColor Gray Write-Host " Name: $AgentName" -ForegroundColor Gray Write-Host " Interval: ${Interval}s" -ForegroundColor Gray Write-Host "================================================" -ForegroundColor Cyan Write-Host "" function Get-SystemMetrics { $metrics = @{} # Hostname $metrics["hostname"] = $env:COMPUTERNAME # OS $os = Get-CimInstance Win32_OperatingSystem $metrics["os"] = "$($os.Caption) $($os.Version)" # CPU $cpu = Get-CimInstance Win32_Processor $metrics["cpu_name"] = $cpu.Name $metrics["cpu_percent"] = [math]::Round((Get-Counter '\Processor(_Total)\% Processor Time' -ErrorAction SilentlyContinue).CounterSamples[0].CookedValue, 1) # RAM $totalRam = [math]::Round($os.TotalVisibleMemorySize / 1024, 0) $freeRam = [math]::Round($os.FreePhysicalMemory / 1024, 0) $usedRam = $totalRam - $freeRam $metrics["ram_total_mb"] = $totalRam $metrics["ram_used_mb"] = $usedRam $metrics["ram_percent"] = [math]::Round(($usedRam / $totalRam) * 100, 1) # Disk (all drives) $disks = @() Get-CimInstance Win32_LogicalDisk -Filter "DriveType=3" | ForEach-Object { $totalGb = [math]::Round($_.Size / 1GB, 1) $freeGb = [math]::Round($_.FreeSpace / 1GB, 1) $usedGb = $totalGb - $freeGb $pct = if ($totalGb -gt 0) { [math]::Round(($usedGb / $totalGb) * 100, 1) } else { 0 } $disks += @{ drive = $_.DeviceID total_gb = $totalGb used_gb = $usedGb free_gb = $freeGb percent = $pct } } $metrics["disks"] = $disks # Primary disk summary $primary = $disks | Where-Object { $_.drive -eq "C:" } | Select-Object -First 1 if ($primary) { $metrics["disk_total_gb"] = $primary.total_gb $metrics["disk_used_gb"] = $primary.used_gb $metrics["disk_percent"] = $primary.percent } # Network $adapters = Get-NetAdapter -Physical -ErrorAction SilentlyContinue | Where-Object { $_.Status -eq "Up" } $netInfo = @() foreach ($a in $adapters) { $stats = Get-NetAdapterStatistics -Name $a.Name -ErrorAction SilentlyContinue $netInfo += @{ name = $a.Name speed_mbps = [math]::Round($a.LinkSpeed.Replace(" Gbps","000").Replace(" Mbps","") -as [double], 0) sent_mb = if ($stats) { [math]::Round($stats.SentBytes / 1MB, 0) } else { 0 } received_mb = if ($stats) { [math]::Round($stats.ReceivedBytes / 1MB, 0) } else { 0 } } } $metrics["network"] = $netInfo # Uptime $uptime = (Get-Date) - $os.LastBootUpTime $metrics["uptime"] = "up $($uptime.Days)d $($uptime.Hours)h $($uptime.Minutes)m" $metrics["uptime_seconds"] = [math]::Round($uptime.TotalSeconds, 0) # GPU (if available) try { $gpu = Get-CimInstance Win32_VideoController | Select-Object -First 1 if ($gpu) { $metrics["gpu_name"] = $gpu.Name $metrics["gpu_ram_mb"] = [math]::Round($gpu.AdapterRAM / 1MB, 0) } } catch {} # Top processes by CPU $topProcs = Get-Process | Sort-Object CPU -Descending | Select-Object -First 5 | ForEach-Object { @{ name = $_.ProcessName; cpu = [math]::Round($_.CPU, 1); ram_mb = [math]::Round($_.WorkingSet64 / 1MB, 0) } } $metrics["top_processes"] = $topProcs return $metrics } function Send-Metrics($metrics) { $body = @{ agent_name = $AgentName timestamp = (Get-Date).ToString("o") metrics = $metrics } | ConvertTo-Json -Depth 5 try { $response = Invoke-RestMethod -Uri "$ServerUrl/api/pc/heartbeat" ` -Method POST ` -Body $body ` -ContentType "application/json" ` -TimeoutSec 15 return $true } catch { Write-Host " [!] Send failed: $($_.Exception.Message)" -ForegroundColor Yellow return $false } } # Main loop Write-Host "Agent started. Press Ctrl+C to stop." -ForegroundColor Green Write-Host "" while ($true) { $ts = Get-Date -Format "HH:mm:ss" try { $metrics = Get-SystemMetrics $ok = Send-Metrics $metrics if ($ok) { Write-Host "[$ts] OK — CPU: $($metrics.cpu_percent)% RAM: $($metrics.ram_percent)% Disk: $($metrics.disk_percent)%" -ForegroundColor Green } } catch { Write-Host "[$ts] ERROR: $($_.Exception.Message)" -ForegroundColor Red } Start-Sleep -Seconds $Interval }