Deploy the site config bays actually read, and close the drift gate

The shortcut fix from e844ff3 has been live in git and absent from the floor
since 2026-08-06. site-config.json exists TWICE on the share, from one repo
source: enrollment/shopfloor-setup/ and enrollment/config/. Only the second one
is staged to a bay - startnet copies Y:\config\site-config.json to
W:\Enrollment\site-config.json - and it was the stale one.

So every bay imaged in the last two weeks came up without the Plant Apps startup
item and without the Defect_Tracker taskbar pin, while the drift report showed
site-config.json in sync, because it was reading the copy nothing consumes. A
green check on the wrong file is worse than no check.

Deployed the repo copy over it (backup on the server at
~/backups/site-config.json.bak-20260819) and marked BOTH destinations git-owned,
so neither can go stale behind the other.

The shopfloor unattend is reconciled the other way round. Live was 87 lines ahead
of the repo - the default-user startup-delay removal, the Windows Update
disables, the removable-media block that stops PPKG auto-detection at OOBE, and
the run-enrollment.ps1 path fix from C:\ to C:\Enrollment. The repo copy was a
201-line fossil. LIVE WINS: these files boot machines, and pushing the repo copy
over them is exactly the 2026-08-06 outage that prompted this tool. Adopted live
into the repo verbatim (lint clean) rather than merging by hand.

Also fixed a pair that could never pass: the engineer unattend was compared
against playbook/FlatUnattendW10.xml, which is the STANDARD answer file, so it
reported DIFFERS permanently. 6f86c81 added FlatUnattendW10-engineer.xml but did
not repoint the pair at it. A permanently red row is one nobody reads, which is
how the site-config gap stayed invisible next to it.

All twelve pairs are now git-owned and in sync, and the gate has nothing left
classified as "known bad" to hide behind.
This commit is contained in:
cproudlock
2026-08-19 15:41:46 -04:00
parent 6f86c81a44
commit 6e8b8a83a7
2 changed files with 308 additions and 212 deletions

View File

@@ -97,6 +97,52 @@
<Path>reg.exe add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\OOBE" /v SkipUserOOBE /t REG_DWORD /d 1 /f</Path> <Path>reg.exe add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\OOBE" /v SkipUserOOBE /t REG_DWORD /d 1 /f</Path>
<Description>Skip user OOBE phase</Description> <Description>Skip user OOBE phase</Description>
</RunSynchronousCommand> </RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>17</Order>
<Path>reg.exe load HKU\TempDefault C:\Users\Default\NTUSER.DAT</Path>
<Description>Load Default User registry hive</Description>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>18</Order>
<Path>reg.exe add "HKU\TempDefault\Software\Microsoft\Windows\CurrentVersion\Explorer\Serialize" /v StartupDelayInMSec /t REG_DWORD /d 0 /f</Path>
<Description>Disable startup delay for all new users</Description>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>19</Order>
<Path>reg.exe add "HKU\TempDefault\Software\Microsoft\Windows\CurrentVersion\Explorer\Serialize" /v WaitForIdleState /t REG_DWORD /d 0 /f</Path>
<Description>Disable wait for idle state for all new users</Description>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>20</Order>
<Path>reg.exe add "HKU\TempDefault\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" /v StartShownOnUpgrade /t REG_DWORD /d 1 /f</Path>
<Description>Prevent Start menu from opening on first login</Description>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>21</Order>
<Path>reg.exe unload HKU\TempDefault</Path>
<Description>Unload Default User registry hive</Description>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>22</Order>
<Path>reg add HKLM\Software\Policies\Microsoft\Windows\WindowsUpdate\AU /v NoAutoUpdate /t REG_DWORD /d 1 /f</Path>
<Description>Disable automatic Windows updates (NoAutoUpdate)</Description>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>23</Order>
<Path>reg add HKLM\Software\Policies\Microsoft\Windows\WindowsUpdate\AU /v AUOptions /t REG_DWORD /d 1 /f</Path>
<Description>Disable automatic Windows updates (AUOptions)</Description>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>24</Order>
<Path>reg.exe add "HKLM\Software\Microsoft\Command Processor" /v AutoRun /t REG_SZ /d "doskey vanilla=powershell.exe -ExecutionPolicy Bypass -WindowStyle Hidden -File C:\Deploy\Applications\BPRT\Show-VanillaConfirmation.ps1" /f</Path>
<Description>Define vanilla CMD alias for manual OOBE fallback via Shift+F10</Description>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>25</Order>
<Path>reg.exe add "HKLM\SOFTWARE\Policies\Microsoft\Windows\RemovableStorageDevices" /v Deny_All /t REG_DWORD /d 1 /f</Path>
<Description>Block all removable media reads to prevent PPKG auto-detection at OOBE</Description>
</RunSynchronousCommand>
</RunSynchronous> </RunSynchronous>
</component> </component>
</settings> </settings>
@@ -186,7 +232,12 @@
</SynchronousCommand> </SynchronousCommand>
<SynchronousCommand wcm:action="add"> <SynchronousCommand wcm:action="add">
<Order>10</Order> <Order>10</Order>
<CommandLine>powershell.exe -ExecutionPolicy Bypass -File "C:\run-enrollment.ps1"</CommandLine> <CommandLine>powershell.exe -ExecutionPolicy Bypass -File "C:\Enrollment\run-enrollment.ps1"</CommandLine>
<!-- run-enrollment.ps1 lives in C:\Enrollment: startnet stages it and
the .ppkg there. The earlier C:\run-enrollment.ps1 path pointed at a
file that never existed, so this step silently did nothing.
Keep prose in comments - Description is capped at 256 chars and an
over-length one invalidates the whole answer file for its pass. -->
<Description>Run GCCH Enrollment</Description> <Description>Run GCCH Enrollment</Description>
</SynchronousCommand> </SynchronousCommand>
<SynchronousCommand wcm:action="add"> <SynchronousCommand wcm:action="add">
@@ -194,6 +245,42 @@
<CommandLine>powershell.exe -ExecutionPolicy Bypass -File "C:\Enrollment\Run-ShopfloorSetup.ps1"</CommandLine> <CommandLine>powershell.exe -ExecutionPolicy Bypass -File "C:\Enrollment\Run-ShopfloorSetup.ps1"</CommandLine>
<Description>Run shopfloor PC type setup</Description> <Description>Run shopfloor PC type setup</Description>
</SynchronousCommand> </SynchronousCommand>
<SynchronousCommand wcm:action="add">
<CommandLine>cmd /c sc config wuauserv start= disabled</CommandLine>
<Description>disable windows update</Description>
<Order>12</Order>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<CommandLine>cmd /c sc stop wuauserv</CommandLine>
<Description>disable windows update</Description>
<Order>13</Order>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<CommandLine>reg.exe load HKU\TempDefault C:\Users\Default\NTUSER.DAT</CommandLine>
<Description>Load Default User registry hive to reverse startup delay</Description>
<Order>14</Order>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<CommandLine>reg.exe delete "HKU\TempDefault\Software\Microsoft\Windows\CurrentVersion\Explorer\Serialize" /v StartupDelayInMSec /f</CommandLine>
<Description>Remove startup delay override from Default User</Description>
<Order>15</Order>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<CommandLine>reg.exe delete "HKU\TempDefault\Software\Microsoft\Windows\CurrentVersion\Explorer\Serialize" /v WaitForIdleState /f</CommandLine>
<Description>Remove wait for idle state override from Default User</Description>
<Order>16</Order>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<CommandLine>reg.exe unload HKU\TempDefault</CommandLine>
<Description>Unload Default User registry hive</Description>
<Order>17</Order>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<CommandLine>reg.exe delete "HKLM\SOFTWARE\Policies\Microsoft\Windows\RemovableStorageDevices" /v Deny_All /f</CommandLine>
<Description>Restore removable media access after OOBE PPKG block</Description>
<Order>18</Order>
</SynchronousCommand>
</FirstLogonCommands> </FirstLogonCommands>
<TimeZone>Eastern Standard Time</TimeZone> <TimeZone>Eastern Standard Time</TimeZone>
</component> </component>

