diff --git a/errorlog.md b/errorlog.md index 1a40d18e..444ba04a 100644 --- a/errorlog.md +++ b/errorlog.md @@ -19,6 +19,12 @@ Categories (the `[type]` tag): _(none)_ = skill/command execution failure · +2026-07-04 | Howard-Home | python/windows | [friction] open(path,'w') defaults to cp1252 on Windows so em-dash/smart-quotes wrote as invalid UTF-8 (0x97), later decode failed; fix: open(...,encoding='utf-8') + +2026-07-04 | Howard-Home | bash/env | [friction] curl inside a while-read loop steals the loop's stdin -> returns empty/partial; fix: add =32 or c in (9,10,13)) +agents=json.loads(clean(get(f"{RMM}/api/agents",{"Authorization":f"Bearer {TOK}"}))) +by_client={} +for a in agents: + by_client.setdefault(a.get("client_name") or "",set()).add((a.get("hostname") or "").lower()) +tgts=json.load(open("projects/gps-rmm-audit/targets.json"))["clients"] +folder_ctr=Counter(); body=[]; total=0 +for t in tgts: + c=t["client"]; cid=t["cid"] + try: data=json.loads(clean(get(f"{BASE}/customer_assets?customer_id={cid}&per_page=100&api_key={SK}"))) + except Exception as e: + body.append(f"**{c}** - ERROR: {e}\n"); continue + dev=[a for a in data.get("assets",[]) if a.get("asset_type")=="Syncro Device" and a.get("name")] + rmm=by_client.get(c,set()) + gap=sorted([a for a in dev if a["name"].lower() not in rmm], key=lambda a:a["name"].lower()) + if not gap: continue + total+=len(gap) + body.append(f"**{c}** - {len(dev)} managed / {len(rmm)} in RMM / {len(gap)} need install") + for a in gap: + f=a.get("policy_folder_id") or "-" + folder_ctr[str(f)]+=1 + body.append(f" - {a['name']} (folder {f})") + body.append("") +out=["# GPS clients - Syncro-managed machines NOT in GuruRMM","", + "Install ScreenConnect / push agent. Syncro assets (authoritative) vs live GuruRMM, 2026-07-03.", + "`folder N` = Syncro policy_folder_id (the ScreenConnect-install policy is tied to a folder - devices in the wrong folder don't get SC).","", + "## Folder distribution across the gap machines (spot the SC-install folder vs outliers)"] +for f,n in folder_ctr.most_common(): + out.append(f"- folder {f}: {n} machines") +out+=["",f"## TOTAL needing install: {total}",""]+body +open("projects/gps-rmm-audit/needs-screenconnect.md","w",encoding="utf-8").write("\n".join(out)) +print(f"total={total}, folders={dict(folder_ctr)}")