Files
shopdb-flask/docs/GE-ENFORCE-DEPLOY.md
cproudlock 4995456136 docs: take one site's name, hosts and paths off the public wiki
The publishability gate caught internal tooling names and developer paths but
nothing site-specific, so roughly sixty leaks reached the wiki: the site name in
ten documents, real fleet hostnames in the collector and GE-Enforce examples, an
internal database name through the whole import guide, imaging-share paths, and
a maintainer's username as the Deciders line of every ADR and inside a generated
curl example.

None of it is a security matter on an air-gapped fleet. It matters because these
pages are read by engineers at other plants, and a document that names one site
throughout reads as that site's notes rather than a product's documentation -
which is exactly what it then gets treated as.

Examples now use neutral hostnames, the site is "the reference site" where the
distinction carries meaning, and ADRs are decided by "ShopDB maintainers". The
gate carries all of these patterns, so the next one fails a build.

Two documents leave docs/ because they were never written for an outside reader.
PROJECT-REVIEW.md is an internal health memo pinned to a commit from July, whose
headline finding (an untracked playbook) has since been fixed - it is history,
and git holds it. PILOT-DEPLOY.md is one site's own cutover runbook, complete
with a "re-measure before publishing" placeholder; it moves next to the loader
it belongs to, in scripts/site_imports/wjf/.

ADR-015 is AMENDED rather than rewritten. Its enforcement section still said
report-only and its backlog still listed hardcodes that are now cleared, which
left the record contradicting itself. The amendment says what changed and why
the report-only period ended; the original text stays, because what the decision
looked like when it was taken is the part worth keeping.

Also corrects llms.txt's response envelope, which had errors at the top level
and pagination at meta.total. Both are nested one deeper, so anything written
against that description read undefined on every error it tried to handle.
2026-08-14 15:38:27 -04:00

6.2 KiB

Deploying the GE-Enforce agent on a PC

This is the deploy contract: what has to be laid down on a PC so GE-Enforce runs, and how to do it regardless of imaging path (PXE, OOBE provisioning package, Intune, or by hand). It complements docs/GE-ENFORCE.md (concepts) and docs/GE-ENFORCE-CLIENT.md (the fetch/report contract).

The reference installer is plugins/geenforce/client/Install-GEEnforce.ps1. It is site-neutral: you pass the PC's identity in, it writes the files/registry the engine reads and registers the enforcement task.


1. What "deploying GE-Enforce" means

A PC needs three things present before enforcement works. HOW they get there is up to your imaging path; WHAT they are is fixed:

  1. The GE-Enforce client - the engine (Install-FromManifest.ps1), the shopdb client kit (ShopdbEnforceClient.psm1, Invoke-ShopdbEnforce.ps1), and a scheduled task (at logon + periodic) that runs as SYSTEM.
  2. Identity in C:\Enrollment - so the PC knows what it is (see section 2).
  3. A credential - the SFLD share credential (for a share-sourced manifest) and/or the shopdb service token (for the fetch/report client). This is what gates enforcement actually starting; until it exists the task exits 0 and retries.

Install-GEEnforce.ps1 lays down 1 and 2, and can write the shopdb token for 3. The engine itself is the GE-Enforce framework's, not shopdb's - point the installer at your copy with -EngineSource, or place it under the install root first (see section 5).


2. Identity: how a PC determines its PC type (and bay)

There is NO auto-detection. The provisioner supplies the values; the engine only reads files. This is the core of "set the PC up to know its type."

Value Written to Purpose Required?
PC type C:\Enrollment\pc-type.txt (first line) picks the manifest scope (gea-shopfloor-<type>) YES
Machine (bay) number C:\Enrollment\machine-number.txt (fallback; DNC registry MachineNo wins) per-bay gates only for bay-gated entries
CMM version C:\Enrollment\cmm\version.txt _CmmVersion gating (CMM PCs) CMM only
CMM bay id C:\Enrollment\cmm\cmmid.txt CMM bay identity CMM only
Share root + site C:\Enrollment\site-config.json where manifests/payloads live for share-sourced
shopdb URL + token HKLM:\SOFTWARE\GE\ShopDB (BaseUrl, ApiToken) fetch/report client for shopdb client

