feat(rmm): onboarding diagnostic (Phase 1) - probe + triage + baseline
/rmm diagnose: dispatches a Windows security/health probe to a newly onboarded agent, grades RED/AMBER/GREEN, writes an immutable per-client baseline (clients/<slug>/onboarding-baselines/), diffs vs prior, and alerts CRITICALs to #dev-alerts. Probe is PS5.1/ASCII/SYSTEM-safe, never-abort, base64 chunked upload around the agent command-size cap. Code-reviewed (no blockers); folded in immutability guard, severity-independent finding ids, Defender-unknown sentinel, expanded competitor/backup detection. First baselines captured: Rednour FRONTDESKRECEPT + LEGALASST (both RED - prior MSP ScreenConnect/Splashtop/Syncro still live; LEGALASST OS EOL). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -24,6 +24,7 @@ Interact with the GuruRMM agent fleet: list agents, run remote commands (PowerSh
|
||||
/rmm cancel <command_id> Cancel a pending or running command
|
||||
/rmm history <hostname|uuid> [N] Recent command history (default 10, max 500)
|
||||
/rmm onboard <client name> [site] Create a new client + site, vault the one-time enrollment key
|
||||
/rmm diagnose <hostname|uuid> [client] Run onboarding health/security diagnostic + baseline
|
||||
```
|
||||
|
||||
---
|
||||
@@ -679,6 +680,84 @@ git -C "$VR" add "clients/$SLUG/gururmm-site-main.sops.yaml" && git -C "$VR" com
|
||||
|
||||
---
|
||||
|
||||
## Onboarding diagnostic (`/rmm diagnose`)
|
||||
|
||||
Run a one-shot security + health + inventory probe against a newly onboarded
|
||||
Windows agent and produce a prioritized "take this seriously" report plus an
|
||||
immutable before/after baseline. This is the Phase 1 tooling implementation;
|
||||
a native GuruRMM feature (DB-backed storage, scheduled re-baselines) is Phase 3.
|
||||
|
||||
**Runner:** `.claude/scripts/run-onboarding-diagnostic.sh <hostname|uuid> [client-slug]`
|
||||
**Probe:** `.claude/scripts/onboarding-diagnostic.ps1` (Windows PowerShell 5.1, ASCII, runs as SYSTEM)
|
||||
|
||||
```bash
|
||||
bash "$REPO_ROOT/.claude/scripts/run-onboarding-diagnostic.sh" FrontDeskReception rednour
|
||||
```
|
||||
|
||||
If no client-slug is given, it is derived by slugifying the agent's `client_name`.
|
||||
|
||||
### Workflow
|
||||
|
||||
1. Authenticate to RMM (vault creds, same as the rest of this skill).
|
||||
2. Resolve the agent (exact UUID, exact hostname, then partial). Windows-only.
|
||||
3. Upload the probe to the endpoint **base64-encoded, in <24 KB chunks** (the
|
||||
agent caps an inline command body at ~32-40 KB; the probe is ~60 KB), then a
|
||||
final small command decodes it to a `.ps1`, runs it, and deletes both temp
|
||||
files. Every check in the probe is wrapped in try/catch, so one failing check
|
||||
becomes an `unknown`-severity finding instead of aborting the probe.
|
||||
4. The probe emits a single JSON object fenced by `===DIAG-JSON-START===` /
|
||||
`===DIAG-JSON-END===`; the runner extracts it from between the markers.
|
||||
5. Grade, write two baseline files, diff against any prior baseline, alert.
|
||||
|
||||
### Grade model
|
||||
|
||||
| Grade | Meaning |
|
||||
|-------|---------|
|
||||
| **RED** | At least one `critical` finding |
|
||||
| **AMBER** | At least one `warning`, no `critical` |
|
||||
| **GREEN** | No `critical` and no `warning` |
|
||||
|
||||
`unknown`-severity findings (a check that failed to run) do not change the grade
|
||||
but are listed in the report for manual follow-up.
|
||||
|
||||
### What it checks
|
||||
|
||||
- **Security:** Defender state (RTP/service/signature age/tamper), 3rd-party AV
|
||||
conflicts, leftover competitor RMM / remote-access agents (ScreenConnect,
|
||||
NinjaRMM, Datto, Atera, Kaseya, TeamViewer, AnyDesk, Splashtop, N-able,
|
||||
Syncro, Action1, Automate, LogMeIn), firewall profiles, BitLocker (laptop-aware),
|
||||
local admins / built-in Administrator / non-expiring passwords, patch posture +
|
||||
OS EOL, RDP/NLA, SMBv1, UAC, LAPS.
|
||||
- **Health:** disk free %, SMART/physical-disk health, 14-day stability
|
||||
(unexpected shutdown / BSOD / disk errors), pending reboot, uptime, failed
|
||||
auto-start services, domain secure channel, time source, battery (laptops),
|
||||
backup-agent presence.
|
||||
- **Inventory baseline (info):** model/serial, CPU/RAM, BIOS, TPM, Secure Boot,
|
||||
OS edition/build/activation, full installed-software list, local users/groups,
|
||||
network, scheduled tasks + Run-key autoruns.
|
||||
|
||||
### Where baselines are stored
|
||||
|
||||
`clients/<slug>/onboarding-baselines/` — two files per run, both timestamped
|
||||
`<HOST>-<UTC-YYYYMMDDTHHMMSS>`:
|
||||
|
||||
- `*.json` — the raw immutable snapshot (do not edit; it is the source of truth
|
||||
for diffs).
|
||||
- `*.md` — the human report: grade, findings grouped critical -> warning ->
|
||||
info -> unknown, inventory summary, and a diff section vs the most recent prior
|
||||
baseline (new / resolved / regressed findings, software added/removed).
|
||||
|
||||
Baselines are immutable and append-only. GuruRMM-DB storage of baselines arrives
|
||||
with the Phase 3 native feature.
|
||||
|
||||
### Alerting
|
||||
|
||||
Each **CRITICAL** finding and a **RED** overall grade auto-post a one-line
|
||||
`[RMM]` alert to **#dev-alerts** via `post-bot-alert.sh` (ASCII only, soft-fail).
|
||||
Example: `[RMM] Onboarding diag <HOST> (<client>) = RED: <n> critical - <titles>`.
|
||||
|
||||
---
|
||||
|
||||
## Known enrolled agents (verify with GET /api/agents — UUIDs change on re-enroll)
|
||||
|
||||
Do not use this table as authoritative — always resolve live. Treat as a starting hint only.
|
||||
|
||||
1275
.claude/scripts/onboarding-diagnostic.ps1
Normal file
1275
.claude/scripts/onboarding-diagnostic.ps1
Normal file
File diff suppressed because it is too large
Load Diff
574
.claude/scripts/run-onboarding-diagnostic.sh
Normal file
574
.claude/scripts/run-onboarding-diagnostic.sh
Normal file
@@ -0,0 +1,574 @@
|
||||
#!/usr/bin/env bash
|
||||
# run-onboarding-diagnostic.sh - GuruRMM onboarding diagnostic runner (Phase 1).
|
||||
#
|
||||
# Dispatches .claude/scripts/onboarding-diagnostic.ps1 to a Windows agent via the
|
||||
# GuruRMM RMM API, extracts the fenced JSON result, grades it RED/AMBER/GREEN,
|
||||
# writes an immutable baseline (JSON + Markdown report) under
|
||||
# clients/<slug>/onboarding-baselines/, diffs against any prior baseline, and
|
||||
# alerts #dev-alerts on RED / critical findings.
|
||||
#
|
||||
# Usage:
|
||||
# bash run-onboarding-diagnostic.sh <hostname-or-uuid> [client-slug]
|
||||
#
|
||||
# Mirrors the plumbing in .claude/commands/rmm.md (vault auth -> JWT -> dispatch
|
||||
# -> poll -> command_text/stdout). Read-only against the endpoint; the probe only
|
||||
# collects, it changes nothing.
|
||||
|
||||
set -u
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Args
|
||||
# ---------------------------------------------------------------------------
|
||||
TARGET="${1:-}"
|
||||
CLIENT_SLUG="${2:-}"
|
||||
|
||||
if [ -z "$TARGET" ]; then
|
||||
echo "[ERROR] Usage: bash run-onboarding-diagnostic.sh <hostname-or-uuid> [client-slug]" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Bootstrap (resolve repo root, vault, RMM base)
|
||||
# ---------------------------------------------------------------------------
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
||||
VAULT="$REPO_ROOT/.claude/scripts/vault.sh"
|
||||
PROBE="$SCRIPT_DIR/onboarding-diagnostic.ps1"
|
||||
ALERT="$REPO_ROOT/.claude/scripts/post-bot-alert.sh"
|
||||
RMM="http://172.16.3.30:3001"
|
||||
|
||||
if [ ! -f "$PROBE" ]; then
|
||||
echo "[ERROR] Probe script not found: $PROBE" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
for tool in jq curl; do
|
||||
if ! command -v "$tool" >/dev/null 2>&1; then
|
||||
echo "[ERROR] Required tool not found: $tool" >&2
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
# Soft-fail wrapper for the bot alert so an alerting failure never aborts the run.
|
||||
post_alert() {
|
||||
local msg="$1"
|
||||
if [ -f "$ALERT" ]; then
|
||||
bash "$ALERT" "$msg" >/dev/null 2>&1 || true
|
||||
fi
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Authenticate
|
||||
# ---------------------------------------------------------------------------
|
||||
RMM_EMAIL="$(bash "$VAULT" get-field infrastructure/gururmm-server.sops.yaml credentials.gururmm-api.admin-email 2>/dev/null)"
|
||||
RMM_PASS="$(bash "$VAULT" get-field infrastructure/gururmm-server.sops.yaml credentials.gururmm-api.admin-password 2>/dev/null)"
|
||||
|
||||
if [ -z "$RMM_EMAIL" ] || [ -z "$RMM_PASS" ] || [ "$RMM_EMAIL" = "null" ]; then
|
||||
echo "[ERROR] Could not read GuruRMM credentials from vault (infrastructure/gururmm-server.sops.yaml)" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
LOGIN_PAYLOAD="$(jq -nc --arg e "$RMM_EMAIL" --arg p "$RMM_PASS" '{email:$e, password:$p}')"
|
||||
TOKEN="$(curl -s -m 30 -X POST "$RMM/api/auth/login" \
|
||||
-H "Content-Type: application/json" \
|
||||
--data-binary "$LOGIN_PAYLOAD" | jq -r '.token // empty')"
|
||||
|
||||
if [ -z "$TOKEN" ]; then
|
||||
echo "[ERROR] RMM login failed (no token returned)" >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "[OK] Authenticated to GuruRMM"
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Resolve agent (by exact UUID, exact hostname, then partial hostname)
|
||||
# ---------------------------------------------------------------------------
|
||||
AGENTS="$(curl -s -m 30 "$RMM/api/agents" -H "Authorization: Bearer $TOKEN")"
|
||||
if [ -z "$AGENTS" ] || ! echo "$AGENTS" | jq -e 'type=="array"' >/dev/null 2>&1; then
|
||||
echo "[ERROR] Could not retrieve agent list" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# UUID-shaped target -> match by id; otherwise match by hostname.
|
||||
AGENT=""
|
||||
if echo "$TARGET" | grep -qiE '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$'; then
|
||||
AGENT="$(echo "$AGENTS" | jq --arg id "$TARGET" '[.[] | select(.id==$id)] | .[0] // empty')"
|
||||
else
|
||||
# exact hostname (case-insensitive) first
|
||||
AGENT="$(echo "$AGENTS" | jq --arg h "$TARGET" '[.[] | select((.hostname|ascii_downcase)==($h|ascii_downcase))] | .[0] // empty')"
|
||||
if [ -z "$AGENT" ] || [ "$AGENT" = "null" ]; then
|
||||
# partial match
|
||||
MATCHES="$(echo "$AGENTS" | jq --arg h "$TARGET" '[.[] | select(.hostname|ascii_downcase|contains($h|ascii_downcase))]')"
|
||||
COUNT="$(echo "$MATCHES" | jq 'length')"
|
||||
if [ "$COUNT" = "0" ]; then
|
||||
AGENT=""
|
||||
elif [ "$COUNT" = "1" ]; then
|
||||
AGENT="$(echo "$MATCHES" | jq '.[0]')"
|
||||
else
|
||||
echo "[ERROR] Multiple agents match '$TARGET' - be more specific:" >&2
|
||||
echo "$MATCHES" | jq -r '.[] | " \(.hostname) (\(.os_type)) id=\(.id) client=\(.client_name)"' >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$AGENT" ] || [ "$AGENT" = "null" ]; then
|
||||
echo "[ERROR] No agent found matching '$TARGET'. Run /rmm agents to list enrolled agents." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
AGENT_ID="$(echo "$AGENT" | jq -r '.id // empty')"
|
||||
AGENT_HOST="$(echo "$AGENT" | jq -r '.hostname // empty')"
|
||||
AGENT_OS="$(echo "$AGENT" | jq -r '.os_type // empty')"
|
||||
AGENT_STATUS="$(echo "$AGENT" | jq -r '.status // "unknown"')"
|
||||
AGENT_CONNECTED="$(echo "$AGENT" | jq -r '.is_connected // "null"')"
|
||||
AGENT_CLIENT="$(echo "$AGENT" | jq -r '.client_name // empty')"
|
||||
AGENT_LAST="$(echo "$AGENT" | jq -r '.last_seen // "never"')"
|
||||
|
||||
echo "[OK] Agent: $AGENT_HOST ($AGENT_OS) status=$AGENT_STATUS connected=$AGENT_CONNECTED client=$AGENT_CLIENT last_seen=$AGENT_LAST id=$AGENT_ID"
|
||||
|
||||
if [ "$AGENT_OS" != "windows" ]; then
|
||||
echo "[ERROR] This diagnostic is Windows-only. Agent os_type='$AGENT_OS'." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Treat online if status==online OR is_connected==true (is_connected can be null even when online).
|
||||
if [ "$AGENT_STATUS" != "online" ] && [ "$AGENT_CONNECTED" != "true" ]; then
|
||||
echo "[WARNING] Agent appears offline (status=$AGENT_STATUS). The command will queue and run when it reconnects."
|
||||
fi
|
||||
|
||||
# Derive client slug if not supplied: prefer explicit arg; else slugify client_name.
|
||||
if [ -z "$CLIENT_SLUG" ]; then
|
||||
if [ -n "$AGENT_CLIENT" ]; then
|
||||
CLIENT_SLUG="$(echo "$AGENT_CLIENT" | tr '[:upper:]' '[:lower:]' | sed -E 's/[^a-z0-9]+/-/g; s/^-+//; s/-+$//')"
|
||||
echo "[INFO] No client slug supplied; derived '$CLIENT_SLUG' from client name '$AGENT_CLIENT'."
|
||||
else
|
||||
CLIENT_SLUG="_unsorted"
|
||||
echo "[WARNING] No client slug and no client name; using '_unsorted'."
|
||||
fi
|
||||
fi
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Command dispatch helper
|
||||
# ---------------------------------------------------------------------------
|
||||
# The agent caps the inline command body at roughly 32-40 KB (above that it
|
||||
# returns "Failed to execute command" before PowerShell ever runs). The probe is
|
||||
# ~60 KB, so we cannot send it inline. Instead we:
|
||||
# 1. base64-encode the probe locally,
|
||||
# 2. upload it to a temp file on the endpoint in <24 KB chunks (one command
|
||||
# each: first writes, the rest append),
|
||||
# 3. send a final small command that decodes the file to a .ps1, runs it,
|
||||
# prints the fenced JSON, and deletes both temp files.
|
||||
# Each dispatched command stays well under the agent limit, so this scales no
|
||||
# matter how large the probe grows in later phases.
|
||||
|
||||
WORK_DIR="$(mktemp -d 2>/dev/null || echo "${TMPDIR:-/tmp}/onboard-diag-$$")"
|
||||
mkdir -p "$WORK_DIR" 2>/dev/null || true
|
||||
cleanup() { rm -rf "$WORK_DIR" 2>/dev/null || true; }
|
||||
trap cleanup EXIT
|
||||
|
||||
# dispatch_one <command-file-with-script> <timeout_seconds> -> echoes result JSON, returns 0/1
|
||||
dispatch_one() {
|
||||
local script_file="$1"
|
||||
local to="$2"
|
||||
local payload_file resp cmd_id status result count
|
||||
|
||||
payload_file="$WORK_DIR/payload.json"
|
||||
jq -nc --rawfile cmd "$script_file" --argjson to "$to" \
|
||||
'{command_type:"powershell", command:$cmd, timeout_seconds:$to}' > "$payload_file"
|
||||
|
||||
resp="$(curl -s -m 30 -X POST "$RMM/api/agents/$AGENT_ID/command" \
|
||||
-H "Authorization: Bearer $TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
--data-binary "@$payload_file")"
|
||||
cmd_id="$(echo "$resp" | jq -r '.command_id // empty')"
|
||||
if [ -z "$cmd_id" ]; then
|
||||
echo "[ERROR] Dispatch failed: $resp" >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
count=0
|
||||
while [ $count -lt 72 ]; do
|
||||
result="$(curl -s -m 30 "$RMM/api/commands/$cmd_id" -H "Authorization: Bearer $TOKEN")"
|
||||
status="$(echo "$result" | jq -r '.status // empty')"
|
||||
case "$status" in
|
||||
completed|failed|cancelled|interrupted)
|
||||
# Persist the command id to a file: this function runs in a $( )
|
||||
# subshell, so a plain variable assignment would not survive.
|
||||
printf '%s' "$cmd_id" > "$WORK_DIR/last_cmd_id" 2>/dev/null || true
|
||||
echo "$result"
|
||||
return 0
|
||||
;;
|
||||
running|pending|"") count=$((count + 1)); sleep 5 ;;
|
||||
*) count=$((count + 1)); sleep 5 ;;
|
||||
esac
|
||||
done
|
||||
echo "[ERROR] Command $cmd_id did not finish (last status=$status)" >&2
|
||||
return 1
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Upload probe (base64, chunked) then execute
|
||||
# ---------------------------------------------------------------------------
|
||||
echo "[INFO] Uploading probe to endpoint (chunked base64)..."
|
||||
|
||||
# Stable-ish remote temp names; unique per run via timestamp+pid.
|
||||
REMOTE_TAG="grmm_onboard_$(date -u +%Y%m%d%H%M%S)_$$"
|
||||
REMOTE_B64="\$env:TEMP\\${REMOTE_TAG}.b64"
|
||||
REMOTE_PS1="\$env:TEMP\\${REMOTE_TAG}.ps1"
|
||||
|
||||
# Produce base64 (single line) and split into chunks.
|
||||
B64_FILE="$WORK_DIR/probe.b64"
|
||||
base64 -w0 "$PROBE" > "$B64_FILE" 2>/dev/null || base64 "$PROBE" | tr -d '\n' > "$B64_FILE"
|
||||
CHUNK_DIR="$WORK_DIR/chunks"
|
||||
mkdir -p "$CHUNK_DIR"
|
||||
split -b 24000 "$B64_FILE" "$CHUNK_DIR/chunk_"
|
||||
CHUNKS=$(ls -1 "$CHUNK_DIR"/chunk_* | sort)
|
||||
N_CHUNKS=$(echo "$CHUNKS" | wc -l | tr -d ' ')
|
||||
echo "[INFO] Probe is $(wc -c < "$PROBE") bytes -> $N_CHUNKS chunk(s)"
|
||||
|
||||
IDX=0
|
||||
for ch in $CHUNKS; do
|
||||
IDX=$((IDX + 1))
|
||||
# INVARIANT: DATA is RFC4648 standard base64 (alphabet A-Za-z0-9+/ with '='
|
||||
# padding). None of those characters are PowerShell metacharacters, so DATA
|
||||
# is safe to interpolate raw into the here-doc below. If this is ever changed
|
||||
# to base64url (alphabet adds '-' and '_'), it stays safe too - but revisit
|
||||
# this assertion before swapping the encoder, do not assume silently.
|
||||
DATA="$(cat "$ch")"
|
||||
SCRIPT_FILE="$WORK_DIR/chunkcmd.ps1"
|
||||
if [ "$IDX" -eq 1 ]; then
|
||||
# First chunk: create/overwrite the file (no newline appended).
|
||||
cat > "$SCRIPT_FILE" <<PS
|
||||
\$ErrorActionPreference = 'Stop'
|
||||
[System.IO.File]::WriteAllText("$REMOTE_B64", "$DATA")
|
||||
Write-Output "CHUNK $IDX OK"
|
||||
PS
|
||||
else
|
||||
cat > "$SCRIPT_FILE" <<PS
|
||||
\$ErrorActionPreference = 'Stop'
|
||||
[System.IO.File]::AppendAllText("$REMOTE_B64", "$DATA")
|
||||
Write-Output "CHUNK $IDX OK"
|
||||
PS
|
||||
fi
|
||||
CH_RESULT="$(dispatch_one "$SCRIPT_FILE" 60)" || { echo "[ERROR] Chunk $IDX dispatch failed" >&2; exit 1; }
|
||||
CH_STATUS="$(echo "$CH_RESULT" | jq -r '.status')"
|
||||
if [ "$CH_STATUS" != "completed" ]; then
|
||||
echo "[ERROR] Chunk $IDX upload failed: status=$CH_STATUS stderr=$(echo "$CH_RESULT" | jq -r '.stderr' | head -c 200)" >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "[OK] Uploaded chunk $IDX/$N_CHUNKS"
|
||||
done
|
||||
|
||||
echo "[INFO] Decoding and executing probe on endpoint (timeout 240s)..."
|
||||
|
||||
# Final command: decode base64 file -> .ps1, run it, then clean up both temp files.
|
||||
RUN_SCRIPT="$WORK_DIR/runcmd.ps1"
|
||||
cat > "$RUN_SCRIPT" <<PS
|
||||
\$ErrorActionPreference = 'Continue'
|
||||
try {
|
||||
\$b64 = [System.IO.File]::ReadAllText("$REMOTE_B64")
|
||||
\$bytes = [System.Convert]::FromBase64String(\$b64)
|
||||
[System.IO.File]::WriteAllBytes("$REMOTE_PS1", \$bytes)
|
||||
& powershell.exe -NonInteractive -ExecutionPolicy Bypass -File "$REMOTE_PS1"
|
||||
} catch {
|
||||
Write-Output ("PROBE_RUN_ERROR: " + \$_.Exception.Message)
|
||||
} finally {
|
||||
Remove-Item -Path "$REMOTE_B64" -Force -ErrorAction SilentlyContinue
|
||||
Remove-Item -Path "$REMOTE_PS1" -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
PS
|
||||
|
||||
RESULT="$(dispatch_one "$RUN_SCRIPT" 240)" || { echo "[ERROR] Probe execution dispatch failed" >&2; exit 1; }
|
||||
CMD_ID="$(cat "$WORK_DIR/last_cmd_id" 2>/dev/null || echo unknown)"
|
||||
|
||||
FINAL_STATUS="$(echo "$RESULT" | jq -r '.status // empty')"
|
||||
EXIT_CODE="$(echo "$RESULT" | jq -r '.exit_code // "null"')"
|
||||
STDOUT="$(echo "$RESULT" | jq -r '.stdout // ""')"
|
||||
STDERR="$(echo "$RESULT" | jq -r '.stderr // ""')"
|
||||
|
||||
echo "[INFO] Probe finished: status=$FINAL_STATUS exit_code=$EXIT_CODE stdout_len=${#STDOUT} stderr_len=${#STDERR} cmd=$CMD_ID"
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Extract fenced JSON from stdout
|
||||
# ---------------------------------------------------------------------------
|
||||
# Pull text strictly between the markers. awk handles arbitrary surrounding noise.
|
||||
DIAG_JSON="$(printf '%s' "$STDOUT" | awk '
|
||||
/===DIAG-JSON-START===/ { capture=1; next }
|
||||
/===DIAG-JSON-END===/ { capture=0 }
|
||||
capture { print }
|
||||
')"
|
||||
|
||||
if [ -z "$DIAG_JSON" ] || ! echo "$DIAG_JSON" | jq -e '.host' >/dev/null 2>&1; then
|
||||
echo "[ERROR] Could not extract valid diagnostic JSON from probe output." >&2
|
||||
echo "[ERROR] status=$FINAL_STATUS exit_code=$EXIT_CODE" >&2
|
||||
if [ -n "$STDERR" ]; then
|
||||
echo "--- stderr ---" >&2
|
||||
printf '%s\n' "$STDERR" | head -40 >&2
|
||||
fi
|
||||
echo "--- stdout (first 60 lines) ---" >&2
|
||||
printf '%s\n' "$STDOUT" | head -60 >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "[OK] Extracted diagnostic JSON ($(echo "$DIAG_JSON" | wc -c | tr -d ' ') bytes)"
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Grade: RED (any critical) / AMBER (any warning, no critical) / GREEN (none)
|
||||
# ---------------------------------------------------------------------------
|
||||
N_CRIT="$(echo "$DIAG_JSON" | jq '[.findings[] | select(.severity=="critical")] | length')"
|
||||
N_WARN="$(echo "$DIAG_JSON" | jq '[.findings[] | select(.severity=="warning")] | length')"
|
||||
N_UNK="$(echo "$DIAG_JSON" | jq '[.findings[] | select(.severity=="unknown")] | length')"
|
||||
N_INFO="$(echo "$DIAG_JSON" | jq '[.findings[] | select(.severity=="info")] | length')"
|
||||
|
||||
if [ "$N_CRIT" -gt 0 ]; then
|
||||
GRADE="RED"
|
||||
elif [ "$N_WARN" -gt 0 ]; then
|
||||
GRADE="AMBER"
|
||||
else
|
||||
GRADE="GREEN"
|
||||
fi
|
||||
|
||||
PROBE_HOST="$(echo "$DIAG_JSON" | jq -r '.host // empty')"
|
||||
[ -z "$PROBE_HOST" ] && PROBE_HOST="$AGENT_HOST"
|
||||
COLLECTED="$(echo "$DIAG_JSON" | jq -r '.collected_at_utc // empty')"
|
||||
|
||||
echo "[INFO] Grade=$GRADE critical=$N_CRIT warning=$N_WARN unknown=$N_UNK info=$N_INFO"
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Output paths
|
||||
# ---------------------------------------------------------------------------
|
||||
BASE_DIR="$REPO_ROOT/clients/$CLIENT_SLUG/onboarding-baselines"
|
||||
mkdir -p "$BASE_DIR"
|
||||
|
||||
UTC_STAMP="$(date -u +%Y%m%dT%H%M%S)"
|
||||
SAFE_HOST="$(echo "$PROBE_HOST" | sed -E 's/[^A-Za-z0-9._-]+/_/g')"
|
||||
JSON_PATH="$BASE_DIR/${SAFE_HOST}-${UTC_STAMP}.json"
|
||||
MD_PATH="$BASE_DIR/${SAFE_HOST}-${UTC_STAMP}.md"
|
||||
|
||||
# Immutability guard: the per-second UTC_STAMP can collide if two runs land in
|
||||
# the same second (or a re-run of the same dispatch). A baseline is immutable
|
||||
# once written, so never truncate an existing one - append a PID uniquifier
|
||||
# instead so the prior baseline survives intact.
|
||||
if [ -e "$JSON_PATH" ]; then JSON_PATH="${JSON_PATH%.json}-$$.json"; MD_PATH="${MD_PATH%.md}-$$.md"; fi
|
||||
|
||||
# Find the most recent PRIOR baseline json for this host (before we write the new one).
|
||||
PRIOR_JSON=""
|
||||
PRIOR_JSON="$(ls -1 "$BASE_DIR/${SAFE_HOST}-"*.json 2>/dev/null | sort | tail -n 1)"
|
||||
|
||||
# Write the immutable raw snapshot (pretty-printed for readability/diffing).
|
||||
echo "$DIAG_JSON" | jq '.' > "$JSON_PATH"
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Build the Markdown report
|
||||
# ---------------------------------------------------------------------------
|
||||
{
|
||||
echo "# Onboarding Diagnostic Baseline - $PROBE_HOST"
|
||||
echo ""
|
||||
echo "- **Grade:** $GRADE"
|
||||
echo "- **Host:** $PROBE_HOST"
|
||||
echo "- **Client:** ${AGENT_CLIENT:-$CLIENT_SLUG} (\`$CLIENT_SLUG\`)"
|
||||
echo "- **Collected (UTC):** $COLLECTED"
|
||||
echo "- **Agent ID:** $AGENT_ID"
|
||||
echo "- **Command ID:** $CMD_ID"
|
||||
echo "- **Findings:** $N_CRIT critical / $N_WARN warning / $N_INFO info / $N_UNK unknown"
|
||||
echo ""
|
||||
OS_CAPTION="$(echo "$DIAG_JSON" | jq -r '.os.caption // "?"')"
|
||||
OS_BUILD="$(echo "$DIAG_JSON" | jq -r '.os.build // "?"')"
|
||||
echo "- **OS:** $OS_CAPTION (build $OS_BUILD)"
|
||||
echo ""
|
||||
echo "---"
|
||||
echo ""
|
||||
|
||||
for sev in critical warning info unknown; do
|
||||
SEV_COUNT="$(echo "$DIAG_JSON" | jq --arg s "$sev" '[.findings[] | select(.severity==$s)] | length')"
|
||||
[ "$SEV_COUNT" = "0" ] && continue
|
||||
SEV_LABEL="$(echo "$sev" | tr '[:lower:]' '[:upper:]')"
|
||||
echo "## $SEV_LABEL ($SEV_COUNT)"
|
||||
echo ""
|
||||
echo "$DIAG_JSON" | jq -r --arg s "$sev" '
|
||||
.findings[] | select(.severity==$s) |
|
||||
"### " + .title + "\n" +
|
||||
"- **Category:** " + (.category // "?") + "\n" +
|
||||
"- **ID:** `" + (.id // "?") + "`\n" +
|
||||
"- " + (.detail // "") + "\n" +
|
||||
(if (.evidence // "") != "" then "\n```\n" + .evidence + "\n```\n" else "" end)
|
||||
'
|
||||
echo ""
|
||||
done
|
||||
|
||||
echo "---"
|
||||
echo ""
|
||||
echo "## Inventory Baseline Summary"
|
||||
echo ""
|
||||
echo "$DIAG_JSON" | jq -r '
|
||||
.facts as $f |
|
||||
"- **Manufacturer / Model:** " + (($f.hardware.manufacturer // "?") + " / " + ($f.hardware.model // "?")) + "\n" +
|
||||
"- **Serial:** " + ($f.hardware.serial // "?") + "\n" +
|
||||
"- **CPU:** " + ($f.hardware.cpu // "?") + " (" + (($f.hardware.cpu_cores // 0)|tostring) + " cores / " + (($f.hardware.cpu_logical // 0)|tostring) + " logical)\n" +
|
||||
"- **RAM (GB):** " + (($f.hardware.ram_gb // 0)|tostring) + "\n" +
|
||||
"- **BIOS:** " + ($f.hardware.bios_version // "?") + " (" + ($f.hardware.bios_date // "?") + ")\n" +
|
||||
"- **Chassis is laptop:** " + (($f.is_laptop // false)|tostring) + "\n" +
|
||||
"- **TPM present / Secure Boot:** " + (($f.tpm.present // "?")|tostring) + " / " + (($f.secure_boot // "?")|tostring) + "\n" +
|
||||
"- **Domain joined:** " + (($f.domain_joined // false)|tostring) + " (" + ($f.domain // "?") + ")\n" +
|
||||
"- **OS activation licensed:** " + (($f.activation.licensed // "?")|tostring) + "\n" +
|
||||
"- **Uptime (days):** " + (($f.uptime_days // "?")|tostring) + "\n" +
|
||||
"- **Pending reboot:** " + (($f.pending_reboot // false)|tostring) + "\n" +
|
||||
"- **Installed software count:** " + (($f.installed_software_count // 0)|tostring) + "\n" +
|
||||
"- **Scheduled tasks (non-MS, enabled):** " + (($f.scheduled_tasks_count // 0)|tostring) + "\n" +
|
||||
"- **Local administrators:** " + (($f.local_administrators // []) | join(", "))
|
||||
'
|
||||
echo ""
|
||||
echo "### Fixed volumes"
|
||||
echo ""
|
||||
echo "$DIAG_JSON" | jq -r '
|
||||
(.facts.volumes // []) | .[] |
|
||||
"- " + (.drive // "?") + " - " + ((.free_gb // 0)|tostring) + " GB free of " + ((.size_gb // 0)|tostring) + " GB (" + ((.free_pct // 0)|tostring) + "%)"
|
||||
'
|
||||
echo ""
|
||||
echo "### Network adapters"
|
||||
echo ""
|
||||
echo "$DIAG_JSON" | jq -r '
|
||||
(.facts.network_adapters // []) | .[] |
|
||||
"- " + (.description // "?") + " - IP: " + ((.ip // []) | join(", ")) + " - DNS: " + ((.dns // []) | join(", ")) + " - DHCP: " + ((.dhcp // false)|tostring)
|
||||
'
|
||||
echo ""
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
# DIFF section vs prior baseline
|
||||
# -----------------------------------------------------------------------
|
||||
if [ -n "$PRIOR_JSON" ] && [ -f "$PRIOR_JSON" ]; then
|
||||
PRIOR_STAMP="$(basename "$PRIOR_JSON")"
|
||||
echo "---"
|
||||
echo ""
|
||||
echo "## Diff vs Prior Baseline"
|
||||
echo ""
|
||||
echo "- **Compared against:** \`$PRIOR_STAMP\`"
|
||||
echo ""
|
||||
|
||||
# New findings: ids present now but not before.
|
||||
NEW_FINDINGS="$(jq -n \
|
||||
--slurpfile cur "$JSON_PATH" \
|
||||
--slurpfile old "$PRIOR_JSON" '
|
||||
($old[0].findings // []) as $o |
|
||||
($cur[0].findings // []) as $c |
|
||||
($o | map(.id)) as $oids |
|
||||
[ $c[] | select(.severity!="info") | select(.id as $id | ($oids | index($id)) | not) ]
|
||||
')"
|
||||
# Resolved findings: ids present before but not now.
|
||||
RESOLVED_FINDINGS="$(jq -n \
|
||||
--slurpfile cur "$JSON_PATH" \
|
||||
--slurpfile old "$PRIOR_JSON" '
|
||||
($old[0].findings // []) as $o |
|
||||
($cur[0].findings // []) as $c |
|
||||
($c | map(.id)) as $cids |
|
||||
[ $o[] | select(.severity!="info") | select(.id as $id | ($cids | index($id)) | not) ]
|
||||
')"
|
||||
# Regressed: same id, severity got worse (info<warning<critical; unknown treated as warning-level).
|
||||
REGRESSED="$(jq -n \
|
||||
--slurpfile cur "$JSON_PATH" \
|
||||
--slurpfile old "$PRIOR_JSON" '
|
||||
def rank(s): if s=="critical" then 3 elif s=="warning" then 2 elif s=="unknown" then 2 elif s=="info" then 1 else 0 end;
|
||||
($old[0].findings // []) as $o |
|
||||
($cur[0].findings // []) as $c |
|
||||
($o | map({key:.id, value:.severity}) | from_entries) as $om |
|
||||
[ $c[] | select(.id as $id | $om[$id] != null) | select(rank(.severity) > rank($om[.id])) |
|
||||
{id, title, was: $om[.id], now: .severity} ]
|
||||
')"
|
||||
|
||||
echo "**New findings:**"
|
||||
echo ""
|
||||
if [ "$(echo "$NEW_FINDINGS" | jq 'length')" = "0" ]; then
|
||||
echo "- (none)"
|
||||
else
|
||||
echo "$NEW_FINDINGS" | jq -r '.[] | "- [" + (.severity|ascii_upcase) + "] " + .title'
|
||||
fi
|
||||
echo ""
|
||||
echo "**Resolved findings:**"
|
||||
echo ""
|
||||
if [ "$(echo "$RESOLVED_FINDINGS" | jq 'length')" = "0" ]; then
|
||||
echo "- (none)"
|
||||
else
|
||||
echo "$RESOLVED_FINDINGS" | jq -r '.[] | "- [" + (.severity|ascii_upcase) + "] " + .title'
|
||||
fi
|
||||
echo ""
|
||||
echo "**Regressed findings:**"
|
||||
echo ""
|
||||
if [ "$(echo "$REGRESSED" | jq 'length')" = "0" ]; then
|
||||
echo "- (none)"
|
||||
else
|
||||
echo "$REGRESSED" | jq -r '.[] | "- " + .title + " (" + .was + " -> " + .now + ")"'
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# Installed-software deltas
|
||||
SW_ADDED="$(jq -n \
|
||||
--slurpfile cur "$JSON_PATH" \
|
||||
--slurpfile old "$PRIOR_JSON" '
|
||||
((($old[0].facts.installed_software // []) | map(.name)) | unique) as $o |
|
||||
((($cur[0].facts.installed_software // []) | map(.name)) | unique) as $c |
|
||||
[ $c[] | select(. as $n | ($o | index($n)) | not) ]
|
||||
')"
|
||||
SW_REMOVED="$(jq -n \
|
||||
--slurpfile cur "$JSON_PATH" \
|
||||
--slurpfile old "$PRIOR_JSON" '
|
||||
((($old[0].facts.installed_software // []) | map(.name)) | unique) as $o |
|
||||
((($cur[0].facts.installed_software // []) | map(.name)) | unique) as $c |
|
||||
[ $o[] | select(. as $n | ($c | index($n)) | not) ]
|
||||
')"
|
||||
|
||||
echo "**Software added:**"
|
||||
echo ""
|
||||
if [ "$(echo "$SW_ADDED" | jq 'length')" = "0" ]; then
|
||||
echo "- (none)"
|
||||
else
|
||||
echo "$SW_ADDED" | jq -r '.[] | "- " + .'
|
||||
fi
|
||||
echo ""
|
||||
echo "**Software removed:**"
|
||||
echo ""
|
||||
if [ "$(echo "$SW_REMOVED" | jq 'length')" = "0" ]; then
|
||||
echo "- (none)"
|
||||
else
|
||||
echo "$SW_REMOVED" | jq -r '.[] | "- " + .'
|
||||
fi
|
||||
echo ""
|
||||
else
|
||||
echo "---"
|
||||
echo ""
|
||||
echo "## Diff vs Prior Baseline"
|
||||
echo ""
|
||||
echo "- No prior baseline found for this host. This is the first baseline."
|
||||
echo ""
|
||||
fi
|
||||
|
||||
echo "---"
|
||||
echo ""
|
||||
echo "_Generated by run-onboarding-diagnostic.sh (GuruRMM onboarding diagnostic, Phase 1). Raw snapshot: \`$(basename "$JSON_PATH")\` (immutable)._"
|
||||
} > "$MD_PATH"
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Alerts (soft-fail): one line for RED overall, one per critical finding (capped)
|
||||
# ---------------------------------------------------------------------------
|
||||
if [ "$GRADE" = "RED" ]; then
|
||||
CRIT_TITLES="$(echo "$DIAG_JSON" | jq -r '[.findings[] | select(.severity=="critical") | .title] | .[0:3] | join("; ")')"
|
||||
MORE=""
|
||||
if [ "$N_CRIT" -gt 3 ]; then MORE=" (+$((N_CRIT - 3)) more)"; fi
|
||||
post_alert "[RMM] Onboarding diag $PROBE_HOST ($CLIENT_SLUG) = RED: $N_CRIT critical - ${CRIT_TITLES}${MORE}"
|
||||
elif [ "$GRADE" = "AMBER" ]; then
|
||||
post_alert "[RMM] Onboarding diag $PROBE_HOST ($CLIENT_SLUG) = AMBER: $N_WARN warning, 0 critical"
|
||||
fi
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Final console summary
|
||||
# ---------------------------------------------------------------------------
|
||||
echo ""
|
||||
echo "=========================================================="
|
||||
echo " Onboarding diagnostic complete"
|
||||
echo " Host: $PROBE_HOST"
|
||||
echo " Client: ${AGENT_CLIENT:-$CLIENT_SLUG} ($CLIENT_SLUG)"
|
||||
echo " Grade: $GRADE ($N_CRIT critical / $N_WARN warning / $N_INFO info / $N_UNK unknown)"
|
||||
echo " JSON: $JSON_PATH"
|
||||
echo " Report: $MD_PATH"
|
||||
echo "=========================================================="
|
||||
echo ""
|
||||
echo "Report path: $MD_PATH"
|
||||
@@ -0,0 +1,774 @@
|
||||
{
|
||||
"host": "FRONTDESKRECEPT",
|
||||
"collected_at_utc": "2026-05-29T19:55:43Z",
|
||||
"os": {
|
||||
"caption": "Microsoft Windows 11 Pro",
|
||||
"version": "10.0.26200",
|
||||
"build": "26200",
|
||||
"install_date": "2025-08-07T02:15:17Z",
|
||||
"last_boot_utc": "2026-05-13T00:39:47Z",
|
||||
"architecture": "64-bit"
|
||||
},
|
||||
"facts": {
|
||||
"builtin_admin_enabled": false,
|
||||
"os_eol": {
|
||||
"eol_date": "2027-10-12",
|
||||
"release": "Win11 25H2"
|
||||
},
|
||||
"pending_updates": 2,
|
||||
"pending_reboot": true,
|
||||
"uptime_days": 16.8,
|
||||
"scheduled_tasks": [
|
||||
{
|
||||
"path": "\\",
|
||||
"name": "CorelUpdateHelperTask-34FAD43C54B1AA7B7D45D9CFCA371A7C",
|
||||
"state": "Ready"
|
||||
},
|
||||
{
|
||||
"path": "\\",
|
||||
"name": "CorelUpdateHelperTaskCore",
|
||||
"state": "Ready"
|
||||
},
|
||||
{
|
||||
"path": "\\",
|
||||
"name": "MicrosoftEdgeUpdateTaskMachineCore1d8299e406acf5f",
|
||||
"state": "Ready"
|
||||
},
|
||||
{
|
||||
"path": "\\",
|
||||
"name": "MicrosoftEdgeUpdateTaskMachineUA",
|
||||
"state": "Ready"
|
||||
},
|
||||
{
|
||||
"path": "\\",
|
||||
"name": "OneDrive Per-Machine Standalone Update Task",
|
||||
"state": "Ready"
|
||||
},
|
||||
{
|
||||
"path": "\\",
|
||||
"name": "OneDrive Reporting Task-S-1-5-21-1826020299-2037390372-3224229966-1001",
|
||||
"state": "Ready"
|
||||
},
|
||||
{
|
||||
"path": "\\",
|
||||
"name": "OneDrive Startup Task-S-1-5-21-1826020299-2037390372-3224229966-1001",
|
||||
"state": "Ready"
|
||||
},
|
||||
{
|
||||
"path": "\\GoogleSystem\\GoogleUpdater\\",
|
||||
"name": "GoogleUpdaterTaskSystem149.0.7814.0{A725F2F7-591B-48E3-A0A9-9AAD55F1DAF1}",
|
||||
"state": "Ready"
|
||||
},
|
||||
{
|
||||
"path": "\\SoftLanding\\S-1-5-21-1826020299-2037390372-3224229966-1001\\",
|
||||
"name": "SoftLandingCreativeManagementTask",
|
||||
"state": "Ready"
|
||||
},
|
||||
{
|
||||
"path": "\\SoftLanding\\S-1-5-21-1826020299-2037390372-3224229966-1001\\",
|
||||
"name": "SoftLandingDeferralTask-{0c3db634-1f6a-464d-bbe9-5526a48a6e15}",
|
||||
"state": "Ready"
|
||||
}
|
||||
],
|
||||
"hardware": {
|
||||
"model": "OptiPlex 3080",
|
||||
"manufacturer": "Dell Inc.",
|
||||
"bios_date": "2025-12-01",
|
||||
"cpu_logical": 12,
|
||||
"bios_version": "2.34.0",
|
||||
"cpu_cores": 6,
|
||||
"ram_gb": 15.8,
|
||||
"serial": "DPZK1G3",
|
||||
"cpu": "Intel(R) Core(TM) i5-10505 CPU @ 3.20GHz"
|
||||
},
|
||||
"os_build": "26200",
|
||||
"secure_boot": false,
|
||||
"backup_agents": null,
|
||||
"autoruns_run_keys": [
|
||||
{
|
||||
"key": "HKLM:\\Software\\Microsoft\\Windows\\CurrentVersion\\Run",
|
||||
"name": "SecurityHealth",
|
||||
"value": "C:\\WINDOWS\\system32\\SecurityHealthSystray.exe"
|
||||
},
|
||||
{
|
||||
"key": "HKLM:\\Software\\Microsoft\\Windows\\CurrentVersion\\Run",
|
||||
"name": "RtkAudUService",
|
||||
"value": "\"C:\\WINDOWS\\System32\\DriverStore\\FileRepository\\realtekservice.inf_amd64_a4555e9b35287491\\RtkAudUService64.exe\" -background"
|
||||
},
|
||||
{
|
||||
"key": "HKLM:\\Software\\Microsoft\\Windows\\CurrentVersion\\Run",
|
||||
"name": "WavesSvc",
|
||||
"value": "\"C:\\WINDOWS\\System32\\DriverStore\\FileRepository\\wavesapo9de.inf_amd64_c6bfc5767fc0181c\\WavesSvc64.exe\" -Jack"
|
||||
},
|
||||
{
|
||||
"key": "HKLM:\\Software\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Run",
|
||||
"name": "QuickFinder Scheduler",
|
||||
"value": "\"c:\\Program Files (x86)\\Corel\\WordPerfect Office 2021\\Programs\\QFSCHD210.EXE\""
|
||||
},
|
||||
{
|
||||
"key": "HKLM:\\Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce",
|
||||
"name": "Delete Cached Update Binary",
|
||||
"value": "C:\\WINDOWS\\system32\\cmd.exe /q /c del /q \"C:\\Program Files\\Microsoft OneDrive\\Update\\OneDriveSetup.exe\""
|
||||
},
|
||||
{
|
||||
"key": "HKLM:\\Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce",
|
||||
"name": "Delete Cached Standalone Update Binary",
|
||||
"value": "C:\\WINDOWS\\system32\\cmd.exe /q /c del /q \"C:\\Program Files\\Microsoft OneDrive\\StandaloneUpdater\\OneDriveSetup.exe\""
|
||||
},
|
||||
{
|
||||
"key": "HKLM:\\Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce",
|
||||
"name": "msedge_cleanup_{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}",
|
||||
"value": "\"C:\\Program Files (x86)\\Microsoft\\EdgeWebView\\Application\\148.0.3967.83\\Installer\\setup.exe\" --msedgewebview --delete-old-versions --system-level --verbose-logging --on-logon"
|
||||
}
|
||||
],
|
||||
"physical_disks": [
|
||||
{
|
||||
"health": "Healthy",
|
||||
"model": "KingFast",
|
||||
"media_type": "SSD"
|
||||
}
|
||||
],
|
||||
"local_users": [
|
||||
{
|
||||
"last_logon": "",
|
||||
"name": "Administrator",
|
||||
"password_never_expires": false,
|
||||
"enabled": false
|
||||
},
|
||||
{
|
||||
"last_logon": "",
|
||||
"name": "DefaultAccount",
|
||||
"password_never_expires": false,
|
||||
"enabled": false
|
||||
},
|
||||
{
|
||||
"last_logon": "",
|
||||
"name": "Guest",
|
||||
"password_never_expires": false,
|
||||
"enabled": false
|
||||
},
|
||||
{
|
||||
"last_logon": "2026-05-29",
|
||||
"name": "guru",
|
||||
"password_never_expires": false,
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"last_logon": "",
|
||||
"name": "localadmin",
|
||||
"password_never_expires": false,
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"last_logon": "",
|
||||
"name": "WDAGUtilityAccount",
|
||||
"password_never_expires": false,
|
||||
"enabled": false
|
||||
}
|
||||
],
|
||||
"scheduled_tasks_count": 10,
|
||||
"volumes": [
|
||||
{
|
||||
"drive": "[unlabeled]",
|
||||
"size_gb": 0.1,
|
||||
"free_pct": 35.9,
|
||||
"free_gb": 0
|
||||
},
|
||||
{
|
||||
"drive": "[unlabeled]",
|
||||
"size_gb": 0.8,
|
||||
"free_pct": 14.4,
|
||||
"free_gb": 0.1
|
||||
},
|
||||
{
|
||||
"drive": "[Recovery]",
|
||||
"size_gb": 0.5,
|
||||
"free_pct": 97.4,
|
||||
"free_gb": 0.5
|
||||
},
|
||||
{
|
||||
"drive": "C:",
|
||||
"size_gb": 475.5,
|
||||
"free_pct": 82.8,
|
||||
"free_gb": 394
|
||||
}
|
||||
],
|
||||
"network_adapters": [
|
||||
{
|
||||
"dhcp": true,
|
||||
"description": "Realtek PCIe GbE Family Controller",
|
||||
"gateway": [
|
||||
"192.168.10.1"
|
||||
],
|
||||
"mac": "70:B5:E8:7A:80:7B",
|
||||
"ip": [
|
||||
"192.168.10.115",
|
||||
"fe80::b17c:c1aa:150b:e65b"
|
||||
],
|
||||
"dns": [
|
||||
"192.168.10.1"
|
||||
]
|
||||
}
|
||||
],
|
||||
"failed_autostart_services": [
|
||||
{
|
||||
"name": "GoogleUpdaterInternalService149.0.7814.0",
|
||||
"display": "Google Updater Internal Service (GoogleUpdaterInternalService149.0.7814.0)",
|
||||
"state": "Stopped"
|
||||
},
|
||||
{
|
||||
"name": "GoogleUpdaterService149.0.7814.0",
|
||||
"display": "Google Updater Service (GoogleUpdaterService149.0.7814.0)",
|
||||
"state": "Stopped"
|
||||
},
|
||||
{
|
||||
"name": "Intel(R) TPM Provisioning Service",
|
||||
"display": "Intel(R) TPM Provisioning Service",
|
||||
"state": "Stopped"
|
||||
}
|
||||
],
|
||||
"stability_14d": {
|
||||
"unexpected_shutdowns": 0,
|
||||
"disk_errors": 0,
|
||||
"bugchecks": 0
|
||||
},
|
||||
"exposure": {
|
||||
"smb1_enabled": false,
|
||||
"laps_present": true,
|
||||
"rdp_enabled": false,
|
||||
"uac_enabled": true,
|
||||
"rdp_nla": true
|
||||
},
|
||||
"accounts_password_never_expires": [],
|
||||
"installed_software": [
|
||||
{
|
||||
"publisher": "Microsoft Corporation",
|
||||
"name": "Copilot",
|
||||
"version": "148.0.3967.70"
|
||||
},
|
||||
{
|
||||
"publisher": "Corel corporation",
|
||||
"name": "Corel Update Manager",
|
||||
"version": "2.16.673"
|
||||
},
|
||||
{
|
||||
"publisher": "Google LLC",
|
||||
"name": "Google Chrome",
|
||||
"version": "148.0.7778.216"
|
||||
},
|
||||
{
|
||||
"publisher": "Microsoft Corporation",
|
||||
"name": "Microsoft 365 Apps for business - en-us",
|
||||
"version": "16.0.19929.20172"
|
||||
},
|
||||
{
|
||||
"publisher": "Microsoft Corporation",
|
||||
"name": "Microsoft Command Line Utilities 11 for SQL Server",
|
||||
"version": "11.0.2270.0"
|
||||
},
|
||||
{
|
||||
"publisher": "Microsoft Corporation",
|
||||
"name": "Microsoft Edge",
|
||||
"version": "148.0.3967.83"
|
||||
},
|
||||
{
|
||||
"publisher": "Microsoft Corporation",
|
||||
"name": "Microsoft Edge WebView2 Runtime",
|
||||
"version": "148.0.3967.83"
|
||||
},
|
||||
{
|
||||
"publisher": "Microsoft Corporation",
|
||||
"name": "Microsoft ODBC Driver 11 for SQL Server",
|
||||
"version": "11.0.2270.0"
|
||||
},
|
||||
{
|
||||
"publisher": "Microsoft Corporation",
|
||||
"name": "Microsoft OneDrive",
|
||||
"version": "26.084.0504.0007"
|
||||
},
|
||||
{
|
||||
"publisher": "Microsoft Corporation",
|
||||
"name": "Microsoft Update Health Tools",
|
||||
"version": "5.72.0.0"
|
||||
},
|
||||
{
|
||||
"publisher": "Microsoft Corporation",
|
||||
"name": "Microsoft Visual Basic for Applications 7.1 (x86)",
|
||||
"version": "7.1.00.00"
|
||||
},
|
||||
{
|
||||
"publisher": "Microsoft Corporation",
|
||||
"name": "Microsoft Visual Basic for Applications 7.1 (x86) English",
|
||||
"version": "7.1.0.0"
|
||||
},
|
||||
{
|
||||
"publisher": "Microsoft Corporation",
|
||||
"name": "Microsoft Visual C++ 2005 Redistributable",
|
||||
"version": "8.0.56336"
|
||||
},
|
||||
{
|
||||
"publisher": "Microsoft Corporation",
|
||||
"name": "Microsoft Visual C++ 2005 Redistributable (x64)",
|
||||
"version": "8.0.56336"
|
||||
},
|
||||
{
|
||||
"publisher": "Microsoft Corporation",
|
||||
"name": "Microsoft Visual C++ 2012 Redistributable (x64) - 11.0.50727",
|
||||
"version": "11.0.50727.1"
|
||||
},
|
||||
{
|
||||
"publisher": "Microsoft Corporation",
|
||||
"name": "Microsoft Visual C++ 2012 Redistributable (x86) - 11.0.61030",
|
||||
"version": "11.0.61030.0"
|
||||
},
|
||||
{
|
||||
"publisher": "Microsoft Corporation",
|
||||
"name": "Microsoft Visual C++ 2012 x64 Additional Runtime - 11.0.50727",
|
||||
"version": "11.0.50727"
|
||||
},
|
||||
{
|
||||
"publisher": "Microsoft Corporation",
|
||||
"name": "Microsoft Visual C++ 2012 x64 Minimum Runtime - 11.0.50727",
|
||||
"version": "11.0.50727"
|
||||
},
|
||||
{
|
||||
"publisher": "Microsoft Corporation",
|
||||
"name": "Microsoft Visual C++ 2012 x86 Additional Runtime - 11.0.61030",
|
||||
"version": "11.0.61030"
|
||||
},
|
||||
{
|
||||
"publisher": "Microsoft Corporation",
|
||||
"name": "Microsoft Visual C++ 2012 x86 Minimum Runtime - 11.0.61030",
|
||||
"version": "11.0.61030"
|
||||
},
|
||||
{
|
||||
"publisher": "Microsoft Corporation",
|
||||
"name": "Microsoft Visual C++ 2015-2022 Redistributable (x64) - 14.44.35211",
|
||||
"version": "14.44.35211.0"
|
||||
},
|
||||
{
|
||||
"publisher": "Microsoft Corporation",
|
||||
"name": "Microsoft Visual C++ 2015-2022 Redistributable (x86) - 14.44.35211",
|
||||
"version": "14.44.35211.0"
|
||||
},
|
||||
{
|
||||
"publisher": "Microsoft Corporation",
|
||||
"name": "Microsoft Visual C++ 2022 X64 Additional Runtime - 14.44.35211",
|
||||
"version": "14.44.35211"
|
||||
},
|
||||
{
|
||||
"publisher": "Microsoft Corporation",
|
||||
"name": "Microsoft Visual C++ 2022 X64 Minimum Runtime - 14.44.35211",
|
||||
"version": "14.44.35211"
|
||||
},
|
||||
{
|
||||
"publisher": "Microsoft Corporation",
|
||||
"name": "Microsoft Visual C++ 2022 X86 Additional Runtime - 14.44.35211",
|
||||
"version": "14.44.35211"
|
||||
},
|
||||
{
|
||||
"publisher": "Microsoft Corporation",
|
||||
"name": "Microsoft Visual C++ 2022 X86 Minimum Runtime - 14.44.35211",
|
||||
"version": "14.44.35211"
|
||||
},
|
||||
{
|
||||
"publisher": "Microsoft Corporation",
|
||||
"name": "Microsoft Visual Studio 2010 Tools for Office Runtime (x64)",
|
||||
"version": "10.0.31119"
|
||||
},
|
||||
{
|
||||
"publisher": "Microsoft Corporation",
|
||||
"name": "Microsoft Visual Studio 2010 Tools for Office Runtime (x64)",
|
||||
"version": "10.0.31124"
|
||||
},
|
||||
{
|
||||
"publisher": "Microsoft Corporation",
|
||||
"name": "Office 16 Click-to-Run Extensibility Component",
|
||||
"version": "16.0.19929.20172"
|
||||
},
|
||||
{
|
||||
"publisher": "ScreenConnect Software",
|
||||
"name": "ScreenConnect Client (1912bf3444b41a08)",
|
||||
"version": "26.1.24.9579"
|
||||
},
|
||||
{
|
||||
"publisher": "Splashtop Inc.",
|
||||
"name": "Splashtop Streamer",
|
||||
"version": "3.8.2.0"
|
||||
},
|
||||
{
|
||||
"publisher": "Servably, Inc.",
|
||||
"name": "Syncro",
|
||||
"version": "1.0.201.18410"
|
||||
},
|
||||
{
|
||||
"publisher": "Microsoft Corporation",
|
||||
"name": "Teams Machine-Wide Installer",
|
||||
"version": "1.4.0.32771"
|
||||
},
|
||||
{
|
||||
"publisher": "PCLaw | Time Matters?",
|
||||
"name": "Time Matters?",
|
||||
"version": "21.0.0.123"
|
||||
},
|
||||
{
|
||||
"publisher": "Microsoft Corporation",
|
||||
"name": "Update for Windows 10 for x64-based Systems (KB5001716)",
|
||||
"version": "4.91.0.0"
|
||||
},
|
||||
{
|
||||
"publisher": "Microsoft Corporation",
|
||||
"name": "Windows PC Health Check",
|
||||
"version": "3.6.2204.08001"
|
||||
},
|
||||
{
|
||||
"publisher": "Corel Corporation",
|
||||
"name": "WordPerfect Office 2021",
|
||||
"version": "21.0"
|
||||
},
|
||||
{
|
||||
"publisher": "Corel Corporation",
|
||||
"name": "WordPerfect Office 2021",
|
||||
"version": "21.1.1.194"
|
||||
},
|
||||
{
|
||||
"publisher": "Corel Corporation",
|
||||
"name": "WordPerfect Office 2021 - Common Files",
|
||||
"version": "21.1.1"
|
||||
},
|
||||
{
|
||||
"publisher": "Corel Corporation",
|
||||
"name": "WordPerfect Office 2021 - Common Files English",
|
||||
"version": "21.1"
|
||||
},
|
||||
{
|
||||
"publisher": "Corel Corporation",
|
||||
"name": "WordPerfect Office 2021 - IPM",
|
||||
"version": "21.1"
|
||||
},
|
||||
{
|
||||
"publisher": "Corel Corporation",
|
||||
"name": "WordPerfect Office 2021 - IPM Content",
|
||||
"version": "21.0"
|
||||
},
|
||||
{
|
||||
"publisher": "Corel Corporation",
|
||||
"name": "WordPerfect Office 2021 - IPM Content TBYB ",
|
||||
"version": "21.0"
|
||||
},
|
||||
{
|
||||
"publisher": "Corel Corporation",
|
||||
"name": "WordPerfect Office 2021 - IPM TBYB",
|
||||
"version": "21.1"
|
||||
},
|
||||
{
|
||||
"publisher": "Corel Corporation",
|
||||
"name": "WordPerfect Office 2021 - Lightning Files",
|
||||
"version": "21.0"
|
||||
},
|
||||
{
|
||||
"publisher": "Corel Corporation",
|
||||
"name": "WordPerfect Office 2021 - Lightning Files English",
|
||||
"version": "21.0"
|
||||
},
|
||||
{
|
||||
"publisher": "Corel Corporation",
|
||||
"name": "WordPerfect Office 2021 - Presentations Files",
|
||||
"version": "21.1.1"
|
||||
},
|
||||
{
|
||||
"publisher": "Corel Corporation",
|
||||
"name": "WordPerfect Office 2021 - Presentations Files English",
|
||||
"version": "21.1"
|
||||
},
|
||||
{
|
||||
"publisher": "Corel Corporation",
|
||||
"name": "WordPerfect Office 2021 - Quattro Pro Files",
|
||||
"version": "21.1.1"
|
||||
},
|
||||
{
|
||||
"publisher": "Corel Corporation",
|
||||
"name": "WordPerfect Office 2021 - Quattro Pro Files English",
|
||||
"version": "21.1"
|
||||
},
|
||||
{
|
||||
"publisher": "Corel Corporation",
|
||||
"name": "WordPerfect Office 2021 - Redists",
|
||||
"version": "21.0"
|
||||
},
|
||||
{
|
||||
"publisher": "Corel Corporation",
|
||||
"name": "WordPerfect Office 2021 - Setup Files",
|
||||
"version": "21.1.1"
|
||||
},
|
||||
{
|
||||
"publisher": "Corel Corporation",
|
||||
"name": "WordPerfect Office 2021 - WordPerfect Files",
|
||||
"version": "21.1.1"
|
||||
},
|
||||
{
|
||||
"publisher": "Corel Corporation",
|
||||
"name": "WordPerfect Office 2021 - WordPerfect Files English",
|
||||
"version": "21.1"
|
||||
},
|
||||
{
|
||||
"publisher": "Corel Corporation",
|
||||
"name": "WordPerfect Office 2021 - WPD format Props x64",
|
||||
"version": "21.0"
|
||||
},
|
||||
{
|
||||
"publisher": " Corel Corporation",
|
||||
"name": "WordPerfect Office 2021 - Writing Tools",
|
||||
"version": "21.0"
|
||||
},
|
||||
{
|
||||
"publisher": "Corel Corporation",
|
||||
"name": "WordPerfect Office IFilter 32-bit",
|
||||
"version": "1.8"
|
||||
},
|
||||
{
|
||||
"publisher": "Corel Corporation",
|
||||
"name": "WordPerfect Office IFilter 64-bit",
|
||||
"version": "1.8"
|
||||
}
|
||||
],
|
||||
"tpm": {
|
||||
"enabled": true,
|
||||
"ready": true,
|
||||
"present": true
|
||||
},
|
||||
"local_groups": [
|
||||
"Access Control Assistance Operators",
|
||||
"Administrators",
|
||||
"Backup Operators",
|
||||
"Cryptographic Operators",
|
||||
"Device Owners",
|
||||
"Distributed COM Users",
|
||||
"Event Log Readers",
|
||||
"Guests",
|
||||
"Hyper-V Administrators",
|
||||
"IIS_IUSRS",
|
||||
"Network Configuration Operators",
|
||||
"OpenSSH Users",
|
||||
"Performance Log Users",
|
||||
"Performance Monitor Users",
|
||||
"Power Users",
|
||||
"Remote Desktop Users",
|
||||
"Remote Management Users",
|
||||
"Replicator",
|
||||
"System Managed Accounts Group",
|
||||
"User Mode Hardware Operators",
|
||||
"Users"
|
||||
],
|
||||
"battery": {
|
||||
"present": false
|
||||
},
|
||||
"activation": {
|
||||
"edition": "Microsoft Windows 11 Pro",
|
||||
"description": "Windows(R) Operating System, OEM_DM channel",
|
||||
"licensed": true,
|
||||
"license_status_code": 1
|
||||
},
|
||||
"time_source": "time.windows.com,0x9",
|
||||
"chassis_types": [
|
||||
3
|
||||
],
|
||||
"last_hotfix": {
|
||||
"hotfix_id": "KB5089549",
|
||||
"installed_on": "2026-05-13T07:00:00Z"
|
||||
},
|
||||
"antivirus_products": [
|
||||
"Windows Defender"
|
||||
],
|
||||
"domain_joined": false,
|
||||
"defender": {
|
||||
"antispyware_signature_age": 0,
|
||||
"tamper_protected": true,
|
||||
"real_time_protection": true,
|
||||
"nis_enabled": true,
|
||||
"available": true,
|
||||
"antivirus_enabled": true,
|
||||
"am_service_enabled": true
|
||||
},
|
||||
"bitlocker": {
|
||||
"os_volume": "C:",
|
||||
"key_protectors": [],
|
||||
"recovery_key_present": false,
|
||||
"available": true,
|
||||
"encryption_percent": 0,
|
||||
"protection_status": "Off"
|
||||
},
|
||||
"is_laptop": false,
|
||||
"installed_software_count": 58,
|
||||
"local_administrators": [
|
||||
"FRONTDESKRECEPT\\Administrator",
|
||||
"FRONTDESKRECEPT\\guru",
|
||||
"FRONTDESKRECEPT\\localadmin"
|
||||
],
|
||||
"firewall_profiles": {
|
||||
"Private": true,
|
||||
"Domain": true,
|
||||
"Public": true
|
||||
},
|
||||
"domain": "WORKGROUP",
|
||||
"foreign_agents": [
|
||||
"ScreenConnect / ConnectWise Control",
|
||||
"Splashtop (SOS/Streamer)",
|
||||
"Syncro / Kabuto"
|
||||
]
|
||||
},
|
||||
"findings": [
|
||||
{
|
||||
"id": "sec.defender.ok",
|
||||
"category": "security",
|
||||
"severity": "info",
|
||||
"title": "Defender active and current",
|
||||
"detail": "Real-time protection on, service running, signatures current.",
|
||||
"evidence": "RealTimeProtectionEnabled=True; AMServiceEnabled=True; AntispywareSignatureAge=0 days; IsTamperProtected=True"
|
||||
},
|
||||
{
|
||||
"id": "sec.av_products.defender_only",
|
||||
"category": "security",
|
||||
"severity": "info",
|
||||
"title": "Defender is the only registered AV",
|
||||
"detail": "Only Microsoft/Windows Defender is registered in Security Center.",
|
||||
"evidence": "Windows Defender"
|
||||
},
|
||||
{
|
||||
"id": "sec.foreign_agents.screenconnect_connectwise_control",
|
||||
"category": "security",
|
||||
"severity": "critical",
|
||||
"title": "Foreign management/remote-access agent: ScreenConnect / ConnectWise Control",
|
||||
"detail": "A competitor RMM or unmanaged remote-access tool is present. At onboarding this is a security and control risk (a prior MSP or attacker may retain remote access). Verify it is authorized; if not, remove it.",
|
||||
"evidence": "program: ScreenConnect Client (1912bf3444b41a08) 26.1.24.9579\nservice: ScreenConnect Client (1912bf3444b41a08) (ScreenConnect Client (1912bf3444b41a08)) Running"
|
||||
},
|
||||
{
|
||||
"id": "sec.foreign_agents.splashtop_sos_streamer_",
|
||||
"category": "security",
|
||||
"severity": "critical",
|
||||
"title": "Foreign management/remote-access agent: Splashtop (SOS/Streamer)",
|
||||
"detail": "A competitor RMM or unmanaged remote-access tool is present. At onboarding this is a security and control risk (a prior MSP or attacker may retain remote access). Verify it is authorized; if not, remove it.",
|
||||
"evidence": "program: Splashtop Streamer 3.8.2.0\nservice: SplashtopRemoteService (Splashtop? Remote Service) Running"
|
||||
},
|
||||
{
|
||||
"id": "sec.foreign_agents.syncro_kabuto",
|
||||
"category": "security",
|
||||
"severity": "critical",
|
||||
"title": "Foreign management/remote-access agent: Syncro / Kabuto",
|
||||
"detail": "A competitor RMM or unmanaged remote-access tool is present. At onboarding this is a security and control risk (a prior MSP or attacker may retain remote access). Verify it is authorized; if not, remove it.",
|
||||
"evidence": "program: Syncro 1.0.201.18410\nservice: Syncro (Syncro) Running"
|
||||
},
|
||||
{
|
||||
"id": "sec.firewall.ok",
|
||||
"category": "security",
|
||||
"severity": "info",
|
||||
"title": "All firewall profiles enabled",
|
||||
"detail": "Domain, Private, and Public firewall profiles are all enabled.",
|
||||
"evidence": "Private=True; Domain=True; Public=True"
|
||||
},
|
||||
{
|
||||
"id": "sec.bitlocker.unencrypted",
|
||||
"category": "security",
|
||||
"severity": "warning",
|
||||
"title": "OS volume is NOT encrypted with BitLocker",
|
||||
"detail": "The operating system volume is unencrypted. Data is exposed if the disk is removed or the device is lost. Enable BitLocker and escrow the recovery key.",
|
||||
"evidence": "Volume=C:; ProtectionStatus=Off; EncryptionPercentage=0; KeyProtectors="
|
||||
},
|
||||
{
|
||||
"id": "sec.local_admins.list",
|
||||
"category": "security",
|
||||
"severity": "info",
|
||||
"title": "Local administrators (3)",
|
||||
"detail": "Members of the local Administrators group. Review for unexpected or unknown accounts (especially leftover MSP/vendor accounts from a prior provider).",
|
||||
"evidence": "FRONTDESKRECEPT\\Administrator\nFRONTDESKRECEPT\\guru\nFRONTDESKRECEPT\\localadmin"
|
||||
},
|
||||
{
|
||||
"id": "sec.patch.os_supported",
|
||||
"category": "security",
|
||||
"severity": "info",
|
||||
"title": "OS build supported: Win11 25H2",
|
||||
"detail": "Build 26200 (Win11 25H2) is in support until 2027-10-12.",
|
||||
"evidence": "Microsoft Windows 11 Pro build 26200"
|
||||
},
|
||||
{
|
||||
"id": "sec.patch.pending",
|
||||
"category": "security",
|
||||
"severity": "warning",
|
||||
"title": "2 pending Windows updates",
|
||||
"detail": "Windows Update reports pending (not installed, not hidden) updates. Some may be security updates. Approve/install on the next maintenance window.",
|
||||
"evidence": "Microsoft.Update.Session search IsInstalled=0 and IsHidden=0 -> 2"
|
||||
},
|
||||
{
|
||||
"id": "sec.patch.last_hotfix",
|
||||
"category": "security",
|
||||
"severity": "info",
|
||||
"title": "Last hotfix: KB5089549",
|
||||
"detail": "Most recently installed update (from Get-HotFix; reflects CBS/MSU packages, not all cumulative metadata).",
|
||||
"evidence": "KB5089549 installed 2026-05-13T07:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": "sec.exposure.smb1_off",
|
||||
"category": "security",
|
||||
"severity": "info",
|
||||
"title": "SMBv1 disabled",
|
||||
"detail": "SMBv1 server protocol is disabled.",
|
||||
"evidence": "EnableSMB1Protocol=False"
|
||||
},
|
||||
{
|
||||
"id": "sec.exposure.laps_present",
|
||||
"category": "security",
|
||||
"severity": "info",
|
||||
"title": "LAPS detected",
|
||||
"detail": "A LAPS mechanism is present.",
|
||||
"evidence": "Windows LAPS reg key"
|
||||
},
|
||||
{
|
||||
"id": "health.stability.clean",
|
||||
"category": "health",
|
||||
"severity": "info",
|
||||
"title": "No stability events in the last 14 days",
|
||||
"detail": "No unexpected shutdowns, BSODs, or disk errors logged.",
|
||||
"evidence": "Unexpected shutdowns (id 41)=0; Bugchecks/BSOD (id 1001)=0; Disk errors (id 7/51/153)=0"
|
||||
},
|
||||
{
|
||||
"id": "health.reboot_uptime.pending",
|
||||
"category": "health",
|
||||
"severity": "warning",
|
||||
"title": "Reboot pending",
|
||||
"detail": "A reboot is pending. Pending reboots can block patches and leave the system in a half-updated state. Schedule a restart.",
|
||||
"evidence": "PendingFileRenameOperations"
|
||||
},
|
||||
{
|
||||
"id": "health.failed_services.stopped",
|
||||
"category": "health",
|
||||
"severity": "warning",
|
||||
"title": "3 auto-start service(s) not running",
|
||||
"detail": "These services are set to start automatically but are not running. Some may be benign; review for security agents, backup agents, or AV that should be running.",
|
||||
"evidence": "GoogleUpdaterInternalService149.0.7814.0 (Google Updater Internal Service (GoogleUpdaterInternalService149.0.7814.0)) = Stopped\nGoogleUpdaterService149.0.7814.0 (Google Updater Service (GoogleUpdaterService149.0.7814.0)) = Stopped\nIntel(R) TPM Provisioning Service (Intel(R) TPM Provisioning Service) = Stopped"
|
||||
},
|
||||
{
|
||||
"id": "health.domain.workgroup",
|
||||
"category": "health",
|
||||
"severity": "info",
|
||||
"title": "Not domain-joined (workgroup)",
|
||||
"detail": "This machine is in workgroup/Azure AD only mode (Domain=WORKGROUP). No on-prem AD secure channel applies.",
|
||||
"evidence": "PartOfDomain=False; Domain=WORKGROUP"
|
||||
},
|
||||
{
|
||||
"id": "health.time.source",
|
||||
"category": "health",
|
||||
"severity": "info",
|
||||
"title": "Time service source",
|
||||
"detail": "Current Windows Time service source.",
|
||||
"evidence": "Source=time.windows.com,0x9"
|
||||
},
|
||||
{
|
||||
"id": "health.backup.none",
|
||||
"category": "health",
|
||||
"severity": "info",
|
||||
"title": "No backup agent detected",
|
||||
"detail": "No known backup agent service found. Backup expectation varies by endpoint; confirm whether this machine is supposed to have local/cloud backup and whether server-side or M365 backup covers it.",
|
||||
"evidence": "No matching backup service in Win32_Service"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,240 @@
|
||||
# Onboarding Diagnostic Baseline - FRONTDESKRECEPT
|
||||
|
||||
- **Grade:** RED
|
||||
- **Host:** FRONTDESKRECEPT
|
||||
- **Client:** Rednour Law Offices (`rednour`)
|
||||
- **Collected (UTC):** 2026-05-29T19:55:43Z
|
||||
- **Agent ID:** 04765560-3e8a-46e5-a507-c5f5f4ead6eb
|
||||
- **Command ID:** 94966f79-74ea-4b47-98c5-6e0f33f819fa
|
||||
- **Findings:** 3 critical / 4 warning / 12 info / 0 unknown
|
||||
|
||||
- **OS:** Microsoft Windows 11 Pro (build 26200)
|
||||
|
||||
---
|
||||
|
||||
## CRITICAL (3)
|
||||
|
||||
### Foreign management/remote-access agent: ScreenConnect / ConnectWise Control
|
||||
- **Category:** security
|
||||
- **ID:** `sec.foreign_agents.screenconnect_connectwise_control`
|
||||
- A competitor RMM or unmanaged remote-access tool is present. At onboarding this is a security and control risk (a prior MSP or attacker may retain remote access). Verify it is authorized; if not, remove it.
|
||||
|
||||
```
|
||||
program: ScreenConnect Client (1912bf3444b41a08) 26.1.24.9579
|
||||
service: ScreenConnect Client (1912bf3444b41a08) (ScreenConnect Client (1912bf3444b41a08)) Running
|
||||
```
|
||||
|
||||
### Foreign management/remote-access agent: Splashtop (SOS/Streamer)
|
||||
- **Category:** security
|
||||
- **ID:** `sec.foreign_agents.splashtop_sos_streamer_`
|
||||
- A competitor RMM or unmanaged remote-access tool is present. At onboarding this is a security and control risk (a prior MSP or attacker may retain remote access). Verify it is authorized; if not, remove it.
|
||||
|
||||
```
|
||||
program: Splashtop Streamer 3.8.2.0
|
||||
service: SplashtopRemoteService (Splashtop? Remote Service) Running
|
||||
```
|
||||
|
||||
### Foreign management/remote-access agent: Syncro / Kabuto
|
||||
- **Category:** security
|
||||
- **ID:** `sec.foreign_agents.syncro_kabuto`
|
||||
- A competitor RMM or unmanaged remote-access tool is present. At onboarding this is a security and control risk (a prior MSP or attacker may retain remote access). Verify it is authorized; if not, remove it.
|
||||
|
||||
```
|
||||
program: Syncro 1.0.201.18410
|
||||
service: Syncro (Syncro) Running
|
||||
```
|
||||
|
||||
|
||||
## WARNING (4)
|
||||
|
||||
### OS volume is NOT encrypted with BitLocker
|
||||
- **Category:** security
|
||||
- **ID:** `sec.bitlocker.unencrypted`
|
||||
- The operating system volume is unencrypted. Data is exposed if the disk is removed or the device is lost. Enable BitLocker and escrow the recovery key.
|
||||
|
||||
```
|
||||
Volume=C:; ProtectionStatus=Off; EncryptionPercentage=0; KeyProtectors=
|
||||
```
|
||||
|
||||
### 2 pending Windows updates
|
||||
- **Category:** security
|
||||
- **ID:** `sec.patch.pending`
|
||||
- Windows Update reports pending (not installed, not hidden) updates. Some may be security updates. Approve/install on the next maintenance window.
|
||||
|
||||
```
|
||||
Microsoft.Update.Session search IsInstalled=0 and IsHidden=0 -> 2
|
||||
```
|
||||
|
||||
### Reboot pending
|
||||
- **Category:** health
|
||||
- **ID:** `health.reboot_uptime.pending`
|
||||
- A reboot is pending. Pending reboots can block patches and leave the system in a half-updated state. Schedule a restart.
|
||||
|
||||
```
|
||||
PendingFileRenameOperations
|
||||
```
|
||||
|
||||
### 3 auto-start service(s) not running
|
||||
- **Category:** health
|
||||
- **ID:** `health.failed_services.stopped`
|
||||
- These services are set to start automatically but are not running. Some may be benign; review for security agents, backup agents, or AV that should be running.
|
||||
|
||||
```
|
||||
GoogleUpdaterInternalService149.0.7814.0 (Google Updater Internal Service (GoogleUpdaterInternalService149.0.7814.0)) = Stopped
|
||||
GoogleUpdaterService149.0.7814.0 (Google Updater Service (GoogleUpdaterService149.0.7814.0)) = Stopped
|
||||
Intel(R) TPM Provisioning Service (Intel(R) TPM Provisioning Service) = Stopped
|
||||
```
|
||||
|
||||
|
||||
## INFO (12)
|
||||
|
||||
### Defender active and current
|
||||
- **Category:** security
|
||||
- **ID:** `sec.defender.ok`
|
||||
- Real-time protection on, service running, signatures current.
|
||||
|
||||
```
|
||||
RealTimeProtectionEnabled=True; AMServiceEnabled=True; AntispywareSignatureAge=0 days; IsTamperProtected=True
|
||||
```
|
||||
|
||||
### Defender is the only registered AV
|
||||
- **Category:** security
|
||||
- **ID:** `sec.av_products.defender_only`
|
||||
- Only Microsoft/Windows Defender is registered in Security Center.
|
||||
|
||||
```
|
||||
Windows Defender
|
||||
```
|
||||
|
||||
### All firewall profiles enabled
|
||||
- **Category:** security
|
||||
- **ID:** `sec.firewall.ok`
|
||||
- Domain, Private, and Public firewall profiles are all enabled.
|
||||
|
||||
```
|
||||
Private=True; Domain=True; Public=True
|
||||
```
|
||||
|
||||
### Local administrators (3)
|
||||
- **Category:** security
|
||||
- **ID:** `sec.local_admins.list`
|
||||
- Members of the local Administrators group. Review for unexpected or unknown accounts (especially leftover MSP/vendor accounts from a prior provider).
|
||||
|
||||
```
|
||||
FRONTDESKRECEPT\Administrator
|
||||
FRONTDESKRECEPT\guru
|
||||
FRONTDESKRECEPT\localadmin
|
||||
```
|
||||
|
||||
### OS build supported: Win11 25H2
|
||||
- **Category:** security
|
||||
- **ID:** `sec.patch.os_supported`
|
||||
- Build 26200 (Win11 25H2) is in support until 2027-10-12.
|
||||
|
||||
```
|
||||
Microsoft Windows 11 Pro build 26200
|
||||
```
|
||||
|
||||
### Last hotfix: KB5089549
|
||||
- **Category:** security
|
||||
- **ID:** `sec.patch.last_hotfix`
|
||||
- Most recently installed update (from Get-HotFix; reflects CBS/MSU packages, not all cumulative metadata).
|
||||
|
||||
```
|
||||
KB5089549 installed 2026-05-13T07:00:00Z
|
||||
```
|
||||
|
||||
### SMBv1 disabled
|
||||
- **Category:** security
|
||||
- **ID:** `sec.exposure.smb1_off`
|
||||
- SMBv1 server protocol is disabled.
|
||||
|
||||
```
|
||||
EnableSMB1Protocol=False
|
||||
```
|
||||
|
||||
### LAPS detected
|
||||
- **Category:** security
|
||||
- **ID:** `sec.exposure.laps_present`
|
||||
- A LAPS mechanism is present.
|
||||
|
||||
```
|
||||
Windows LAPS reg key
|
||||
```
|
||||
|
||||
### No stability events in the last 14 days
|
||||
- **Category:** health
|
||||
- **ID:** `health.stability.clean`
|
||||
- No unexpected shutdowns, BSODs, or disk errors logged.
|
||||
|
||||
```
|
||||
Unexpected shutdowns (id 41)=0; Bugchecks/BSOD (id 1001)=0; Disk errors (id 7/51/153)=0
|
||||
```
|
||||
|
||||
### Not domain-joined (workgroup)
|
||||
- **Category:** health
|
||||
- **ID:** `health.domain.workgroup`
|
||||
- This machine is in workgroup/Azure AD only mode (Domain=WORKGROUP). No on-prem AD secure channel applies.
|
||||
|
||||
```
|
||||
PartOfDomain=False; Domain=WORKGROUP
|
||||
```
|
||||
|
||||
### Time service source
|
||||
- **Category:** health
|
||||
- **ID:** `health.time.source`
|
||||
- Current Windows Time service source.
|
||||
|
||||
```
|
||||
Source=time.windows.com,0x9
|
||||
```
|
||||
|
||||
### No backup agent detected
|
||||
- **Category:** health
|
||||
- **ID:** `health.backup.none`
|
||||
- No known backup agent service found. Backup expectation varies by endpoint; confirm whether this machine is supposed to have local/cloud backup and whether server-side or M365 backup covers it.
|
||||
|
||||
```
|
||||
No matching backup service in Win32_Service
|
||||
```
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Inventory Baseline Summary
|
||||
|
||||
- **Manufacturer / Model:** Dell Inc. / OptiPlex 3080
|
||||
- **Serial:** DPZK1G3
|
||||
- **CPU:** Intel(R) Core(TM) i5-10505 CPU @ 3.20GHz (6 cores / 12 logical)
|
||||
- **RAM (GB):** 15.8
|
||||
- **BIOS:** 2.34.0 (2025-12-01)
|
||||
- **Chassis is laptop:** false
|
||||
- **TPM present / Secure Boot:** true / ?
|
||||
- **Domain joined:** false (WORKGROUP)
|
||||
- **OS activation licensed:** true
|
||||
- **Uptime (days):** 16.8
|
||||
- **Pending reboot:** true
|
||||
- **Installed software count:** 58
|
||||
- **Scheduled tasks (non-MS, enabled):** 10
|
||||
- **Local administrators:** FRONTDESKRECEPT\Administrator, FRONTDESKRECEPT\guru, FRONTDESKRECEPT\localadmin
|
||||
|
||||
### Fixed volumes
|
||||
|
||||
- [unlabeled] - 0 GB free of 0.1 GB (35.9%)
|
||||
- [unlabeled] - 0.1 GB free of 0.8 GB (14.4%)
|
||||
- [Recovery] - 0.5 GB free of 0.5 GB (97.4%)
|
||||
- C: - 394 GB free of 475.5 GB (82.8%)
|
||||
|
||||
### Network adapters
|
||||
|
||||
- Realtek PCIe GbE Family Controller - IP: 192.168.10.115, fe80::b17c:c1aa:150b:e65b - DNS: 192.168.10.1 - DHCP: true
|
||||
|
||||
---
|
||||
|
||||
## Diff vs Prior Baseline
|
||||
|
||||
- No prior baseline found for this host. This is the first baseline.
|
||||
|
||||
---
|
||||
|
||||
_Generated by run-onboarding-diagnostic.sh (GuruRMM onboarding diagnostic, Phase 1). Raw snapshot: `FRONTDESKRECEPT-20260529T195614.json` (immutable)._
|
||||
@@ -0,0 +1,833 @@
|
||||
{
|
||||
"host": "LEGALASST",
|
||||
"collected_at_utc": "2026-05-29T20:05:50Z",
|
||||
"os": {
|
||||
"caption": "Microsoft Windows 10 Pro",
|
||||
"version": "10.0.19045",
|
||||
"build": "19045",
|
||||
"install_date": "2020-10-14T20:37:24Z",
|
||||
"last_boot_utc": "2026-04-16T17:07:07Z",
|
||||
"architecture": "64-bit"
|
||||
},
|
||||
"facts": {
|
||||
"builtin_admin_enabled": false,
|
||||
"os_eol": {
|
||||
"eol_date": "2025-10-14",
|
||||
"release": "Win10 22H2"
|
||||
},
|
||||
"pending_updates": 1,
|
||||
"pending_reboot": true,
|
||||
"uptime_days": 43.1,
|
||||
"scheduled_tasks": [
|
||||
{
|
||||
"path": "\\",
|
||||
"name": "Adobe Acrobat Update Task",
|
||||
"state": "Ready"
|
||||
},
|
||||
{
|
||||
"path": "\\",
|
||||
"name": "Launch Adobe CCXProcess",
|
||||
"state": "Ready"
|
||||
},
|
||||
{
|
||||
"path": "\\",
|
||||
"name": "MicrosoftEdgeUpdateTaskMachineCore",
|
||||
"state": "Ready"
|
||||
},
|
||||
{
|
||||
"path": "\\",
|
||||
"name": "MicrosoftEdgeUpdateTaskMachineUA",
|
||||
"state": "Ready"
|
||||
},
|
||||
{
|
||||
"path": "\\",
|
||||
"name": "OneDrive Per-Machine Standalone Update Task",
|
||||
"state": "Ready"
|
||||
},
|
||||
{
|
||||
"path": "\\",
|
||||
"name": "OneDrive Reporting Task-S-1-5-21-1572446079-3930123124-3343558679-1001",
|
||||
"state": "Ready"
|
||||
},
|
||||
{
|
||||
"path": "\\",
|
||||
"name": "OneDrive Reporting Task-S-1-5-21-1572446079-3930123124-3343558679-1002",
|
||||
"state": "Ready"
|
||||
},
|
||||
{
|
||||
"path": "\\",
|
||||
"name": "OneDrive Reporting Task-S-1-5-21-1572446079-3930123124-3343558679-1009",
|
||||
"state": "Ready"
|
||||
},
|
||||
{
|
||||
"path": "\\",
|
||||
"name": "OneDrive Startup Task-S-1-5-21-1572446079-3930123124-3343558679-1001",
|
||||
"state": "Ready"
|
||||
},
|
||||
{
|
||||
"path": "\\",
|
||||
"name": "OneDrive Startup Task-S-1-5-21-1572446079-3930123124-3343558679-1002",
|
||||
"state": "Ready"
|
||||
},
|
||||
{
|
||||
"path": "\\",
|
||||
"name": "OneDrive Startup Task-S-1-5-21-1572446079-3930123124-3343558679-1009",
|
||||
"state": "Ready"
|
||||
},
|
||||
{
|
||||
"path": "\\",
|
||||
"name": "TM_Scheduled_Backup_Task",
|
||||
"state": "Ready"
|
||||
},
|
||||
{
|
||||
"path": "\\GoogleSystem\\GoogleUpdater\\",
|
||||
"name": "GoogleUpdaterTaskSystem149.0.7814.0{3238CEEE-C349-45C0-BB24-92859BBE402D}",
|
||||
"state": "Ready"
|
||||
}
|
||||
],
|
||||
"hardware": {
|
||||
"model": "To Be Filled By O.E.M.",
|
||||
"manufacturer": "To Be Filled By O.E.M.",
|
||||
"bios_date": "2019-05-15",
|
||||
"cpu_logical": 4,
|
||||
"bios_version": "P3.50",
|
||||
"cpu_cores": 4,
|
||||
"ram_gb": 5.9,
|
||||
"serial": "To Be Filled By O.E.M.",
|
||||
"cpu": "AMD Ryzen 3 3200G with Radeon Vega Graphics "
|
||||
},
|
||||
"os_build": "19045",
|
||||
"secure_boot": false,
|
||||
"backup_agents": null,
|
||||
"autoruns_run_keys": [
|
||||
{
|
||||
"key": "HKLM:\\Software\\Microsoft\\Windows\\CurrentVersion\\Run",
|
||||
"name": "SecurityHealth",
|
||||
"value": "C:\\Windows\\system32\\SecurityHealthSystray.exe"
|
||||
},
|
||||
{
|
||||
"key": "HKLM:\\Software\\Microsoft\\Windows\\CurrentVersion\\Run",
|
||||
"name": "Logitech Download Assistant",
|
||||
"value": "C:\\Windows\\system32\\rundll32.exe C:\\Windows\\System32\\LogiLDA.dll,LogiFetch"
|
||||
},
|
||||
{
|
||||
"key": "HKLM:\\Software\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Run",
|
||||
"name": "QuickFinder Scheduler",
|
||||
"value": "\"c:\\Program Files (x86)\\Corel\\WordPerfect Office X6\\Programs\\QFSCHD160.EXE\""
|
||||
},
|
||||
{
|
||||
"key": "HKLM:\\Software\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Run",
|
||||
"name": "SunJavaUpdateSched",
|
||||
"value": "\"C:\\Program Files (x86)\\Common Files\\Java\\Java Update\\jusched.exe\""
|
||||
},
|
||||
{
|
||||
"key": "HKLM:\\Software\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Run",
|
||||
"name": "Adobe CCXProcess",
|
||||
"value": "C:\\Program Files (x86)\\Adobe\\Adobe Creative Cloud Experience\\CCXProcess.exe"
|
||||
},
|
||||
{
|
||||
"key": "HKLM:\\Software\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Run",
|
||||
"name": "Adobe Creative Cloud",
|
||||
"value": "\"C:\\Program Files\\Adobe\\Adobe Creative Cloud\\ACC\\Creative Cloud.exe\" --showwindow=false --onOSstartup=true"
|
||||
},
|
||||
{
|
||||
"key": "HKLM:\\Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce",
|
||||
"name": "Delete Cached Update Binary",
|
||||
"value": "C:\\Windows\\system32\\cmd.exe /q /c del /q \"C:\\Program Files\\Microsoft OneDrive\\Update\\OneDriveSetup.exe\""
|
||||
},
|
||||
{
|
||||
"key": "HKLM:\\Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce",
|
||||
"name": "Delete Cached Standalone Update Binary",
|
||||
"value": "C:\\Windows\\system32\\cmd.exe /q /c del /q \"C:\\Program Files\\Microsoft OneDrive\\StandaloneUpdater\\OneDriveSetup.exe\""
|
||||
},
|
||||
{
|
||||
"key": "HKLM:\\Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce",
|
||||
"name": "msedge_cleanup_{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}",
|
||||
"value": "\"C:\\Program Files (x86)\\Microsoft\\EdgeWebView\\Application\\148.0.3967.83\\Installer\\setup.exe\" --msedgewebview --delete-old-versions --system-level --verbose-logging --on-logon"
|
||||
}
|
||||
],
|
||||
"local_users": [
|
||||
{
|
||||
"last_logon": "",
|
||||
"name": "Administrator",
|
||||
"password_never_expires": false,
|
||||
"enabled": false
|
||||
},
|
||||
{
|
||||
"last_logon": "2022-05-17",
|
||||
"name": "Ale",
|
||||
"password_never_expires": false,
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"last_logon": "",
|
||||
"name": "DefaultAccount",
|
||||
"password_never_expires": false,
|
||||
"enabled": false
|
||||
},
|
||||
{
|
||||
"last_logon": "2026-05-29",
|
||||
"name": "Emma",
|
||||
"password_never_expires": false,
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"last_logon": "",
|
||||
"name": "Guest",
|
||||
"password_never_expires": false,
|
||||
"enabled": false
|
||||
},
|
||||
{
|
||||
"last_logon": "2020-10-14",
|
||||
"name": "localadmin",
|
||||
"password_never_expires": false,
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"last_logon": "",
|
||||
"name": "WDAGUtilityAccount",
|
||||
"password_never_expires": false,
|
||||
"enabled": false
|
||||
}
|
||||
],
|
||||
"scheduled_tasks_count": 13,
|
||||
"volumes": {
|
||||
"drive": "C:",
|
||||
"size_gb": 465.1,
|
||||
"free_pct": 75.2,
|
||||
"free_gb": 349.6
|
||||
},
|
||||
"network_adapters": [
|
||||
{
|
||||
"dhcp": true,
|
||||
"description": "Realtek PCIe GbE Family Controller",
|
||||
"gateway": [
|
||||
"192.168.10.1"
|
||||
],
|
||||
"mac": "70:85:C2:CD:6D:65",
|
||||
"ip": [
|
||||
"192.168.10.213"
|
||||
],
|
||||
"dns": [
|
||||
"192.168.10.1"
|
||||
]
|
||||
}
|
||||
],
|
||||
"failed_autostart_services": [
|
||||
{
|
||||
"name": "WMPNetworkSvc",
|
||||
"display": "Windows Media Player Network Sharing Service",
|
||||
"state": "Stopped"
|
||||
},
|
||||
{
|
||||
"name": "GoogleUpdaterInternalService149.0.7814.0",
|
||||
"display": "Google Updater Internal Service (GoogleUpdaterInternalService149.0.7814.0)",
|
||||
"state": "Stopped"
|
||||
},
|
||||
{
|
||||
"name": "GoogleUpdaterService149.0.7814.0",
|
||||
"display": "Google Updater Service (GoogleUpdaterService149.0.7814.0)",
|
||||
"state": "Stopped"
|
||||
}
|
||||
],
|
||||
"stability_14d": {
|
||||
"unexpected_shutdowns": 0,
|
||||
"disk_errors": 1,
|
||||
"bugchecks": 0
|
||||
},
|
||||
"exposure": {
|
||||
"smb1_enabled": false,
|
||||
"laps_present": true,
|
||||
"rdp_enabled": false,
|
||||
"uac_enabled": true,
|
||||
"rdp_nla": true
|
||||
},
|
||||
"accounts_password_never_expires": [],
|
||||
"installed_software": [
|
||||
{
|
||||
"publisher": "Adobe",
|
||||
"name": "Adobe Acrobat (64-bit)",
|
||||
"version": "26.001.21483"
|
||||
},
|
||||
{
|
||||
"publisher": "Adobe Inc.",
|
||||
"name": "Adobe Creative Cloud",
|
||||
"version": "6.9.1.1"
|
||||
},
|
||||
{
|
||||
"publisher": "Adobe Systems Incorporated",
|
||||
"name": "Adobe Refresh Manager",
|
||||
"version": "1.8.0"
|
||||
},
|
||||
{
|
||||
"publisher": "Microsoft Corporation",
|
||||
"name": "Copilot",
|
||||
"version": "148.0.3967.96"
|
||||
},
|
||||
{
|
||||
"publisher": "Corel Corporation",
|
||||
"name": "Corel Compatibility Pack",
|
||||
"version": "12.4518.1018"
|
||||
},
|
||||
{
|
||||
"publisher": "Eclipse Adoptium",
|
||||
"name": "Eclipse Temurin JDK with Hotspot 17.0.2+8 (x64)",
|
||||
"version": "17.0.2.8"
|
||||
},
|
||||
{
|
||||
"publisher": "Google LLC",
|
||||
"name": "Google Chrome",
|
||||
"version": "148.0.7778.179"
|
||||
},
|
||||
{
|
||||
"publisher": "Oracle Corporation",
|
||||
"name": "Java 8 Update 341 (64-bit)",
|
||||
"version": "8.0.3410.10"
|
||||
},
|
||||
{
|
||||
"publisher": "Oracle Corporation",
|
||||
"name": "Java Auto Updater",
|
||||
"version": "2.8.341.10"
|
||||
},
|
||||
{
|
||||
"publisher": "Microsoft Corporation",
|
||||
"name": "Microsoft 365 Apps for business - en-us",
|
||||
"version": "16.0.19929.20106"
|
||||
},
|
||||
{
|
||||
"publisher": "Microsoft Corporation",
|
||||
"name": "Microsoft Command Line Utilities 11 for SQL Server",
|
||||
"version": "11.0.2270.0"
|
||||
},
|
||||
{
|
||||
"publisher": "Microsoft Corporation",
|
||||
"name": "Microsoft Edge",
|
||||
"version": "148.0.3967.83"
|
||||
},
|
||||
{
|
||||
"publisher": "Microsoft Corporation",
|
||||
"name": "Microsoft Edge WebView2 Runtime",
|
||||
"version": "148.0.3967.83"
|
||||
},
|
||||
{
|
||||
"publisher": "Microsoft Corporation",
|
||||
"name": "Microsoft ODBC Driver 11 for SQL Server",
|
||||
"version": "11.0.2270.0"
|
||||
},
|
||||
{
|
||||
"publisher": "Microsoft Corporation",
|
||||
"name": "Microsoft OneDrive",
|
||||
"version": "26.078.0426.0002"
|
||||
},
|
||||
{
|
||||
"publisher": "Microsoft Corporation",
|
||||
"name": "Microsoft Update Health Tools",
|
||||
"version": "3.74.0.0"
|
||||
},
|
||||
{
|
||||
"publisher": "Microsoft Corporation",
|
||||
"name": "Microsoft Visual C++ 2005 Redistributable",
|
||||
"version": "8.0.56336"
|
||||
},
|
||||
{
|
||||
"publisher": "Microsoft Corporation",
|
||||
"name": "Microsoft Visual C++ 2005 Redistributable (x64)",
|
||||
"version": "8.0.56336"
|
||||
},
|
||||
{
|
||||
"publisher": "Microsoft Corporation",
|
||||
"name": "Microsoft Visual C++ 2012 Redistributable (x64) - 11.0.50727",
|
||||
"version": "11.0.50727.1"
|
||||
},
|
||||
{
|
||||
"publisher": "Microsoft Corporation",
|
||||
"name": "Microsoft Visual C++ 2012 Redistributable (x86) - 11.0.61030",
|
||||
"version": "11.0.61030.0"
|
||||
},
|
||||
{
|
||||
"publisher": "Microsoft Corporation",
|
||||
"name": "Microsoft Visual C++ 2012 x64 Additional Runtime - 11.0.50727",
|
||||
"version": "11.0.50727"
|
||||
},
|
||||
{
|
||||
"publisher": "Microsoft Corporation",
|
||||
"name": "Microsoft Visual C++ 2012 x64 Minimum Runtime - 11.0.50727",
|
||||
"version": "11.0.50727"
|
||||
},
|
||||
{
|
||||
"publisher": "Microsoft Corporation",
|
||||
"name": "Microsoft Visual C++ 2012 x86 Additional Runtime - 11.0.61030",
|
||||
"version": "11.0.61030"
|
||||
},
|
||||
{
|
||||
"publisher": "Microsoft Corporation",
|
||||
"name": "Microsoft Visual C++ 2012 x86 Minimum Runtime - 11.0.61030",
|
||||
"version": "11.0.61030"
|
||||
},
|
||||
{
|
||||
"publisher": "Microsoft Corporation",
|
||||
"name": "Microsoft Visual C++ 2013 Redistributable (x64) - 12.0.30501",
|
||||
"version": "12.0.30501.0"
|
||||
},
|
||||
{
|
||||
"publisher": "Microsoft Corporation",
|
||||
"name": "Microsoft Visual C++ 2013 x64 Additional Runtime - 12.0.21005",
|
||||
"version": "12.0.21005"
|
||||
},
|
||||
{
|
||||
"publisher": "Microsoft Corporation",
|
||||
"name": "Microsoft Visual C++ 2013 x64 Minimum Runtime - 12.0.21005",
|
||||
"version": "12.0.21005"
|
||||
},
|
||||
{
|
||||
"publisher": "Microsoft Corporation",
|
||||
"name": "Microsoft Visual C++ 2015-2022 Redistributable (x64) - 14.44.35211",
|
||||
"version": "14.44.35211.0"
|
||||
},
|
||||
{
|
||||
"publisher": "Microsoft Corporation",
|
||||
"name": "Microsoft Visual C++ 2015-2022 Redistributable (x86) - 14.44.35211",
|
||||
"version": "14.44.35211.0"
|
||||
},
|
||||
{
|
||||
"publisher": "Microsoft Corporation",
|
||||
"name": "Microsoft Visual C++ 2022 X64 Additional Runtime - 14.44.35211",
|
||||
"version": "14.44.35211"
|
||||
},
|
||||
{
|
||||
"publisher": "Microsoft Corporation",
|
||||
"name": "Microsoft Visual C++ 2022 X64 Minimum Runtime - 14.44.35211",
|
||||
"version": "14.44.35211"
|
||||
},
|
||||
{
|
||||
"publisher": "Microsoft Corporation",
|
||||
"name": "Microsoft Visual C++ 2022 X86 Additional Runtime - 14.44.35211",
|
||||
"version": "14.44.35211"
|
||||
},
|
||||
{
|
||||
"publisher": "Microsoft Corporation",
|
||||
"name": "Microsoft Visual C++ 2022 X86 Minimum Runtime - 14.44.35211",
|
||||
"version": "14.44.35211"
|
||||
},
|
||||
{
|
||||
"publisher": "Microsoft Corporation",
|
||||
"name": "Microsoft Visual Studio 2010 Tools for Office Runtime (x64)",
|
||||
"version": "10.0.31119"
|
||||
},
|
||||
{
|
||||
"publisher": "Microsoft Corporation",
|
||||
"name": "Microsoft Visual Studio 2010 Tools for Office Runtime (x64)",
|
||||
"version": "10.0.31124"
|
||||
},
|
||||
{
|
||||
"publisher": "Microsoft Corporation",
|
||||
"name": "Office 15 Click-to-Run Extensibility Component",
|
||||
"version": "15.0.5603.1000"
|
||||
},
|
||||
{
|
||||
"publisher": "Microsoft Corporation",
|
||||
"name": "Office 15 Click-to-Run Licensing Component",
|
||||
"version": "15.0.5603.1000"
|
||||
},
|
||||
{
|
||||
"publisher": "Microsoft Corporation",
|
||||
"name": "Office 15 Click-to-Run Localization Component",
|
||||
"version": "15.0.5603.1000"
|
||||
},
|
||||
{
|
||||
"publisher": "Microsoft Corporation",
|
||||
"name": "Office 16 Click-to-Run Extensibility Component",
|
||||
"version": "16.0.19929.20106"
|
||||
},
|
||||
{
|
||||
"publisher": "ScreenConnect Software",
|
||||
"name": "ScreenConnect Client (1912bf3444b41a08)",
|
||||
"version": "26.1.24.9579"
|
||||
},
|
||||
{
|
||||
"publisher": "Splashtop Inc.",
|
||||
"name": "Splashtop Streamer",
|
||||
"version": "3.8.2.0"
|
||||
},
|
||||
{
|
||||
"publisher": "Stamps.com, Inc.",
|
||||
"name": "Stamps.com",
|
||||
"version": "20.0.1.5122"
|
||||
},
|
||||
{
|
||||
"publisher": "Stamps.com, Inc.",
|
||||
"name": "Stamps.com Classic",
|
||||
"version": "20.8.0.10190"
|
||||
},
|
||||
{
|
||||
"publisher": "Servably, Inc.",
|
||||
"name": "Syncro",
|
||||
"version": "1.0.201.18410"
|
||||
},
|
||||
{
|
||||
"publisher": "PCLaw | Time Matters?",
|
||||
"name": "Time Matters?",
|
||||
"version": "21.0.0.123"
|
||||
},
|
||||
{
|
||||
"publisher": "Tweaking.com",
|
||||
"name": "Tweaking.com - Windows Repair",
|
||||
"version": "4.14.0"
|
||||
},
|
||||
{
|
||||
"publisher": "Microsoft Corporation",
|
||||
"name": "Update for x64-based Windows Systems (KB5001716)",
|
||||
"version": "8.94.0.0"
|
||||
},
|
||||
{
|
||||
"publisher": "Microsoft Corporation",
|
||||
"name": "Windows PC Health Check",
|
||||
"version": "3.6.2204.08001"
|
||||
},
|
||||
{
|
||||
"publisher": "Microsoft Corporation",
|
||||
"name": "Windows PC Health Check",
|
||||
"version": "4.0.2410.23001"
|
||||
},
|
||||
{
|
||||
"publisher": "Corel Corporation",
|
||||
"name": "WordPerfect Office IFilter 32-bit",
|
||||
"version": "1.4"
|
||||
},
|
||||
{
|
||||
"publisher": "Corel Corporation",
|
||||
"name": "WordPerfect Office IFilter 64-bit",
|
||||
"version": "1.4"
|
||||
},
|
||||
{
|
||||
"publisher": "Corel Corporation",
|
||||
"name": "WordPerfect Office X6",
|
||||
"version": "16.0.0.429"
|
||||
},
|
||||
{
|
||||
"publisher": "Corel Corporation",
|
||||
"name": "WordPerfect Office X6",
|
||||
"version": "16.3"
|
||||
},
|
||||
{
|
||||
"publisher": "Corel Corporation",
|
||||
"name": "WordPerfect Office X6 - Common Files",
|
||||
"version": "16.3"
|
||||
},
|
||||
{
|
||||
"publisher": "Corel Corporation",
|
||||
"name": "WordPerfect Office X6 - Common Files English",
|
||||
"version": "16.3.1"
|
||||
},
|
||||
{
|
||||
"publisher": "Corel Corporation",
|
||||
"name": "WordPerfect Office X6 - IPM",
|
||||
"version": "16.3"
|
||||
},
|
||||
{
|
||||
"publisher": "Corel Corporation",
|
||||
"name": "WordPerfect Office X6 - Lightning Files",
|
||||
"version": "16.3"
|
||||
},
|
||||
{
|
||||
"publisher": "Corel Corporation",
|
||||
"name": "WordPerfect Office X6 - Lightning Files English",
|
||||
"version": "16.3"
|
||||
},
|
||||
{
|
||||
"publisher": "Corel Corporation",
|
||||
"name": "WordPerfect Office X6 - Oxford",
|
||||
"version": "16.3"
|
||||
},
|
||||
{
|
||||
"publisher": "Corel Corporation",
|
||||
"name": "WordPerfect Office X6 - Presentations Files",
|
||||
"version": "16.3"
|
||||
},
|
||||
{
|
||||
"publisher": "Corel Corporation",
|
||||
"name": "WordPerfect Office X6 - Presentations Files English",
|
||||
"version": "16.3"
|
||||
},
|
||||
{
|
||||
"publisher": "Corel Corporation",
|
||||
"name": "WordPerfect Office X6 - Quattro Pro Files",
|
||||
"version": "16.3"
|
||||
},
|
||||
{
|
||||
"publisher": "Corel Corporation",
|
||||
"name": "WordPerfect Office X6 - Quattro Pro Files English",
|
||||
"version": "16.3"
|
||||
},
|
||||
{
|
||||
"publisher": "Corel Corporation",
|
||||
"name": "WordPerfect Office X6 - Setup Files",
|
||||
"version": "16.3.1"
|
||||
},
|
||||
{
|
||||
"publisher": "Corel Corporation",
|
||||
"name": "WordPerfect Office X6 - System Files",
|
||||
"version": "16.1"
|
||||
},
|
||||
{
|
||||
"publisher": "Corel Corporation",
|
||||
"name": "WordPerfect Office X6 - WordPerfect Files",
|
||||
"version": "16.3"
|
||||
},
|
||||
{
|
||||
"publisher": "Corel Corporation",
|
||||
"name": "WordPerfect Office X6 - WordPerfect Files English",
|
||||
"version": "16.3"
|
||||
},
|
||||
{
|
||||
"publisher": " Corel Corporation",
|
||||
"name": "WordPerfect Office X6 - WT",
|
||||
"version": "16.1"
|
||||
}
|
||||
],
|
||||
"tpm": {
|
||||
"enabled": false,
|
||||
"ready": false,
|
||||
"present": false
|
||||
},
|
||||
"local_groups": [
|
||||
"Access Control Assistance Operators",
|
||||
"Administrators",
|
||||
"Backup Operators",
|
||||
"Cryptographic Operators",
|
||||
"Device Owners",
|
||||
"Distributed COM Users",
|
||||
"Event Log Readers",
|
||||
"Guests",
|
||||
"Hyper-V Administrators",
|
||||
"IIS_IUSRS",
|
||||
"Network Configuration Operators",
|
||||
"Performance Log Users",
|
||||
"Performance Monitor Users",
|
||||
"Power Users",
|
||||
"Remote Desktop Users",
|
||||
"Remote Management Users",
|
||||
"Replicator",
|
||||
"System Managed Accounts Group",
|
||||
"Users"
|
||||
],
|
||||
"battery": {
|
||||
"present": false
|
||||
},
|
||||
"activation": {
|
||||
"edition": "Microsoft Windows 10 Pro",
|
||||
"description": "Windows(R) Operating System, RETAIL channel",
|
||||
"licensed": false,
|
||||
"license_status_code": 5
|
||||
},
|
||||
"time_source": "time.windows.com,0x9",
|
||||
"chassis_types": [
|
||||
3
|
||||
],
|
||||
"last_hotfix": {
|
||||
"hotfix_id": "KB5075039",
|
||||
"installed_on": "2026-03-04T07:00:00Z"
|
||||
},
|
||||
"antivirus_products": [
|
||||
"Windows Defender"
|
||||
],
|
||||
"domain_joined": false,
|
||||
"defender": {
|
||||
"antispyware_signature_age": 0,
|
||||
"tamper_protected": true,
|
||||
"real_time_protection": true,
|
||||
"nis_enabled": true,
|
||||
"available": true,
|
||||
"antivirus_enabled": true,
|
||||
"am_service_enabled": true
|
||||
},
|
||||
"bitlocker": {
|
||||
"available": false,
|
||||
"os_volume": "C:"
|
||||
},
|
||||
"is_laptop": false,
|
||||
"installed_software_count": 68,
|
||||
"local_administrators": [
|
||||
"LEGALASST\\Administrator",
|
||||
"LEGALASST\\Ale",
|
||||
"LEGALASST\\Emma",
|
||||
"LEGALASST\\localadmin"
|
||||
],
|
||||
"domain": "WORKGROUP",
|
||||
"foreign_agents": [
|
||||
"ScreenConnect / ConnectWise Control",
|
||||
"Splashtop (SOS/Streamer)",
|
||||
"Syncro / Kabuto"
|
||||
]
|
||||
},
|
||||
"findings": [
|
||||
{
|
||||
"id": "sec.defender.ok",
|
||||
"category": "security",
|
||||
"severity": "info",
|
||||
"title": "Defender active and current",
|
||||
"detail": "Real-time protection on, service running, signatures current.",
|
||||
"evidence": "RealTimeProtectionEnabled=True; AMServiceEnabled=True; AntispywareSignatureAge=0 days; IsTamperProtected=True"
|
||||
},
|
||||
{
|
||||
"id": "sec.av_products.defender_only",
|
||||
"category": "security",
|
||||
"severity": "info",
|
||||
"title": "Defender is the only registered AV",
|
||||
"detail": "Only Microsoft/Windows Defender is registered in Security Center.",
|
||||
"evidence": "Windows Defender"
|
||||
},
|
||||
{
|
||||
"id": "sec.foreign_agents.screenconnect_connectwise_control",
|
||||
"category": "security",
|
||||
"severity": "critical",
|
||||
"title": "Foreign management/remote-access agent: ScreenConnect / ConnectWise Control",
|
||||
"detail": "A competitor RMM or unmanaged remote-access tool is present. At onboarding this is a security and control risk (a prior MSP or attacker may retain remote access). Verify it is authorized; if not, remove it.",
|
||||
"evidence": "program: ScreenConnect Client (1912bf3444b41a08) 26.1.24.9579\nservice: ScreenConnect Client (1912bf3444b41a08) (ScreenConnect Client (1912bf3444b41a08)) Running"
|
||||
},
|
||||
{
|
||||
"id": "sec.foreign_agents.splashtop_sos_streamer_",
|
||||
"category": "security",
|
||||
"severity": "critical",
|
||||
"title": "Foreign management/remote-access agent: Splashtop (SOS/Streamer)",
|
||||
"detail": "A competitor RMM or unmanaged remote-access tool is present. At onboarding this is a security and control risk (a prior MSP or attacker may retain remote access). Verify it is authorized; if not, remove it.",
|
||||
"evidence": "program: Splashtop Streamer 3.8.2.0\nservice: SplashtopRemoteService (Splashtop? Remote Service) Running"
|
||||
},
|
||||
{
|
||||
"id": "sec.foreign_agents.syncro_kabuto",
|
||||
"category": "security",
|
||||
"severity": "critical",
|
||||
"title": "Foreign management/remote-access agent: Syncro / Kabuto",
|
||||
"detail": "A competitor RMM or unmanaged remote-access tool is present. At onboarding this is a security and control risk (a prior MSP or attacker may retain remote access). Verify it is authorized; if not, remove it.",
|
||||
"evidence": "program: Syncro 1.0.201.18410\nservice: Syncro (Syncro) Running"
|
||||
},
|
||||
{
|
||||
"id": "sec.firewall.error",
|
||||
"category": "security",
|
||||
"severity": "unknown",
|
||||
"title": "Check failed: Windows Firewall profiles",
|
||||
"detail": "The probe could not complete this check. Manual review recommended.",
|
||||
"evidence": "Invalid class "
|
||||
},
|
||||
{
|
||||
"id": "sec.bitlocker.unavailable",
|
||||
"category": "security",
|
||||
"severity": "unknown",
|
||||
"title": "BitLocker status unavailable",
|
||||
"detail": "Get-BitLockerVolume failed for the OS volume. BitLocker may not be installed (Home edition) or the cmdlet is unavailable. Verify encryption manually (manage-bde -status).",
|
||||
"evidence": "MountPoint=C:, Get-BitLockerVolume returned null"
|
||||
},
|
||||
{
|
||||
"id": "sec.local_admins.list",
|
||||
"category": "security",
|
||||
"severity": "info",
|
||||
"title": "Local administrators (4)",
|
||||
"detail": "Members of the local Administrators group. Review for unexpected or unknown accounts (especially leftover MSP/vendor accounts from a prior provider).",
|
||||
"evidence": "LEGALASST\\Administrator\nLEGALASST\\Ale\nLEGALASST\\Emma\nLEGALASST\\localadmin"
|
||||
},
|
||||
{
|
||||
"id": "sec.patch.os_eol",
|
||||
"category": "security",
|
||||
"severity": "critical",
|
||||
"title": "OS build is end-of-life: Win10 22H2",
|
||||
"detail": "This OS build (19045, Win10 22H2) passed end-of-servicing on 2025-10-14. It no longer receives security updates. Plan a feature update or OS upgrade.",
|
||||
"evidence": "Microsoft Windows 10 Pro build 19045; EOL 2025-10-14"
|
||||
},
|
||||
{
|
||||
"id": "sec.patch.pending",
|
||||
"category": "security",
|
||||
"severity": "warning",
|
||||
"title": "1 pending Windows updates",
|
||||
"detail": "Windows Update reports pending (not installed, not hidden) updates. Some may be security updates. Approve/install on the next maintenance window.",
|
||||
"evidence": "Microsoft.Update.Session search IsInstalled=0 and IsHidden=0 -> 1"
|
||||
},
|
||||
{
|
||||
"id": "sec.patch.last_hotfix",
|
||||
"category": "security",
|
||||
"severity": "info",
|
||||
"title": "Last hotfix: KB5075039",
|
||||
"detail": "Most recently installed update (from Get-HotFix; reflects CBS/MSU packages, not all cumulative metadata).",
|
||||
"evidence": "KB5075039 installed 2026-03-04T07:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": "sec.exposure.smb1_off",
|
||||
"category": "security",
|
||||
"severity": "info",
|
||||
"title": "SMBv1 disabled",
|
||||
"detail": "SMBv1 server protocol is disabled.",
|
||||
"evidence": "EnableSMB1Protocol=False"
|
||||
},
|
||||
{
|
||||
"id": "sec.exposure.laps_present",
|
||||
"category": "security",
|
||||
"severity": "info",
|
||||
"title": "LAPS detected",
|
||||
"detail": "A LAPS mechanism is present.",
|
||||
"evidence": "Windows LAPS reg key"
|
||||
},
|
||||
{
|
||||
"id": "health.disk_smart.unavailable",
|
||||
"category": "health",
|
||||
"severity": "unknown",
|
||||
"title": "Physical disk health unavailable",
|
||||
"detail": "Get-PhysicalDisk is unavailable (older OS / RAID controller hiding disks). Verify drive health via vendor tools.",
|
||||
"evidence": "Get-PhysicalDisk returned null"
|
||||
},
|
||||
{
|
||||
"id": "health.stability.some",
|
||||
"category": "health",
|
||||
"severity": "warning",
|
||||
"title": "Stability events present in the last 14 days",
|
||||
"detail": "One or more unexpected shutdowns, BSODs, or disk errors occurred recently. Monitor and correlate with user reports.",
|
||||
"evidence": "Unexpected shutdowns (id 41)=0; Bugchecks/BSOD (id 1001)=0; Disk errors (id 7/51/153)=1"
|
||||
},
|
||||
{
|
||||
"id": "health.reboot_uptime.pending",
|
||||
"category": "health",
|
||||
"severity": "warning",
|
||||
"title": "Reboot pending",
|
||||
"detail": "A reboot is pending. Pending reboots can block patches and leave the system in a half-updated state. Schedule a restart.",
|
||||
"evidence": "PendingFileRenameOperations"
|
||||
},
|
||||
{
|
||||
"id": "health.reboot_uptime.long_uptime",
|
||||
"category": "health",
|
||||
"severity": "warning",
|
||||
"title": "Uptime is 43.1 days",
|
||||
"detail": "Uptime exceeds 30 days. Long uptime usually means pending updates have not been applied (reboots deferred). Schedule maintenance.",
|
||||
"evidence": "LastBootUpTime=2026-04-16 10:07:07Z"
|
||||
},
|
||||
{
|
||||
"id": "health.failed_services.stopped",
|
||||
"category": "health",
|
||||
"severity": "warning",
|
||||
"title": "3 auto-start service(s) not running",
|
||||
"detail": "These services are set to start automatically but are not running. Some may be benign; review for security agents, backup agents, or AV that should be running.",
|
||||
"evidence": "WMPNetworkSvc (Windows Media Player Network Sharing Service) = Stopped\nGoogleUpdaterInternalService149.0.7814.0 (Google Updater Internal Service (GoogleUpdaterInternalService149.0.7814.0)) = Stopped\nGoogleUpdaterService149.0.7814.0 (Google Updater Service (GoogleUpdaterService149.0.7814.0)) = Stopped"
|
||||
},
|
||||
{
|
||||
"id": "health.domain.workgroup",
|
||||
"category": "health",
|
||||
"severity": "info",
|
||||
"title": "Not domain-joined (workgroup)",
|
||||
"detail": "This machine is in workgroup/Azure AD only mode (Domain=WORKGROUP). No on-prem AD secure channel applies.",
|
||||
"evidence": "PartOfDomain=False; Domain=WORKGROUP"
|
||||
},
|
||||
{
|
||||
"id": "health.time.source",
|
||||
"category": "health",
|
||||
"severity": "info",
|
||||
"title": "Time service source",
|
||||
"detail": "Current Windows Time service source.",
|
||||
"evidence": "Source=time.windows.com,0x9"
|
||||
},
|
||||
{
|
||||
"id": "health.backup.none",
|
||||
"category": "health",
|
||||
"severity": "info",
|
||||
"title": "No backup agent detected",
|
||||
"detail": "No known backup agent service found. Backup expectation varies by endpoint; confirm whether this machine is supposed to have local/cloud backup and whether server-side or M365 backup covers it.",
|
||||
"evidence": "No matching backup service in Win32_Service"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,258 @@
|
||||
# Onboarding Diagnostic Baseline - LEGALASST
|
||||
|
||||
- **Grade:** RED
|
||||
- **Host:** LEGALASST
|
||||
- **Client:** Rednour Law Offices (`rednour`)
|
||||
- **Collected (UTC):** 2026-05-29T20:05:50Z
|
||||
- **Agent ID:** 18825ea7-df58-47bb-b492-822cb16fb5ec
|
||||
- **Command ID:** beb27c88-4161-4183-a2b9-c43ec1ea0c0b
|
||||
- **Findings:** 4 critical / 5 warning / 9 info / 3 unknown
|
||||
|
||||
- **OS:** Microsoft Windows 10 Pro (build 19045)
|
||||
|
||||
---
|
||||
|
||||
## CRITICAL (4)
|
||||
|
||||
### Foreign management/remote-access agent: ScreenConnect / ConnectWise Control
|
||||
- **Category:** security
|
||||
- **ID:** `sec.foreign_agents.screenconnect_connectwise_control`
|
||||
- A competitor RMM or unmanaged remote-access tool is present. At onboarding this is a security and control risk (a prior MSP or attacker may retain remote access). Verify it is authorized; if not, remove it.
|
||||
|
||||
```
|
||||
program: ScreenConnect Client (1912bf3444b41a08) 26.1.24.9579
|
||||
service: ScreenConnect Client (1912bf3444b41a08) (ScreenConnect Client (1912bf3444b41a08)) Running
|
||||
```
|
||||
|
||||
### Foreign management/remote-access agent: Splashtop (SOS/Streamer)
|
||||
- **Category:** security
|
||||
- **ID:** `sec.foreign_agents.splashtop_sos_streamer_`
|
||||
- A competitor RMM or unmanaged remote-access tool is present. At onboarding this is a security and control risk (a prior MSP or attacker may retain remote access). Verify it is authorized; if not, remove it.
|
||||
|
||||
```
|
||||
program: Splashtop Streamer 3.8.2.0
|
||||
service: SplashtopRemoteService (Splashtop? Remote Service) Running
|
||||
```
|
||||
|
||||
### Foreign management/remote-access agent: Syncro / Kabuto
|
||||
- **Category:** security
|
||||
- **ID:** `sec.foreign_agents.syncro_kabuto`
|
||||
- A competitor RMM or unmanaged remote-access tool is present. At onboarding this is a security and control risk (a prior MSP or attacker may retain remote access). Verify it is authorized; if not, remove it.
|
||||
|
||||
```
|
||||
program: Syncro 1.0.201.18410
|
||||
service: Syncro (Syncro) Running
|
||||
```
|
||||
|
||||
### OS build is end-of-life: Win10 22H2
|
||||
- **Category:** security
|
||||
- **ID:** `sec.patch.os_eol`
|
||||
- This OS build (19045, Win10 22H2) passed end-of-servicing on 2025-10-14. It no longer receives security updates. Plan a feature update or OS upgrade.
|
||||
|
||||
```
|
||||
Microsoft Windows 10 Pro build 19045; EOL 2025-10-14
|
||||
```
|
||||
|
||||
|
||||
## WARNING (5)
|
||||
|
||||
### 1 pending Windows updates
|
||||
- **Category:** security
|
||||
- **ID:** `sec.patch.pending`
|
||||
- Windows Update reports pending (not installed, not hidden) updates. Some may be security updates. Approve/install on the next maintenance window.
|
||||
|
||||
```
|
||||
Microsoft.Update.Session search IsInstalled=0 and IsHidden=0 -> 1
|
||||
```
|
||||
|
||||
### Stability events present in the last 14 days
|
||||
- **Category:** health
|
||||
- **ID:** `health.stability.some`
|
||||
- One or more unexpected shutdowns, BSODs, or disk errors occurred recently. Monitor and correlate with user reports.
|
||||
|
||||
```
|
||||
Unexpected shutdowns (id 41)=0; Bugchecks/BSOD (id 1001)=0; Disk errors (id 7/51/153)=1
|
||||
```
|
||||
|
||||
### Reboot pending
|
||||
- **Category:** health
|
||||
- **ID:** `health.reboot_uptime.pending`
|
||||
- A reboot is pending. Pending reboots can block patches and leave the system in a half-updated state. Schedule a restart.
|
||||
|
||||
```
|
||||
PendingFileRenameOperations
|
||||
```
|
||||
|
||||
### Uptime is 43.1 days
|
||||
- **Category:** health
|
||||
- **ID:** `health.reboot_uptime.long_uptime`
|
||||
- Uptime exceeds 30 days. Long uptime usually means pending updates have not been applied (reboots deferred). Schedule maintenance.
|
||||
|
||||
```
|
||||
LastBootUpTime=2026-04-16 10:07:07Z
|
||||
```
|
||||
|
||||
### 3 auto-start service(s) not running
|
||||
- **Category:** health
|
||||
- **ID:** `health.failed_services.stopped`
|
||||
- These services are set to start automatically but are not running. Some may be benign; review for security agents, backup agents, or AV that should be running.
|
||||
|
||||
```
|
||||
WMPNetworkSvc (Windows Media Player Network Sharing Service) = Stopped
|
||||
GoogleUpdaterInternalService149.0.7814.0 (Google Updater Internal Service (GoogleUpdaterInternalService149.0.7814.0)) = Stopped
|
||||
GoogleUpdaterService149.0.7814.0 (Google Updater Service (GoogleUpdaterService149.0.7814.0)) = Stopped
|
||||
```
|
||||
|
||||
|
||||
## INFO (9)
|
||||
|
||||
### Defender active and current
|
||||
- **Category:** security
|
||||
- **ID:** `sec.defender.ok`
|
||||
- Real-time protection on, service running, signatures current.
|
||||
|
||||
```
|
||||
RealTimeProtectionEnabled=True; AMServiceEnabled=True; AntispywareSignatureAge=0 days; IsTamperProtected=True
|
||||
```
|
||||
|
||||
### Defender is the only registered AV
|
||||
- **Category:** security
|
||||
- **ID:** `sec.av_products.defender_only`
|
||||
- Only Microsoft/Windows Defender is registered in Security Center.
|
||||
|
||||
```
|
||||
Windows Defender
|
||||
```
|
||||
|
||||
### Local administrators (4)
|
||||
- **Category:** security
|
||||
- **ID:** `sec.local_admins.list`
|
||||
- Members of the local Administrators group. Review for unexpected or unknown accounts (especially leftover MSP/vendor accounts from a prior provider).
|
||||
|
||||
```
|
||||
LEGALASST\Administrator
|
||||
LEGALASST\Ale
|
||||
LEGALASST\Emma
|
||||
LEGALASST\localadmin
|
||||
```
|
||||
|
||||
### Last hotfix: KB5075039
|
||||
- **Category:** security
|
||||
- **ID:** `sec.patch.last_hotfix`
|
||||
- Most recently installed update (from Get-HotFix; reflects CBS/MSU packages, not all cumulative metadata).
|
||||
|
||||
```
|
||||
KB5075039 installed 2026-03-04T07:00:00Z
|
||||
```
|
||||
|
||||
### SMBv1 disabled
|
||||
- **Category:** security
|
||||
- **ID:** `sec.exposure.smb1_off`
|
||||
- SMBv1 server protocol is disabled.
|
||||
|
||||
```
|
||||
EnableSMB1Protocol=False
|
||||
```
|
||||
|
||||
### LAPS detected
|
||||
- **Category:** security
|
||||
- **ID:** `sec.exposure.laps_present`
|
||||
- A LAPS mechanism is present.
|
||||
|
||||
```
|
||||
Windows LAPS reg key
|
||||
```
|
||||
|
||||
### Not domain-joined (workgroup)
|
||||
- **Category:** health
|
||||
- **ID:** `health.domain.workgroup`
|
||||
- This machine is in workgroup/Azure AD only mode (Domain=WORKGROUP). No on-prem AD secure channel applies.
|
||||
|
||||
```
|
||||
PartOfDomain=False; Domain=WORKGROUP
|
||||
```
|
||||
|
||||
### Time service source
|
||||
- **Category:** health
|
||||
- **ID:** `health.time.source`
|
||||
- Current Windows Time service source.
|
||||
|
||||
```
|
||||
Source=time.windows.com,0x9
|
||||
```
|
||||
|
||||
### No backup agent detected
|
||||
- **Category:** health
|
||||
- **ID:** `health.backup.none`
|
||||
- No known backup agent service found. Backup expectation varies by endpoint; confirm whether this machine is supposed to have local/cloud backup and whether server-side or M365 backup covers it.
|
||||
|
||||
```
|
||||
No matching backup service in Win32_Service
|
||||
```
|
||||
|
||||
|
||||
## UNKNOWN (3)
|
||||
|
||||
### Check failed: Windows Firewall profiles
|
||||
- **Category:** security
|
||||
- **ID:** `sec.firewall.error`
|
||||
- The probe could not complete this check. Manual review recommended.
|
||||
|
||||
```
|
||||
Invalid class
|
||||
```
|
||||
|
||||
### BitLocker status unavailable
|
||||
- **Category:** security
|
||||
- **ID:** `sec.bitlocker.unavailable`
|
||||
- Get-BitLockerVolume failed for the OS volume. BitLocker may not be installed (Home edition) or the cmdlet is unavailable. Verify encryption manually (manage-bde -status).
|
||||
|
||||
```
|
||||
MountPoint=C:, Get-BitLockerVolume returned null
|
||||
```
|
||||
|
||||
### Physical disk health unavailable
|
||||
- **Category:** health
|
||||
- **ID:** `health.disk_smart.unavailable`
|
||||
- Get-PhysicalDisk is unavailable (older OS / RAID controller hiding disks). Verify drive health via vendor tools.
|
||||
|
||||
```
|
||||
Get-PhysicalDisk returned null
|
||||
```
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Inventory Baseline Summary
|
||||
|
||||
- **Manufacturer / Model:** To Be Filled By O.E.M. / To Be Filled By O.E.M.
|
||||
- **Serial:** To Be Filled By O.E.M.
|
||||
- **CPU:** AMD Ryzen 3 3200G with Radeon Vega Graphics (4 cores / 4 logical)
|
||||
- **RAM (GB):** 5.9
|
||||
- **BIOS:** P3.50 (2019-05-15)
|
||||
- **Chassis is laptop:** false
|
||||
- **TPM present / Secure Boot:** ? / ?
|
||||
- **Domain joined:** false (WORKGROUP)
|
||||
- **OS activation licensed:** ?
|
||||
- **Uptime (days):** 43.1
|
||||
- **Pending reboot:** true
|
||||
- **Installed software count:** 68
|
||||
- **Scheduled tasks (non-MS, enabled):** 13
|
||||
- **Local administrators:** LEGALASST\Administrator, LEGALASST\Ale, LEGALASST\Emma, LEGALASST\localadmin
|
||||
|
||||
### Fixed volumes
|
||||
|
||||
|
||||
### Network adapters
|
||||
|
||||
- Realtek PCIe GbE Family Controller - IP: 192.168.10.213 - DNS: 192.168.10.1 - DHCP: true
|
||||
|
||||
---
|
||||
|
||||
## Diff vs Prior Baseline
|
||||
|
||||
- No prior baseline found for this host. This is the first baseline.
|
||||
|
||||
---
|
||||
|
||||
_Generated by run-onboarding-diagnostic.sh (GuruRMM onboarding diagnostic, Phase 1). Raw snapshot: `LEGALASST-20260529T200647.json` (immutable)._
|
||||
Reference in New Issue
Block a user