From 6e8b8a83a765ede38951729c455a27f77e95ab43 Mon Sep 17 00:00:00 2001 From: cproudlock Date: Wed, 19 Aug 2026 15:41:46 -0400 Subject: [PATCH] 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. --- playbook/FlatUnattendW10-shopfloor.xml | 489 +++++++++++++++---------- scripts/share-drift.py | 31 +- 2 files changed, 308 insertions(+), 212 deletions(-) diff --git a/playbook/FlatUnattendW10-shopfloor.xml b/playbook/FlatUnattendW10-shopfloor.xml index 0445f1d..967826c 100644 --- a/playbook/FlatUnattendW10-shopfloor.xml +++ b/playbook/FlatUnattendW10-shopfloor.xml @@ -1,201 +1,288 @@ - - - - - - - - - W:\Drivers - - - - - - - H%serialnumber% - GE Aerospace - GE - Eastern Standard Time - - - - - 1 - powershell.exe -ExecutionPolicy Bypass -Command "Import-Certificate -FilePath 'C:\Deploy\Applications\GE_External_Root_CA_2_1.cer' -CertStoreLocation 'Cert:\LocalMachine\Root'" - Install External Root Certificate - - - 2 - powershell.exe -ExecutionPolicy Bypass -Command "Import-Certificate -FilePath 'C:\Deploy\Applications\GE_External_Intermediate_CA_2_1.cer' -CertStoreLocation 'Cert:\LocalMachine\CA'" - Install External Intermediate Certificate - - - 3 - powershell.exe -ExecutionPolicy Bypass -Command "Import-Certificate -FilePath 'C:\Deploy\Applications\GE_Enterprise_Root_CA_2_1.cer' -CertStoreLocation 'Cert:\LocalMachine\Root'" - Install Enterprise Root Certificate - - - 4 - powershell.exe -ExecutionPolicy Bypass -Command "Import-Certificate -FilePath 'C:\Deploy\Applications\GE_Enterprise_Device_Issuing_CA_2_1.cer' -CertStoreLocation 'Cert:\LocalMachine\CA'" - Install Enterprise Device Issuing Certificate - - - 5 - powershell.exe -ExecutionPolicy Bypass -Command "Import-Certificate -FilePath 'C:\Deploy\Applications\GE_Enterprise_Server_Issuing_CA_2_1.cer' -CertStoreLocation 'Cert:\LocalMachine\CA'" - Install Enterprise Server Issuing Certificate - - - 6 - powershell.exe -ExecutionPolicy Bypass -Command "Import-Certificate -FilePath 'C:\Deploy\Applications\GE_Enterprise_Smart_Card_Issuing_CA_2_1.cer' -CertStoreLocation 'Cert:\LocalMachine\CA'" - Install Enterprise SmartCard Issuing Certificate - - - 7 - powershell.exe -ExecutionPolicy Bypass -Command "Import-Certificate -FilePath 'C:\Deploy\Applications\GE_Enterprise_User_Issuing_CA_2_1.cer' -CertStoreLocation 'Cert:\LocalMachine\CA'" - Install Enterprise User Issuing Certificate - - - 8 - powershell.exe -ExecutionPolicy Bypass -Command "Import-Certificate -FilePath 'C:\Deploy\Applications\GE_Aerospace_Enterprise_Root_CA_1.cer' -CertStoreLocation 'Cert:\LocalMachine\Root'" - Install Aerospace Enterprise Root Certificate - - - 9 - powershell.exe -ExecutionPolicy Bypass -Command "Import-Certificate -FilePath 'C:\Deploy\Applications\ZscalerCommercialCertificate-2048-SHA256.crt' -CertStoreLocation 'Cert:\LocalMachine\Root'" - Install Zscaler Commercial Certificate - - - reg.exe add "HKLM\System\CurrentControlSet\Control\Network\NewNetworkWindowOff" /f - Disable Network Windows - 10 - - - 11 - netsh wlan add profile filename="C:\Deploy\Applications\extra\wireless\WiFi-Profile.xml" user=all - Install INTERNETACCESS WiFi Profile - - - 12 - powershell.exe -ExecutionPolicy Bypass -Command "Enable-PSRemoting -Force -SkipNetworkProfileCheck" - Enable WinRM - - - 13 - reg.exe add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\OOBE" /v BypassNRO /t REG_DWORD /d 1 /f - Bypass OOBE network requirement - - - 14 - reg.exe add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\OOBE" /v SkipMachineOOBE /t REG_DWORD /d 1 /f - Skip machine OOBE phase - - - 15 - reg.exe add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\OOBE" /v SkipUserOOBE /t REG_DWORD /d 1 /f - Skip user OOBE phase - - - - - - - en-US - en-US - en-US - en-US - - - - true - true - true - true - true - 3 - - - - - - Pa55word - true</PlainText> - </Password> - <Name>SupportUser</Name> - <Group>Administrators</Group> - <DisplayName>SupportUser</DisplayName> - </LocalAccount> - </LocalAccounts> - </UserAccounts> - <AutoLogon> - <Password> - <Value>Pa55word</Value> - <PlainText>true</PlainText> - </Password> - <Enabled>true</Enabled> - <Username>SupportUser</Username> - <LogonCount>12</LogonCount> - </AutoLogon> - <FirstLogonCommands> - <SynchronousCommand wcm:action="add"> - <Order>1</Order> - <CommandLine>cmd.exe /c powercfg /change monitor-timeout-ac 0 &amp; powercfg /change monitor-timeout-dc 0 &amp; powercfg /change standby-timeout-ac 0 &amp; powercfg /change standby-timeout-dc 0</CommandLine> - <Description>Disable display and sleep timeout during setup</Description> - </SynchronousCommand> - <SynchronousCommand wcm:action="add"> - <Order>2</Order> - <CommandLine>powershell.exe -ExecutionPolicy Bypass -Command "Get-NetAdapter -Physical | Where-Object { $_.InterfaceDescription -match 'Wi-Fi|Wireless' } | Set-NetIPInterface -InterfaceMetric 10; Get-NetAdapter -Physical | Where-Object { $_.InterfaceDescription -notmatch 'Wi-Fi|Wireless' } | Set-NetIPInterface -InterfaceMetric 100"</CommandLine> - <Description>Prioritize WiFi over ethernet</Description> - </SynchronousCommand> - <SynchronousCommand wcm:action="add"> - <Order>3</Order> - <CommandLine>powershell.exe -ExecutionPolicy Bypass -Command "Get-NetConnectionProfile | Set-NetConnectionProfile -NetworkCategory Private"</CommandLine> - <Description>Set network profile to Private</Description> - </SynchronousCommand> - <SynchronousCommand wcm:action="add"> - <Order>4</Order> - <CommandLine>powershell.exe -ep Bypass -Command "net use Z: \\172.16.9.1\enrollment /user:pxe-upload pxe; robocopy Z:\shopfloor-setup C:\Enrollment Fetch-StagingPayload.ps1 Verify-And-Heal-Staging.ps1 /R:2 /W:2; robocopy Z:\scripts C:\Enrollment run-enrollment.ps1 wait-for-internet.ps1 migrate-to-wifi.ps1 /R:2 /W:2"</CommandLine> - <Description>Bootstrap self-heal: pull Fetch/Verify-Heal + enrollment scripts from the PXE share so Order 5/6 run after an early WinPE staging failure.</Description> - </SynchronousCommand> - <SynchronousCommand wcm:action="add"> - <Order>5</Order> - <CommandLine>powershell.exe -ExecutionPolicy Bypass -File "C:\Enrollment\Fetch-StagingPayload.ps1"</CommandLine> - <Description>Fetch bulk staging (shopfloor-setup tree + preinstall bundle) from the PXE share on a fresh mount, BEFORE the production-network switch takes the bay off the imaging LAN. Detailed log at C:\Logs\Fetch\.</Description> - </SynchronousCommand> - <SynchronousCommand wcm:action="add"> - <Order>6</Order> - <CommandLine>powershell.exe -ExecutionPolicy Bypass -File "C:\Enrollment\Verify-And-Heal-Staging.ps1"</CommandLine> - <Description>Verify + re-pull any missing imaging payload from the PXE share (CMM/Keyence/WaxTrace bundles + bay backup) on the imaging LAN before the production-network switch. Log C:\Logs\Fetch.</Description> - </SynchronousCommand> - <SynchronousCommand wcm:action="add"> - <Order>7</Order> - <CommandLine>powershell.exe -ExecutionPolicy Bypass -File "C:\Enrollment\wait-for-internet.ps1"</CommandLine> - <Description>Prompt to connect production network then wait for TCP 443 connectivity</Description> - </SynchronousCommand> - <SynchronousCommand wcm:action="add"> - <Order>8</Order> - <CommandLine>powershell.exe -ExecutionPolicy Bypass -File "C:\Enrollment\migrate-to-wifi.ps1"</CommandLine> - <Description>Migrate from wired to WiFi if WiFi adapter present, else stay on wired</Description> - </SynchronousCommand> - <SynchronousCommand wcm:action="add"> - <Order>9</Order> - <CommandLine>msiexec.exe /i "C:\PreInstall\installers\powershell7\PowerShell-7.5.4-win-x64.msi" /qn /norestart ADD_PATH=1 USE_MU=0 ENABLE_MU=0 DISABLE_TELEMETRY=1</CommandLine> - <Description>Install PowerShell 7 BEFORE PPKG so Intune SetupCredentials Win32App finds pwsh.exe (race fix)</Description> - </SynchronousCommand> - <SynchronousCommand wcm:action="add"> - <Order>10</Order> - <CommandLine>powershell.exe -ExecutionPolicy Bypass -File "C:\run-enrollment.ps1"</CommandLine> - <Description>Run GCCH Enrollment</Description> - </SynchronousCommand> - <SynchronousCommand wcm:action="add"> - <Order>11</Order> - <CommandLine>powershell.exe -ExecutionPolicy Bypass -File "C:\Enrollment\Run-ShopfloorSetup.ps1"</CommandLine> - <Description>Run shopfloor PC type setup</Description> - </SynchronousCommand> - </FirstLogonCommands> - <TimeZone>Eastern Standard Time</TimeZone> - </component> - </settings> -</unattend> +<?xml version="1.0"?> +<unattend xmlns="urn:schemas-microsoft-com:unattend"> + <settings pass="windowsPE"> + </settings> + <settings pass="offlineServicing"> + <component name="Microsoft-Windows-PnpCustomizationsNonWinPE" processorArchitecture="*arch*" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" + xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <DriverPaths> + <PathAndCredentials xmlns="" wcm:keyValue="1" action="add"> + <Path>W:\Drivers</Path> + </PathAndCredentials> + </DriverPaths> + </component> + </settings> + <settings pass="specialize"> + <component name="Microsoft-Windows-Shell-Setup" processorArchitecture="*arch*" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State"> + <ComputerName>H%serialnumber%</ComputerName> + <RegisteredOrganization>GE Aerospace</RegisteredOrganization> + <RegisteredOwner>GE</RegisteredOwner> + <TimeZone>Eastern Standard Time</TimeZone> + </component> + <component name="Microsoft-Windows-Deployment" processorArchitecture="*arch*" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State"> + <RunSynchronous> + <RunSynchronousCommand wcm:action="add"> + <Order>1</Order> + <Path>powershell.exe -ExecutionPolicy Bypass -Command "Import-Certificate -FilePath 'C:\Deploy\Applications\GE_External_Root_CA_2_1.cer' -CertStoreLocation 'Cert:\LocalMachine\Root'"</Path> + <Description>Install External Root Certificate</Description> + </RunSynchronousCommand> + <RunSynchronousCommand wcm:action="add"> + <Order>2</Order> + <Path>powershell.exe -ExecutionPolicy Bypass -Command "Import-Certificate -FilePath 'C:\Deploy\Applications\GE_External_Intermediate_CA_2_1.cer' -CertStoreLocation 'Cert:\LocalMachine\CA'"</Path> + <Description>Install External Intermediate Certificate</Description> + </RunSynchronousCommand> + <RunSynchronousCommand wcm:action="add"> + <Order>3</Order> + <Path>powershell.exe -ExecutionPolicy Bypass -Command "Import-Certificate -FilePath 'C:\Deploy\Applications\GE_Enterprise_Root_CA_2_1.cer' -CertStoreLocation 'Cert:\LocalMachine\Root'"</Path> + <Description>Install Enterprise Root Certificate</Description> + </RunSynchronousCommand> + <RunSynchronousCommand wcm:action="add"> + <Order>4</Order> + <Path>powershell.exe -ExecutionPolicy Bypass -Command "Import-Certificate -FilePath 'C:\Deploy\Applications\GE_Enterprise_Device_Issuing_CA_2_1.cer' -CertStoreLocation 'Cert:\LocalMachine\CA'"</Path> + <Description>Install Enterprise Device Issuing Certificate</Description> + </RunSynchronousCommand> + <RunSynchronousCommand wcm:action="add"> + <Order>5</Order> + <Path>powershell.exe -ExecutionPolicy Bypass -Command "Import-Certificate -FilePath 'C:\Deploy\Applications\GE_Enterprise_Server_Issuing_CA_2_1.cer' -CertStoreLocation 'Cert:\LocalMachine\CA'"</Path> + <Description>Install Enterprise Server Issuing Certificate</Description> + </RunSynchronousCommand> + <RunSynchronousCommand wcm:action="add"> + <Order>6</Order> + <Path>powershell.exe -ExecutionPolicy Bypass -Command "Import-Certificate -FilePath 'C:\Deploy\Applications\GE_Enterprise_Smart_Card_Issuing_CA_2_1.cer' -CertStoreLocation 'Cert:\LocalMachine\CA'"</Path> + <Description>Install Enterprise SmartCard Issuing Certificate</Description> + </RunSynchronousCommand> + <RunSynchronousCommand wcm:action="add"> + <Order>7</Order> + <Path>powershell.exe -ExecutionPolicy Bypass -Command "Import-Certificate -FilePath 'C:\Deploy\Applications\GE_Enterprise_User_Issuing_CA_2_1.cer' -CertStoreLocation 'Cert:\LocalMachine\CA'"</Path> + <Description>Install Enterprise User Issuing Certificate</Description> + </RunSynchronousCommand> + <RunSynchronousCommand wcm:action="add"> + <Order>8</Order> + <Path>powershell.exe -ExecutionPolicy Bypass -Command "Import-Certificate -FilePath 'C:\Deploy\Applications\GE_Aerospace_Enterprise_Root_CA_1.cer' -CertStoreLocation 'Cert:\LocalMachine\Root'"</Path> + <Description>Install Aerospace Enterprise Root Certificate</Description> + </RunSynchronousCommand> + <RunSynchronousCommand wcm:action="add"> + <Order>9</Order> + <Path>powershell.exe -ExecutionPolicy Bypass -Command "Import-Certificate -FilePath 'C:\Deploy\Applications\ZscalerCommercialCertificate-2048-SHA256.crt' -CertStoreLocation 'Cert:\LocalMachine\Root'"</Path> + <Description>Install Zscaler Commercial Certificate</Description> + </RunSynchronousCommand> + <RunSynchronousCommand wcm:action="add"> + <Path>reg.exe add "HKLM\System\CurrentControlSet\Control\Network\NewNetworkWindowOff" /f </Path> + <Description>Disable Network Windows</Description> + <Order>10</Order> + </RunSynchronousCommand> + <RunSynchronousCommand wcm:action="add"> + <Order>11</Order> + <Path>netsh wlan add profile filename="C:\Deploy\Applications\extra\wireless\WiFi-Profile.xml" user=all</Path> + <Description>Install INTERNETACCESS WiFi Profile</Description> + </RunSynchronousCommand> + <RunSynchronousCommand wcm:action="add"> + <Order>12</Order> + <Path>powershell.exe -ExecutionPolicy Bypass -Command "Enable-PSRemoting -Force -SkipNetworkProfileCheck"</Path> + <Description>Enable WinRM</Description> + </RunSynchronousCommand> + <RunSynchronousCommand wcm:action="add"> + <Order>13</Order> + <Path>reg.exe add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\OOBE" /v BypassNRO /t REG_DWORD /d 1 /f</Path> + <Description>Bypass OOBE network requirement</Description> + </RunSynchronousCommand> + <RunSynchronousCommand wcm:action="add"> + <Order>14</Order> + <Path>reg.exe add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\OOBE" /v SkipMachineOOBE /t REG_DWORD /d 1 /f</Path> + <Description>Skip machine OOBE phase</Description> + </RunSynchronousCommand> + <RunSynchronousCommand wcm:action="add"> + <Order>15</Order> + <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> + </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> + </component> + </settings> + <settings pass="oobeSystem"> + <component name="Microsoft-Windows-International-Core" processorArchitecture="*arch*" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State"> + <InputLocale>en-US</InputLocale> + <SystemLocale>en-US</SystemLocale> + <UILanguage>en-US</UILanguage> + <UserLocale>en-US</UserLocale> + </component> + <component name="Microsoft-Windows-Shell-Setup" processorArchitecture="*arch*" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State"> + <OOBE> + <HideEULAPage>true</HideEULAPage> + <HideLocalAccountScreen>true</HideLocalAccountScreen> + <HideOEMRegistrationScreen>true</HideOEMRegistrationScreen> + <HideOnlineAccountScreens>true</HideOnlineAccountScreens> + <HideWirelessSetupInOOBE>true</HideWirelessSetupInOOBE> + <ProtectYourPC>3</ProtectYourPC> + </OOBE> + <UserAccounts> + <LocalAccounts> + <LocalAccount wcm:action="add"> + <Password> + <Value>Pa55word</Value> + <PlainText>true</PlainText> + </Password> + <Name>SupportUser</Name> + <Group>Administrators</Group> + <DisplayName>SupportUser</DisplayName> + </LocalAccount> + </LocalAccounts> + </UserAccounts> + <AutoLogon> + <Password> + <Value>Pa55word</Value> + <PlainText>true</PlainText> + </Password> + <Enabled>true</Enabled> + <Username>SupportUser</Username> + <LogonCount>12</LogonCount> + </AutoLogon> + <FirstLogonCommands> + <SynchronousCommand wcm:action="add"> + <Order>1</Order> + <CommandLine>cmd.exe /c powercfg /change monitor-timeout-ac 0 &amp; powercfg /change monitor-timeout-dc 0 &amp; powercfg /change standby-timeout-ac 0 &amp; powercfg /change standby-timeout-dc 0</CommandLine> + <Description>Disable display and sleep timeout during setup</Description> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <Order>2</Order> + <CommandLine>powershell.exe -ExecutionPolicy Bypass -Command "Get-NetAdapter -Physical | Where-Object { $_.InterfaceDescription -match 'Wi-Fi|Wireless' } | Set-NetIPInterface -InterfaceMetric 10; Get-NetAdapter -Physical | Where-Object { $_.InterfaceDescription -notmatch 'Wi-Fi|Wireless' } | Set-NetIPInterface -InterfaceMetric 100"</CommandLine> + <Description>Prioritize WiFi over ethernet</Description> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <Order>3</Order> + <CommandLine>powershell.exe -ExecutionPolicy Bypass -Command "Get-NetConnectionProfile | Set-NetConnectionProfile -NetworkCategory Private"</CommandLine> + <Description>Set network profile to Private</Description> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <Order>4</Order> + <CommandLine>powershell.exe -ep Bypass -Command "net use Z: \\172.16.9.1\enrollment /user:pxe-upload pxe; robocopy Z:\shopfloor-setup C:\Enrollment Fetch-StagingPayload.ps1 Verify-And-Heal-Staging.ps1 /R:2 /W:2; robocopy Z:\scripts C:\Enrollment run-enrollment.ps1 wait-for-internet.ps1 migrate-to-wifi.ps1 /R:2 /W:2"</CommandLine> + <Description>Bootstrap self-heal: pull Fetch/Verify-Heal + enrollment scripts from the PXE share so Order 5/6 run after an early WinPE staging failure.</Description> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <Order>5</Order> + <CommandLine>powershell.exe -ExecutionPolicy Bypass -File "C:\Enrollment\Fetch-StagingPayload.ps1"</CommandLine> + <Description>Fetch bulk staging (shopfloor-setup tree + preinstall bundle) from the PXE share on a fresh mount, BEFORE the production-network switch takes the bay off the imaging LAN. Detailed log at C:\Logs\Fetch\.</Description> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <Order>6</Order> + <CommandLine>powershell.exe -ExecutionPolicy Bypass -File "C:\Enrollment\Verify-And-Heal-Staging.ps1"</CommandLine> + <Description>Verify + re-pull any missing imaging payload from the PXE share (CMM/Keyence/WaxTrace bundles + bay backup) on the imaging LAN before the production-network switch. Log C:\Logs\Fetch.</Description> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <Order>7</Order> + <CommandLine>powershell.exe -ExecutionPolicy Bypass -File "C:\Enrollment\wait-for-internet.ps1"</CommandLine> + <Description>Prompt to connect production network then wait for TCP 443 connectivity</Description> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <Order>8</Order> + <CommandLine>powershell.exe -ExecutionPolicy Bypass -File "C:\Enrollment\migrate-to-wifi.ps1"</CommandLine> + <Description>Migrate from wired to WiFi if WiFi adapter present, else stay on wired</Description> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <Order>9</Order> + <CommandLine>msiexec.exe /i "C:\PreInstall\installers\powershell7\PowerShell-7.5.4-win-x64.msi" /qn /norestart ADD_PATH=1 USE_MU=0 ENABLE_MU=0 DISABLE_TELEMETRY=1</CommandLine> + <Description>Install PowerShell 7 BEFORE PPKG so Intune SetupCredentials Win32App finds pwsh.exe (race fix)</Description> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <Order>10</Order> + <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> + </SynchronousCommand> + <SynchronousCommand wcm:action="add"> + <Order>11</Order> + <CommandLine>powershell.exe -ExecutionPolicy Bypass -File "C:\Enrollment\Run-ShopfloorSetup.ps1"</CommandLine> + <Description>Run shopfloor PC type setup</Description> + </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> + <TimeZone>Eastern Standard Time</TimeZone> + </component> + </settings> +</unattend> diff --git a/scripts/share-drift.py b/scripts/share-drift.py index f746a88..dfdfb84 100755 --- a/scripts/share-drift.py +++ b/scripts/share-drift.py @@ -63,21 +63,30 @@ PAIRS = [ ("playbook/shopfloor-setup/BIOS/check-bios.cmd", "/srv/samba/winpeapps/_shared/BIOS/check-bios.cmd", GIT_OWNED), - # The config/ copy is what startnet stages to C:\Enrollment\site-config.json - # and it has its own edit history - it carried the dead tsgwp00524 host that - # the repo copy never had. Same filename, different lineage. + # The config/ copy is the one startnet actually stages to + # C:\Enrollment\site-config.json, so it is the copy every bay reads. It had + # 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", - "/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 - # of the repo copies (17 KB vs 12 KB). Pushing the repo over them would - # regress production. Reconcile before promoting to git-owned. + # All three unattends are reconciled. The live files were ahead of the repo + # and the LIVE side won, because these are what boot machines - pushing the + # 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", - "/srv/samba/winpeapps/gea-shopfloor/Deploy/FlatUnattendW10.xml", UNRECONCILED), + "/srv/samba/winpeapps/gea-shopfloor/Deploy/FlatUnattendW10.xml", GIT_OWNED), ("playbook/FlatUnattendW10.xml", - "/srv/samba/winpeapps/gea-standard/Deploy/FlatUnattendW10.xml", UNRECONCILED), - ("playbook/FlatUnattendW10.xml", - "/srv/samba/winpeapps/gea-engineer/Deploy/FlatUnattendW10.xml", UNRECONCILED), + "/srv/samba/winpeapps/gea-standard/Deploy/FlatUnattendW10.xml", GIT_OWNED), + ("playbook/FlatUnattendW10-engineer.xml", + "/srv/samba/winpeapps/gea-engineer/Deploy/FlatUnattendW10.xml", GIT_OWNED), ]