Valid pc-type values are the manifest scope names (gea-shopfloor-cmm, -collections, -nocollections, -common, -keyence, -genspect, -heattreat, -partmarker, -waxtrace) or a legacy alias the engine maps (Standard, CMM, ...).

shopdb cannot set the type at imaging - a PC is not known to shopdb until it enrolls and reports. If you want the value to come from an asset system, pre-map asset-tag / hostname -> PC type in your provisioning and feed it to the installer.


3. Running it, per imaging path

Install-GEEnforce.ps1 is the same in every case; only how you invoke it differs.

PXE / imaging step (identity known at image time)

Run it as an imaging step after the OS lays down, passing the type the operator selected:

powershell -ExecutionPolicy Bypass -File Install-GEEnforce.ps1 `
  -PCType gea-shopfloor-cmm -MachineNumber 0615 -CmmVersion 2019 `
  -ShareRoot \\server\share\dt\shopfloor -Site "the reference site" `
  -ShopdbUrl https://shopdb.site.geaerospace.net -ShopdbToken shopdb_pat_xxx `
  -EngineSource \\server\share\dt\shopfloor\common

OOBE provisioning package (ppkg)

Sites that apply a ppkg during OOBE (no PXE/WinPE step) embed the installer + the client kit in the ppkg and run it from a CommandLine / ProvisioningCommands action. Supply the PC type from a ppkg variable, a first-boot prompt, or an asset lookup:

powershell -ExecutionPolicy Bypass -File Install-GEEnforce.ps1 -PCType %PCTYPE% ...

Timing is forgiving: the scheduled task is fail-safe, so if OOBE finishes before Intune/DSC provisions the credential, enforcement simply waits and starts once the credential lands. There is no ordering trap.

Intune / manual

Same script as a Win32 app / remediation, or run by hand on an existing PC to retrofit it. -NoTask provisions identity + kit without registering the task.


4. What the installer does (idempotent)

  1. Writes the C:\Enrollment identity files (section 2).
  2. Writes HKLM:\SOFTWARE\GE\ShopDB (BaseUrl + token) if provided.
  3. Copies the client kit (the two files shipped next to it) to -InstallRoot (default C:\ProgramData\GE-Enforce).
  4. If -EngineSource is given, copies GE-Enforce.ps1 + lib\Install-FromManifest.ps1.
  5. Registers the scheduled task (SYSTEM, at logon + every -IntervalMinutes) to run Invoke-ShopdbEnforce.ps1 -Scope <PCType> -EnginePath <engine>.

Re-running it updates identity/config and re-registers the task in place.

For PC types that have cut over to HTTPS manifest delivery (currently displays/kiosks), the full server-side setup, auth model (IP allowlist vs ApiToken), and per-PC-type cutover playbook live in geenforce-api-cutover.md. This doc covers what gets laid on the PC; that doc covers where the manifest comes from.


5. The engine boundary

shopdb ships the manifest store + client kit + this installer, not the GE-Enforce engine (Install-FromManifest.ps1) or dispatcher - those live in the GE-Enforce framework. So one of:

  • pass -EngineSource <path> pointing at a folder that has GE-Enforce.ps1 and lib\Install-FromManifest.ps1 (e.g. your share's common dir), or
  • place the engine under <InstallRoot>\lib\Install-FromManifest.ps1 yourself before enforcement runs.

The installer warns if the engine is missing but still provisions identity so a PC is at least correctly labelled. Use engine lib >= 2.6 (required for the _CmmVersion gate).


6. Verify a provisioned PC

  • Get-Content C:\Enrollment\pc-type.txt -> the expected scope.
  • Get-ItemProperty HKLM:\SOFTWARE\GE\ShopDB -> BaseUrl + ApiToken set.
  • Get-ScheduledTask GE-Enforce -> Ready.
  • Trigger it once and check the client log (C:\Logs\Shopfloor\shopdb-enforce-*.log), then confirm the PC appears under GE-Enforce > Enforcement Reports in shopdb with the right PC type.