Consolidates per-type enforcers (CMM, Keyence, Machine, Common, Acrobat)
into one dispatcher driven by pc-type.txt + site-config and a share-side
manifest layout. Same share is now the single source of truth for routine
software updates without re-imaging.
Runtime:
common/GE-Enforce.ps1 SYSTEM scheduled task. Reads
common/manifest.json plus optional
<pcType>/manifest.json and
<pcType-subType>/manifest.json.
Dispatches each entry through the lib.
Writes _outputs/logs/<hostname>/status.json
on the share after each cycle for fleet
monitoring.
common/Register-GEEnforce.ps1 Task registration. Triggers: AtLogOn +
every 5 min (jittered per-PC from
hostname hash) + daily at 05:45,
13:45, 21:45 EST shift windows.
Unregisters legacy per-type tasks on
install so the two coexist at most for
the duration of a single enforce cycle.
common/Deploy-GEEnforce.ps1 Retrofit helper for already-imaged PCs
(admin-run; copies runtime + registers
task + optional immediate trigger).
Library (common/lib/Install-FromManifest.ps1):
- New Type values: PS1, BAT, File, Registry, INF
- New DetectionMethod values: Always, MarkerFile, ValueMatches, pnputil
- TargetHostnames filter (exact + -like wildcards, ANDed with PCTypes)
- Schema version check (logs WARN on manifest newer than lib MAJOR)
- Auto-writes MarkerFile on successful one-shot PS1/BAT/CMD runs
- MSI log scan on failure surfaces meaningful install errors
- Lib version bumped 2.0 -> 2.1 for TargetHostnames
Observability:
common/monitor-fleet-status.py Scans _outputs/logs/*/status.json for
stale check-ins, failed scopes, and
version drift. Respects scope (dir-name),
PCTypes, and TargetHostnames filters so
entries excluded from a PC do not
false-flag as drift.
Regression harness:
common/test/ Parameterized VM harness + README
covering every action type plus
rollback, bad/missing SFLD creds, and
schema versioning.
Imaging integration:
Run-ShopfloorSetup.ps1 now stages GE-Enforce.ps1 and lib to
C:\Program Files\GE\Shopfloor\ and invokes Register-GEEnforce.ps1
at the end of setup. Legacy Register-CommonEnforce invocation is
kept for the transition; it and the legacy per-type enforcer files
are dead code once Register-GEEnforce runs and will be removed in a
dedicated cleanup pass.
Standard-Machine manifest:
eDNC entry bumped 6.4.3 -> 6.4.5. DetectionValue pinned to the
4-part FileVersion 6.4.5.0 verified against a fresh install in the
Win11 analyzer VM. UDC DetectionValue pinned to 1.0.34 (registry
stores 3-part for UDC; verified live).
scripts/mirror-from-gold.sh:
Restructured around share-root rsyncs (one pass per Samba share)
to close gaps in the prior per-subdir layout: winpeapps/_shared/
Applications (7.5 GB of Adobe + fonts + Java + Office + OpenText
+ printdrivers + wireless + Zscaler), additional winpeapps image
types, and enrollment flat-layout root files. Adds
--skip-clonezilla and --skip-reports.
Verified end-to-end in the Win11 analyzer VM:
- Every action Type and DetectionMethod round-tripped
- PCTypes filter (Oracle excluded on Shopfloor, Firefox included
on Shopfloor and DESKTOP-*, excluded elsewhere)
- TargetHostnames filter (exact, wildcard, no-match)
- Upgrade path: XML hash bump + fleet re-copy
- Rollback path: history-archive restore propagates via enforcer,
fleet converges back without per-PC intervention
- Status writeback + monitor script drift detection
- Graceful degradation on bad creds, missing creds, share
unreachable (all exit 0, log clearly, retry next cycle)
Not in this commit (follow-ups):
- Retire legacy per-type *-Enforce.ps1 files and simplify
09-Setup-*.ps1 scripts (coordinated multi-file cleanup)
- Stage 2b: InUseCheck close-and-reopen, ApplyMode gating,
UpdateWindow, .apply-now.txt sentinel, BITS pre-staging,
1618 mutex retry, PostInstallCheck, Uninstall action
- Management app (manifest CRUD + deploy + rollback + fleet view)
- ShopFloor autologon persistence bug (deferred for next imaging
attempt with live registry evidence)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
37 lines
3.7 KiB
JSON
37 lines
3.7 KiB
JSON
{
|
|
"Version": "1.0",
|
|
"_comment": "Standard-Machine shopfloor app enforcement manifest. This is the TEMPLATE kept in the repo; the authoritative copy lives on the SFLD share at \\\\tsgwp00525.wjs.geaerospace.net\\shared\\dt\\shopfloor\\main\\machineapps\\machineapps-manifest.json. Machine-Enforce.ps1 reads the share copy on every user logon via the 'GE Shopfloor Machine Apps Enforce' scheduled task (registered by Register-MachineEnforce.ps1 at imaging time, Standard-Machine only). Initial install still happens during the preinstall phase on the imaging PXE server; this enforcer is the ongoing drift-correction side. On a freshly-imaged PC detection passes immediately and the enforcer no-ops. Replaces DSC-based enforcement of these apps which was pulled because Intune DSC has no pc-subtype awareness and was pushing UDC/eDNC/NTLARS to Standard-Timeclock PCs.",
|
|
"Applications": [
|
|
{
|
|
"_comment": "UDC. Install args follow the preinstall.json pattern: Site name in quotes, then machine number placeholder (Configure-PC.ps1 re-runs UDC_Setup with the real machine number after imaging, so the placeholder is overwritten in HKLM at that point). KillAfterDetection is only meaningful during preinstall; the enforcer lets Install-FromManifest wait for the process normally.",
|
|
"Name": "UDC",
|
|
"Installer": "UDC_Setup.exe",
|
|
"Type": "EXE",
|
|
"InstallArgs": "\"West Jefferson\" 9999",
|
|
"DetectionMethod": "Registry",
|
|
"DetectionPath": "HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\UDC",
|
|
"DetectionName": "DisplayVersion",
|
|
"DetectionValue": "REPLACE_WITH_PINNED_UDC_VERSION"
|
|
},
|
|
{
|
|
"_comment": "eDNC 6.4.5. Ships with NTLARS bundled (NTLARS.exe lands at C:\\Program Files (x86)\\Dnc\\Common\\ as part of the same install), so no separate NTLARS entry is needed. SITESELECTED encodes the site (was a recurring bug in early shopfloor-setup scripts that omitted it). Adjust to your site's value if not West Jefferson. Detection uses FileVersion on DncMain.exe so version upgrades actually fire. The vendor stamps DncMain.exe with a 4-part version (e.g. '6.4.5.0'), not 3-part, so DetectionValue must be the exact 4-part string - an earlier 3-part value in this entry caused detection to always fail and the MSI reinstalled silently on every logon. Update workflow: drop the new MSI on the SFLD share, bump DetectionValue + Installer in this manifest to the new vendor-stamped FileVersion, and the next user logon installs it.",
|
|
"Name": "eDNC (bundles NTLARS)",
|
|
"Installer": "eDNC_6-4-5.msi",
|
|
"Type": "MSI",
|
|
"InstallArgs": "/qn /norestart ALLUSERS=1 REBOOT=ReallySuppress SITESELECTED=\"West Jefferson\"",
|
|
"DetectionMethod": "FileVersion",
|
|
"DetectionPath": "C:\\Program Files (x86)\\Dnc\\bin\\DncMain.exe",
|
|
"DetectionValue": "6.4.5.0"
|
|
},
|
|
{
|
|
"_comment": "Custom eMxInfo.txt (site-specific eDNC config). No vendor installer - the secret file lives on the SFLD share alongside the eDNC MSI. Install-eMxInfo.cmd copies it to both 32-bit and 64-bit eDNC Program Files paths. Hash detection catches both 'file missing' and 'file is a stale version'. Yearly rotation procedure: drop the new eMxInfo.txt on the share, recompute its SHA256 (PowerShell: (Get-FileHash .\\eMxInfo.txt -Algorithm SHA256).Hash), paste the new hash into DetectionValue here, save. Every Machine PC catches up on the next user logon. Content-sensitive: eMxInfo.txt must NEVER be committed to git (already in .gitignore).",
|
|
"Name": "eMxInfo.txt",
|
|
"Installer": "Install-eMxInfo.cmd",
|
|
"Type": "CMD",
|
|
"DetectionMethod": "Hash",
|
|
"DetectionPath": "C:\\Program Files\\eDNC\\eMxInfo.txt",
|
|
"DetectionValue": "87733201CB11E7343BD432F1E303FBF41DB58EBAAEFF37BD4C3C9B267B145A20"
|
|
}
|
|
]
|
|
}
|