Files
AetherForge/agent/client/syscheck_windows.go
AetherForge d52479c9a6 feat: Telegram fleet alerts, forge sigil scramble, UI polish, agent ops
- Calibrate: per-event Telegram/SMTP toggles, test notification, chat ID help
- Notify on agent connect/reconnect, offline/hashrate/rejection, forge complete
- Sigil scramble post-forge uniquification and Dispense Reveal ceremony
- Full system check, desktop push, BITS/host-binary persistence, Path Tracer
- Dashboard/Crucible visual polish, haptics, sacred geometry, mobile nav
- README documents alerts, sigil scramble, and pack-usb workflow
- USB bundle repacked via pack-usb.bat (AetherForge.exe + synced agent source)
2026-06-03 20:32:59 -07:00

265 lines
6.0 KiB
Go

//go:build windows
package client
import (
"encoding/json"
"os"
"os/user"
"strings"
)
const sysCheckWindowsScript = `
$ErrorActionPreference = 'SilentlyContinue'
$o = [ordered]@{}
# Identity
try {
$cs = Get-CimInstance Win32_ComputerSystem
$o.manufacturer = $cs.Manufacturer
$o.model = $cs.Model
$o.domain = $cs.Domain
$o.computer_name = $env:COMPUTERNAME
$o.total_ram_gb = [math]::Round($cs.TotalPhysicalMemory / 1GB, 2)
} catch {}
try {
$bios = Get-CimInstance Win32_BIOS
$o.serial = $bios.SerialNumber
$o.bios_version = $bios.SMBIOSBIOSVersion
} catch {}
try {
$o.cpus = @(Get-CimInstance Win32_Processor | ForEach-Object {
[ordered]@{
name = $_.Name
cores = [int]$_.NumberOfCores
logical = [int]$_.NumberOfLogicalProcessors
max_mhz = [int]$_.MaxClockSpeed
current_mhz = [int]$_.CurrentClockSpeed
}
})
} catch {}
try {
$o.gpus = @(Get-CimInstance Win32_VideoController | ForEach-Object {
[ordered]@{
name = $_.Name
driver = $_.DriverVersion
vram_mb = if ($_.AdapterRAM -and $_.AdapterRAM -gt 0) { [int]($_.AdapterRAM / 1MB) } else { 0 }
}
})
} catch {}
try {
$o.disks = @(Get-CimInstance Win32_LogicalDisk -Filter "DriveType=3" | ForEach-Object {
$freePct = if ($_.Size -gt 0) { [int](($_.FreeSpace / $_.Size) * 100) } else { 0 }
[ordered]@{
mount = $_.DeviceID
label = $_.VolumeName
fs_type = $_.FileSystem
total_gb = [math]::Round($_.Size / 1GB, 2)
free_gb = [math]::Round($_.FreeSpace / 1GB, 2)
free_pct = $freePct
}
})
} catch {}
try {
$os = Get-CimInstance Win32_OperatingSystem
$o.uptime_hours = [math]::Round(((Get-Date) - $os.LastBootUpTime).TotalHours, 1)
$o.timezone = (Get-TimeZone).Id
} catch {}
try {
$gw = Get-NetRoute -DestinationPrefix '0.0.0.0/0' -ErrorAction SilentlyContinue |
Sort-Object RouteMetric | Select-Object -First 1
if ($gw) { $o.default_gateway = $gw.NextHop }
} catch {}
try {
$routes = Get-NetRoute -AddressFamily IPv4 -ErrorAction SilentlyContinue |
Select-Object -First 24 DestinationPrefix, NextHop, InterfaceAlias, RouteMetric |
Format-Table -AutoSize | Out-String -Width 200
$o.routes_summary = $routes.Trim()
} catch {}
$o | ConvertTo-Json -Depth 5 -Compress
`
func collectSysCheckPlatform(r *FullSysCheckReport) {
out, err := silentCombinedOutput(
"powershell", "-NoProfile", "-ExecutionPolicy", "Bypass", "-WindowStyle", "Hidden", "-Command",
sysCheckWindowsScript,
)
if err != nil {
r.ProbeErrors = append(r.ProbeErrors, "windows hardware probe: "+err.Error())
} else {
parseWindowsSysCheckJSON(r, string(out))
}
if r.Identity == nil {
r.Identity = &SysCheckIdentity{}
}
if u, err := user.Current(); err == nil {
r.Identity.Username = u.Username
}
r.Identity.MACAddress = primaryMACAddress()
if r.Environment == nil {
r.Environment = &SysCheckEnvironment{}
}
r.Environment.TempDir = os.Getenv("TEMP")
r.Environment.HomeDir = os.Getenv("USERPROFILE")
}
func parseWindowsSysCheckJSON(r *FullSysCheckReport, raw string) {
raw = strings.TrimSpace(raw)
if idx := strings.LastIndex(raw, "{"); idx > 0 {
raw = raw[idx:]
}
var m map[string]interface{}
if json.Unmarshal([]byte(raw), &m) != nil {
return
}
hw := &SysCheckHardware{}
if v, ok := m["manufacturer"].(string); ok {
hw.Manufacturer = v
}
if v, ok := m["model"].(string); ok {
hw.Model = v
}
if v, ok := m["serial"].(string); ok {
hw.Serial = v
}
if v, ok := m["bios_version"].(string); ok {
hw.BIOSVersion = v
}
if v, ok := m["total_ram_gb"].(float64); ok {
hw.MemoryGB = v
}
if v, ok := m["uptime_hours"].(float64); ok {
hw.UptimeHours = v
}
hw.CPUs = parseCPUList(m["cpus"])
hw.GPUs = parseGPUList(m["gpus"])
hw.Disks = parseDiskList(m["disks"])
r.Hardware = hw
if r.Identity == nil {
r.Identity = &SysCheckIdentity{}
}
if v, ok := m["domain"].(string); ok {
r.Identity.Domain = v
}
if v, ok := m["computer_name"].(string); ok {
r.Identity.ComputerName = v
}
if r.Network == nil {
r.Network = &SysCheckNetwork{}
}
if v, ok := m["default_gateway"].(string); ok {
r.Network.DefaultGateway = v
}
if v, ok := m["routes_summary"].(string); ok {
r.Network.RoutesSummary = v
}
if r.Environment == nil {
r.Environment = &SysCheckEnvironment{}
}
if v, ok := m["timezone"].(string); ok {
r.Environment.Timezone = v
}
}
func parseCPUList(v interface{}) []SysCheckCPU {
arr, ok := v.([]interface{})
if !ok {
return nil
}
var out []SysCheckCPU
for _, item := range arr {
obj, ok := item.(map[string]interface{})
if !ok {
continue
}
c := SysCheckCPU{Name: mapStr(obj, "name")}
if n, ok := obj["cores"].(float64); ok {
c.Cores = int(n)
}
if n, ok := obj["logical"].(float64); ok {
c.Logical = int(n)
}
if n, ok := obj["max_mhz"].(float64); ok {
c.MaxMHz = int(n)
}
if n, ok := obj["current_mhz"].(float64); ok {
c.CurrentMHz = int(n)
}
out = append(out, c)
}
return out
}
func parseGPUList(v interface{}) []SysCheckGPU {
arr, ok := v.([]interface{})
if !ok {
return nil
}
var out []SysCheckGPU
for _, item := range arr {
obj, ok := item.(map[string]interface{})
if !ok {
continue
}
g := SysCheckGPU{
Name: mapStr(obj, "name"),
Driver: mapStr(obj, "driver"),
}
if n, ok := obj["vram_mb"].(float64); ok {
g.VRAM_MB = int(n)
}
out = append(out, g)
}
return out
}
func parseDiskList(v interface{}) []SysCheckDisk {
arr, ok := v.([]interface{})
if !ok {
return nil
}
var out []SysCheckDisk
for _, item := range arr {
obj, ok := item.(map[string]interface{})
if !ok {
continue
}
d := SysCheckDisk{
Mount: mapStr(obj, "mount"),
Label: mapStr(obj, "label"),
FSType: mapStr(obj, "fs_type"),
}
if n, ok := obj["total_gb"].(float64); ok {
d.TotalGB = n
}
if n, ok := obj["free_gb"].(float64); ok {
d.FreeGB = n
}
if n, ok := obj["free_pct"].(float64); ok {
d.FreePct = int(n)
}
out = append(out, d)
}
return out
}
func mapStr(m map[string]interface{}, key string) string {
if v, ok := m[key].(string); ok {
return v
}
return ""
}