# 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 "West Jefferson" `
  -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.

---

## 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.
