Document Phase 2 system telemetry
Records why rebootreasons is not redundant with pendingreboot, why bootinfo carries two facts that must not be collapsed, and why defender is stored unsurfaced. Also corrects the notes: pending file-rename was already being collected and OR-ed into pendingreboot, so the gap was that the stronger signal was flattened into the weaker one rather than missing. Records that the columns landed as 0015 because 0014 was taken by disk health earlier in this phase.
This commit is contained in:
@@ -155,11 +155,18 @@ inventory-snapshot plumbing and one migration.
|
||||
ManagementObjectSearcher, not the friendly strings `Get-PhysicalDisk` prints
|
||||
(Health=0 Op=2 Media=4 Bus=17 for a healthy NVMe); the mapping lives in the
|
||||
collector so the wire stays self-describing.
|
||||
- **NIC link speed and duplex** - collect, pair into the existing Network
|
||||
interfaces collection, NOT surfaced yet.
|
||||
- **Boot type** - fast startup vs true cold boot. Explains why uptime lies and
|
||||
why a "reboot" did not clear a fault. Collect now; UI placement undecided,
|
||||
candidate for the Operating system or Hardware card.
|
||||
- **NIC link speed and duplex** - DONE. Paired onto the existing interfaces
|
||||
entries by MAC from `MSFT_NetAdapter` (`Win32_NetworkAdapterConfiguration`
|
||||
carries no link state, so it is a second query). Both fields are null when
|
||||
unreadable: verified on the live box that a DISCONNECTED adapter returns
|
||||
empty Speed and FullDuplex, so defaulting would have reported every unplugged
|
||||
NIC as half-duplex. Not surfaced.
|
||||
- **Boot type** - DONE. Two facts kept separate: `hiberbootenabled` from the
|
||||
registry (fast startup configured) and `lastboottype` from Kernel-Boot event
|
||||
27 (what the last boot did). Neither substitutes for the other - the registry
|
||||
cannot say what the last boot did, and the event can age out of the log.
|
||||
Verified live: BootType=0 with HiberbootEnabled=0. Not surfaced; placement
|
||||
still undecided.
|
||||
- **Windows Update history, last 5** - PINNED, deferred out of Phase 2. The COM
|
||||
update searcher is not cheap: it routinely takes seconds and sometimes tens of
|
||||
seconds, which would make it the most expensive thing in an otherwise
|
||||
@@ -170,20 +177,28 @@ inventory-snapshot plumbing and one migration.
|
||||
interfering with collections - or with the hosted application itself. Needs
|
||||
its own investigation before any implementation, and if it lands it wants its
|
||||
own cadence (hourly/daily), never the every-cycle path.
|
||||
- **Defender/AV health** - collect and persist, do NOT surface. Known to
|
||||
produce false positives in this environment; stored for future wiring.
|
||||
- **Defender/AV health** - DONE, collected and persisted, NOT surfaced, exactly
|
||||
as specified. Note the ages are in days and a real 0 means updated today, so
|
||||
the collector sends null rather than 0 when Defender did not report. A box
|
||||
with third-party AV or a stripped image has no Defender WMI provider at all,
|
||||
which is normal here and not a fault.
|
||||
|
||||
Explicitly dropped after discussion, do not collect:
|
||||
certificates (corporate-managed), BitLocker (network join already requires it),
|
||||
display topology (single monitor on the floor, trained users), session
|
||||
type/RDP (RDP-in not permitted on the shop floor), logon server (local users).
|
||||
|
||||
**Pending file-rename operations** - CONFIRMED, collect. A stronger
|
||||
reboot-required signal than the current `pendingreboot` key, and cheap.
|
||||
**Pending file-rename operations** - DONE, but NOT as a new collection. It was
|
||||
already being read: `GetPendingReboot()` OR-s it together with the CBS and
|
||||
Windows Update keys into one bool. The gap was that the bool cannot say WHICH
|
||||
signal fired, so the "stronger signal" was already being flattened into the
|
||||
weaker one. Shipped as `rebootreasons`, a list naming the signals that fired,
|
||||
leaving `pendingreboot` untouched for compatibility. Empty list = checked,
|
||||
nothing pending; null = the check failed.
|
||||
|
||||
Schema: these add columns to `endpointstates`. One migration, `0014`, with
|
||||
idempotent guards and a real downgrade, shipped in the SAME change as the model
|
||||
edit (a model referencing an unapplied column 500s every query on the table).
|
||||
Schema: these add columns to `endpointstates`. This landed as `0015`, not the
|
||||
`0014` reserved here - `0014` was taken by the disk health column earlier in
|
||||
Phase 2.
|
||||
|
||||
## Phase 3 - Service/Process Monitors tab split
|
||||
|
||||
|
||||
@@ -68,6 +68,18 @@ arrays. `adopt` is first-contact only.
|
||||
"osinfo": { /* opaque object: build, version, install date */ },
|
||||
"domain": "shopfloor.example.com", // domain or workgroup membership
|
||||
"pendingreboot": false, // omit when unknown; absent != false
|
||||
"rebootreasons": [], // [] = checked, nothing pending; see notes
|
||||
"bootinfo": {
|
||||
"hiberbootenabled": false, // fast startup CONFIGURED
|
||||
"lastboottype": "Cold" // what the last boot DID: Cold|Fast startup|Resume|Unknown
|
||||
},
|
||||
"defender": { // persisted, deliberately not surfaced
|
||||
"serviceenabled": true,
|
||||
"realtimeenabled": true,
|
||||
"signatureagedays": 0, // real 0 = updated today; null = did not report
|
||||
"antispywareagedays": 0,
|
||||
"quickscanagedays": 0
|
||||
},
|
||||
"diskhealth": [ // per PHYSICAL device; see notes
|
||||
{
|
||||
"deviceid": "0",
|
||||
@@ -144,6 +156,28 @@ Notes:
|
||||
genuinely empty now"; omit when you simply did not collect it this cycle.
|
||||
- `pendingreboot` follows that rule strictly: omit it when the check failed. A
|
||||
literal `false` asserts the endpoint is confirmed NOT holding a reboot.
|
||||
- `rebootreasons` is NOT redundant with `pendingreboot`. That key is a single
|
||||
bool OR-ed from three registry signals and cannot say which fired, and the
|
||||
difference is operational: `pendingfilerename` means files are staged for
|
||||
replacement on next boot, so the box is mid-servicing, while a lone
|
||||
`componentbasedservicing` or `windowsupdate` key can sit set for weeks on a
|
||||
machine nobody has rebooted. Same boolean, very different urgency. An EMPTY
|
||||
array means checked and nothing pending; OMIT the key when the check failed.
|
||||
- `bootinfo` carries two distinct facts that must not be collapsed:
|
||||
`hiberbootenabled` is whether fast startup is CONFIGURED (registry, always
|
||||
readable) and `lastboottype` is what the last boot ACTUALLY did (Kernel-Boot
|
||||
event 27). The registry cannot tell you what the last boot did, and the event
|
||||
may have aged out of the log, so neither substitutes for the other. This
|
||||
exists because uptime LIES under fast startup: a box reports days of uptime
|
||||
after what the operator experienced as a shutdown.
|
||||
- `defender` is stored but deliberately NOT surfaced. Defender produces known
|
||||
false positives in this environment, so wiring it to a card now would train
|
||||
operators to ignore that card. Signature/scan ages are in DAYS; a real `0`
|
||||
means updated today, so send `null` when Defender did not report rather than
|
||||
defaulting to zero.
|
||||
- `interfaces` entries gained `linkspeedbps` and `fullduplex`, paired on by MAC
|
||||
from `MSFT_NetAdapter`. Both are `null` when link state was unreadable or the
|
||||
adapter is disconnected - an unknown duplex must not read as half-duplex.
|
||||
- `diskhealth` is per PHYSICAL device and is NOT the same list as `disks`, which
|
||||
is per volume. One physical drive can back several volumes or none the
|
||||
operator sees, so the two do not share a key and are not merged.
|
||||
|
||||
Reference in New Issue
Block a user