Fix 7 factual errors in GE-Enforce doc (Fable fact-check vs real source)
Verified claim-by-claim against the engine/dispatcher/preinstall runner/manifests. Corrections (3 were ship-blocking): - Timeline (ship-blocking): identity files (pc-type/machine-number/cmm version/ site-config) are written in WinPE at the PXE menu BEFORE the image boots, not during a post-imaging 'enrollment' step; preinstall already reads them. Added a step [0]; enrollment is now only Intune + Azure DSC credential provisioning. - _CmmVersion (ship-blocking): a CMM bay with NO resolved version gets ALL PC-DMIS versions (legacy install-all), not none. - machine-number 9999 (ship-blocking): the enforcement engine does not special-case 9999; it is a placeholder that won't match real bay gates (the 9999-skip is status-write-back only). - Preinstall runner implements only MSI/EXE + Registry/File detection, not the full matrix (that is runtime-only). - Runtime processes up to three scopes: common, type, then optional type-subtype. - pc-subtype.txt is legacy (no longer written at imaging since 2026-05-04). - The collector ComputerType mapping lives at Settings > Collector PC Types, not the geenforce scope (scope computertypeid is a local reference field). - FileVersion is a raw string compare; 4-part is convention, not engine-enforced. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -45,10 +45,13 @@ Every shopfloor PC is governed in two distinct phases:
|
||||
| Phase | When | Runs what | Purpose |
|
||||
|---|---|---|---|
|
||||
| **Preinstall** | ONCE, at imaging | `preinstall.json` (via the imaging `00-PreInstall` step) | Day-zero foundation: PowerShell 7, the VC++ redistributable matrix, Oracle Client, Adobe Reader, HostExplorer, serial drivers, etc. "Install once at imaging, no drift correction." |
|
||||
| **Runtime** | EVERY logon + periodically | `common/manifest.json` then the PC's `gea-shopfloor-<type>/manifest.json` | Ongoing enforcement + self-heal: app versions, config-file drift, registry drift, per-cycle scripts (asset report, VNC firewall, EventSaver), version-gated installs. |
|
||||
| **Runtime** | EVERY logon + periodically | `common/manifest.json`, then `gea-shopfloor-<type>/manifest.json`, then an optional `<type>-<subtype>` manifest | Ongoing enforcement + self-heal: app versions, config-file drift, registry drift, per-cycle scripts (asset report, VNC firewall, EventSaver), version-gated installs. |
|
||||
|
||||
The two phases share the SAME entry schema but are run by different runners.
|
||||
Preinstall is a one-shot at imaging; runtime is the continuous enforcement loop.
|
||||
The two phases share the same entry SHAPE (field names) but are run by different
|
||||
runners with different capabilities. Preinstall is a one-shot at imaging that
|
||||
implements only `Type=MSI` and `Type=EXE`, with only `Registry` / `File`
|
||||
detection (other types/detections are skipped). Runtime is the continuous
|
||||
enforcement loop and implements the full Type + DetectionMethod matrix below.
|
||||
|
||||
### 2.2 The runtime loop, step by step
|
||||
|
||||
@@ -60,9 +63,9 @@ On each cycle (`GE-Enforce.ps1` on the PC):
|
||||
provisioned SFLD user - `net use W: ...`). If no credential yet, exit 0 and
|
||||
retry next cycle (Azure DSC has not provisioned it).
|
||||
3. Run the engine (`Install-FromManifest.ps1`) against `common/manifest.json`,
|
||||
then against `gea-shopfloor-<pctype>/manifest.json`. Common runs first so
|
||||
shared prerequisites (e.g. Oracle Client) land before type-specific apps that
|
||||
depend on them.
|
||||
then `gea-shopfloor-<pctype>/manifest.json`, then a `<pctype>-<subtype>`
|
||||
manifest if one exists. Common runs first so shared prerequisites (e.g.
|
||||
Oracle Client) land before type-specific apps that depend on them.
|
||||
4. Write a status file back to the share (and, in the shopdb model, POST a
|
||||
report - see 4.3).
|
||||
|
||||
@@ -101,7 +104,7 @@ Every entry has a `DetectionMethod` that decides whether the action fires:
|
||||
|---|---|
|
||||
| Registry | the key/value exists (optionally equals a value) |
|
||||
| File | the file exists |
|
||||
| FileVersion | the file's version equals an exact 4-part string |
|
||||
| FileVersion | the file's version string matches exactly (fleet convention is a 4-part string like 6.4.5.0; the engine does a raw string compare, it does not enforce 4 parts) |
|
||||
| Hash | the file's SHA256 matches (case-insensitive) |
|
||||
| MarkerFile | a marker file exists (the engine writes it after a clean install) |
|
||||
| ValueMatches | a registry value equals the entry's target |
|
||||
@@ -122,8 +125,11 @@ An entry can be narrowed by any combination of:
|
||||
`collections`/`nocollections`/`common`). Fleet-wide `common` uses this heavily.
|
||||
- `TargetHostnames` - specific hostnames (supports `*` wildcards).
|
||||
- `TargetMachineNumbers` - specific bay machine numbers (e.g. Okuma bays).
|
||||
- `_CmmVersion` - CMM PCs only: install only on bays resolved to that PC-DMIS
|
||||
version (requires engine lib >= 2.6).
|
||||
- `_CmmVersion` - CMM PCs only: a tagged entry applies when it equals the bay's
|
||||
resolved PC-DMIS version (`C:\Enrollment\cmm\version.txt`). IMPORTANT: if no
|
||||
version is resolved (file missing/empty - a pre-picker bay), ALL tagged
|
||||
entries apply (deliberate legacy "install-all" behavior), so such a bay gets
|
||||
every PC-DMIS version, not none. Requires engine lib >= 2.6.
|
||||
- `PCTypesStrict` - disables alias expansion (PREINSTALL runner only; the runtime
|
||||
engine ignores it).
|
||||
|
||||
@@ -135,14 +141,24 @@ the gates a given scope actually uses (see 4.1).
|
||||
|
||||
The runtime engine reads the PC's identity from `C:\Enrollment\`:
|
||||
|
||||
- `pc-type.txt` / `pc-subtype.txt` - the imaging PC type (which scope to run).
|
||||
- `machine-number.txt` - the bay number (the eDNC/DNC registry value wins if
|
||||
present; the txt is the fallback). `9999` = placeholder/skip.
|
||||
- `pc-type.txt` - the imaging PC type (which scope to run). `pc-subtype.txt` is
|
||||
LEGACY (no longer written at imaging since the 2026-05-04 rename reorg; the
|
||||
dispatcher still honors it if present on older fleet PCs).
|
||||
- `machine-number.txt` - the bay number FALLBACK; the eDNC/DNC registry
|
||||
`MachineNo` value wins if present. `9999` is the imaging placeholder by
|
||||
convention - the enforcement engine does NOT special-case it; it is simply a
|
||||
value that won't match a real bay number in a `TargetMachineNumbers` gate.
|
||||
(The 9999-skip you may see is only in the status write-back, not enforcement.)
|
||||
- `cmm/version.txt` - CMM bays only: the resolved PC-DMIS version for `_CmmVersion`.
|
||||
- `site-config.json` - the share root and site settings.
|
||||
- SFLD credentials at `HKLM:\SOFTWARE\GE\SFLD\Credentials` - provisioned by
|
||||
Azure DSC after enrollment (this is what gates the runtime phase starting).
|
||||
|
||||
Note: all of the identity files above (pc-type, machine-number, cmm version,
|
||||
site-config) are written in WinPE at the PXE menu, BEFORE the image boots - the
|
||||
preinstall phase already reads them. What happens post-imaging is only Intune
|
||||
enrollment + the Azure DSC credential (see the timeline below).
|
||||
|
||||
---
|
||||
|
||||
## 3. When GE-Enforce installs / takes over (the imaging timeline)
|
||||
@@ -150,29 +166,38 @@ The runtime engine reads the PC's identity from `C:\Enrollment\`:
|
||||
This is the "when to implement it during imaging" question. The order is:
|
||||
|
||||
```
|
||||
PXE image applied
|
||||
[0] WinPE / PXE menu (BEFORE the image boots)
|
||||
- identity written to C:\Enrollment: pc-type.txt, machine-number.txt,
|
||||
cmm/version.txt, site-config.json (startnet.cmd). The PC already knows
|
||||
what it is before Windows starts.
|
||||
|
|
||||
v
|
||||
[1] PREINSTALL (00-PreInstall-* runs preinstall.json ONCE)
|
||||
- foundational software: PowerShell 7, VC++ redists, Oracle Client,
|
||||
Adobe Reader, HostExplorer, serial drivers, Display kiosk app, ...
|
||||
- these are the things later runtime apps depend on
|
||||
PXE image applied, Windows boots
|
||||
|
|
||||
v
|
||||
[1] PREINSTALL (00-PreInstall runner runs preinstall.json ONCE)
|
||||
- reads the step-0 identity files, then installs the foundation:
|
||||
PowerShell 7, VC++ redists, Oracle Client, Adobe Reader, HostExplorer,
|
||||
serial drivers, Display kiosk app, ... (things later runtime apps need)
|
||||
- preinstall implements MSI/EXE + Registry/File detection only
|
||||
|
|
||||
v
|
||||
[2] GE-ENFORCE ITSELF is laid down during imaging
|
||||
- the dispatcher (GE-Enforce.ps1), the engine lib (Install-FromManifest.ps1),
|
||||
and a scheduled task (at-logon + periodic) are placed on the PC as part
|
||||
of the image / common bootstrap
|
||||
and a scheduled task (at-logon + every ~5 min + shift windows) are
|
||||
registered as part of the image / shopfloor setup
|
||||
|
|
||||
v
|
||||
[3] ENROLLMENT
|
||||
- C:\Enrollment\* written: pc-type, machine number, cmm version, site-config
|
||||
- Azure DSC provisions the SFLD share credential in the registry
|
||||
[3] ENROLLMENT (post-imaging)
|
||||
- Intune / GCCH enrollment, THEN Azure DSC provisions the SFLD share
|
||||
credential into HKLM:\SOFTWARE\GE\SFLD\Credentials
|
||||
- (the identity files already exist from step 0 - enrollment adds only the
|
||||
credential, which is what unblocks runtime)
|
||||
|
|
||||
v
|
||||
[4] FIRST LOGON -> RUNTIME ENFORCEMENT BEGINS
|
||||
- the scheduled task runs GE-Enforce.ps1: mount share, run common + the
|
||||
PC-type manifest, install/self-heal, report
|
||||
PC-type (+ subtype) manifests, install/self-heal, report
|
||||
- repeats every logon + periodically forever after
|
||||
```
|
||||
|
||||
@@ -205,8 +230,10 @@ because it is a full management surface.
|
||||
|
||||
### 4.1 Manifests - authoring (GE-Enforce > Manifests)
|
||||
|
||||
- **PC Types (scopes):** each imaging PC type is a row; add/edit/delete. The
|
||||
ComputerType mapping the collector uses lives here too.
|
||||
- **PC Types (scopes):** each imaging PC type is a row; add/edit/delete. (The
|
||||
scope carries an optional `computertypeid` reference field, but the collector's
|
||||
imaging-pc-type -> ComputerType mapping is configured separately at
|
||||
Settings > Collector PC Types.)
|
||||
- **Entries:** an ordered list (Up/Down = the execution-order contract). Add/Edit
|
||||
opens a typed form: the payload fields switch on `Type` (MSI shows Installer +
|
||||
InstallArgs, PS1 shows Script + Args, File shows Source + Destination, Registry
|
||||
|
||||
Reference in New Issue
Block a user