View File

@@ -63,21 +63,30 @@ PAIRS = [
("playbook/shopfloor-setup/BIOS/check-bios.cmd", ("playbook/shopfloor-setup/BIOS/check-bios.cmd",
"/srv/samba/winpeapps/_shared/BIOS/check-bios.cmd", GIT_OWNED), "/srv/samba/winpeapps/_shared/BIOS/check-bios.cmd", GIT_OWNED),
# The config/ copy is what startnet stages to C:\Enrollment\site-config.json # The config/ copy is the one startnet actually stages to
# and it has its own edit history - it carried the dead tsgwp00524 host that # C:\Enrollment\site-config.json, so it is the copy every bay reads. It had
# the repo copy never had. Same filename, different lineage. # its own edit history and sat stale since 2026-08-06, which meant bays
# imaged after e844ff3 quietly lost the Plant Apps startup item and the
# Defect_Tracker pin - while the sibling copy under shopfloor-setup/ showed
# perfectly in sync and made the pair look healthy. Reconciled 2026-08-19 by
# deploying the repo copy over it. One source file, two destinations, both
# git-owned now, so a stale one cannot hide behind the other again.
("playbook/shopfloor-setup/site-config.json", ("playbook/shopfloor-setup/site-config.json",
"/srv/samba/enrollment/config/site-config.json", UNRECONCILED), "/srv/samba/enrollment/config/site-config.json", GIT_OWNED),
# The live unattends are the ones that boot machines and they are FAR ahead # All three unattends are reconciled. The live files were ahead of the repo
# of the repo copies (17 KB vs 12 KB). Pushing the repo over them would # and the LIVE side won, because these are what boot machines - pushing the
# regress production. Reconcile before promoting to git-owned. # repo over them is precisely the 2026-08-06 outage.
#
# Engineer has its own repo file. It used to be compared against the
# standard unattend, which is a different answer file, so the pair reported
# DIFFERS permanently - and a light that is always red is one nobody reads.
("playbook/FlatUnattendW10-shopfloor.xml", ("playbook/FlatUnattendW10-shopfloor.xml",
"/srv/samba/winpeapps/gea-shopfloor/Deploy/FlatUnattendW10.xml", UNRECONCILED), "/srv/samba/winpeapps/gea-shopfloor/Deploy/FlatUnattendW10.xml", GIT_OWNED),
("playbook/FlatUnattendW10.xml", ("playbook/FlatUnattendW10.xml",
"/srv/samba/winpeapps/gea-standard/Deploy/FlatUnattendW10.xml", UNRECONCILED), "/srv/samba/winpeapps/gea-standard/Deploy/FlatUnattendW10.xml", GIT_OWNED),
("playbook/FlatUnattendW10.xml", ("playbook/FlatUnattendW10-engineer.xml",
"/srv/samba/winpeapps/gea-engineer/Deploy/FlatUnattendW10.xml", UNRECONCILED), "/srv/samba/winpeapps/gea-engineer/Deploy/FlatUnattendW10.xml", GIT_OWNED),
] ]