Everything West Jefferson specific moved out to a separate repo (pxe-site-wj): NTLARS/UDC/heat-treat backups keyed by WJ machine numbers, CMM and Wax/Trace bay lists, WJ OpenText profiles, site-config.json, the WJ preinstall list, and the WJ shopfloor PC types (Collections, NoCollections, Common, Keyence, CMM, Genspect, HeatTreat, Wax/Trace, Display, PartMarker) with GE-Enforce, machine numbers and the desktop layout. The part-marker bench tools moved to their own repo. Dead scripts removed: build-proxmox-iso, deploy-bios, sync_hardware_models, mirror-from-gold, pull-bios, startnet-template.cmd. Shopfloor is one generic type, gea-shopfloor-standard, with today's timing: - PPKG at first logon (unattend Order 10, unchanged). - Install-AppList.ps1 runs C:\PreInstall\preinstall.json during setup. - A new SYSTEM task, GE Shopfloor Post-PPKG, runs postppkg.json once after the post-PPKG reboot. It also clears AutoLogonCount after the ShopFloor handover (the Users-level monitor can be denied that HKLM write) and removes the Intune Sync task when done. - Both lists ship empty. A site adds entries and installers. - WinPE choice 3 goes straight to the PPKG menu. Staging, fetch and heal carry only the generic payload. The webapp's shopfloor sub-menu editor is gone, and the imaging tiles name the new stages. - The playbook deploys the empty lists only if missing. It now deploys the PowerShell 7 MSI the shopfloor unattend installs, which it never did before. Blancco site settings move into the webapp (Updates > Blancco releases): business location, licensing Wi-Fi SSID and password. They are rendered into the served preferences.xml and applied to every staged release, and are seeded from site-vars (site_name, blancco_wifi_ssid, blancco_wifi_password) only while none exist. The repo XML carries no site values; the plaintext Wi-Fi password is gone from it. New site_name and site_timezone settings: report and evidence-pack site name, server clock and webapp time zone. No more West Jefferson defaults in webapp/config.py or the dashboard title. Sync-BPRT.ps1 gets the server address filled in at download instead of WJ's GE address. USB on Windows: - scripts/Build-PxeUsb.ps1 runs the same checks as build-usb.sh. It writes one FAT32 CIDATA partition (ISO files plus patched grub.cfg plus payload) with diskpart and reads every file back by SHA-256. - Tested with Windows PowerShell 5.1 in the win11 VM, and the layout installs and first-boots in the pxetest VM. - scripts/stage-usb-share.sh stages the build folder on a share. - site-content/ is optional for both builders. KB docs/kb/How_To_Deploy_PXE_Server_New_Site.html: new-site deployment, Windows only, with a site-vars.yml guide. Checks: webapp tests pass (5 suites); the unattend lint and playbook syntax checks pass; every .ps1 parses; there are no WJ hosts, IPs, names or PC types in playbook/, webapp/, scripts/ or autoinstall/.
87 lines
4.1 KiB
PowerShell
87 lines
4.1 KiB
PowerShell
# Invoke-PostPpkg.ps1 - run by the "GE Shopfloor Post-PPKG" task (SYSTEM,
|
|
# at startup and logon). Three jobs, each done once:
|
|
#
|
|
# 1. Install the site's post-PPKG app list, C:\PreInstall\postppkg.json
|
|
# (Install-AppList.ps1; empty in the generic build). Only once the PPKG
|
|
# has been applied (C:\Enrollment\.ppkg-applied, written by
|
|
# run-enrollment.ps1), i.e. on the boot after the PPKG reboot.
|
|
# Done marker: C:\Enrollment\postppkg-done.txt
|
|
# 2. After the ShopFloor handover (Winlogon DefaultUserName ShopFloor*),
|
|
# delete the imaging AutoLogonCount. Left in place, ShopFloor inherits
|
|
# it and Windows turns autologon off when it reaches 0: the bay stops at
|
|
# a ShopFloor password prompt a few reboots later. The monitor tries the
|
|
# same, but it runs as Users and the HKLM write can be denied.
|
|
# 3. Once Monitor-IntuneProgress has written C:\Enrollment\sync-complete.txt,
|
|
# remove the "Shopfloor Intune Sync" logon task.
|
|
# When all three are done the task unregisters itself.
|
|
#
|
|
# Never throws: every step logs and the script exits 0.
|
|
|
|
$ErrorActionPreference = 'Continue'
|
|
$logDir = 'C:\Logs\SFLD'
|
|
New-Item -Path $logDir -ItemType Directory -Force -ErrorAction SilentlyContinue | Out-Null
|
|
try { Start-Transcript -Path (Join-Path $logDir 'postppkg.log') -Append -Force | Out-Null } catch {}
|
|
|
|
$appliedMarker = 'C:\Enrollment\.ppkg-applied'
|
|
$doneMarker = 'C:\Enrollment\postppkg-done.txt'
|
|
$syncComplete = 'C:\Enrollment\sync-complete.txt'
|
|
$listPath = 'C:\PreInstall\postppkg.json'
|
|
$taskName = 'GE Shopfloor Post-PPKG'
|
|
$syncTask = 'Shopfloor Intune Sync'
|
|
|
|
Write-Host "=== Invoke-PostPpkg $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') ==="
|
|
|
|
# 1. post-PPKG app list
|
|
if (Test-Path -LiteralPath $doneMarker) {
|
|
Write-Host "Post-PPKG list already done ($(Get-Content $doneMarker -First 1))."
|
|
} elseif (-not (Test-Path -LiteralPath $appliedMarker)) {
|
|
Write-Host "PPKG not applied yet ($appliedMarker missing) - waiting for the next boot."
|
|
} else {
|
|
$runner = Join-Path $PSScriptRoot 'Install-AppList.ps1'
|
|
if (Test-Path -LiteralPath $runner) {
|
|
try { & $runner -ListPath $listPath -Phase 'PostPpkg' } catch { Write-Warning "Install-AppList failed: $_" }
|
|
Set-Content -Path $doneMarker -Value (Get-Date -Format 'yyyy-MM-dd HH:mm:ss') -ErrorAction SilentlyContinue
|
|
Write-Host "Post-PPKG list done (log: C:\Logs\PostPpkg\install.log)."
|
|
} else {
|
|
Write-Warning "Install-AppList.ps1 not found next to this script ($runner)."
|
|
}
|
|
}
|
|
|
|
# 2. AutoLogonCount after the ShopFloor handover
|
|
$handedOver = $false
|
|
$countGone = $true
|
|
try {
|
|
$wlKey = 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon'
|
|
$wl = Get-ItemProperty $wlKey -ErrorAction Stop
|
|
$handedOver = ($wl.DefaultUserName -like 'ShopFloor*')
|
|
if ($handedOver -and $null -ne $wl.AutoLogonCount) {
|
|
Remove-ItemProperty $wlKey -Name AutoLogonCount -ErrorAction Stop
|
|
Write-Host "Removed leftover AutoLogonCount ($($wl.AutoLogonCount)) after the ShopFloor handover."
|
|
}
|
|
$countGone = ($null -eq (Get-ItemProperty $wlKey -ErrorAction Stop).AutoLogonCount)
|
|
} catch {
|
|
Write-Warning "AutoLogonCount check failed: $_"
|
|
$countGone = $false
|
|
}
|
|
|
|
# 3. the monitor's logon task, once it has finished
|
|
$syncDone = Test-Path -LiteralPath $syncComplete
|
|
if ($syncDone -and (Get-ScheduledTask -TaskName $syncTask -ErrorAction SilentlyContinue)) {
|
|
try {
|
|
Unregister-ScheduledTask -TaskName $syncTask -Confirm:$false -ErrorAction Stop
|
|
Write-Host "Removed the '$syncTask' task (sync-complete.txt present)."
|
|
} catch {
|
|
Write-Warning "Could not remove '$syncTask': $_"
|
|
}
|
|
}
|
|
|
|
if ((Test-Path -LiteralPath $doneMarker) -and $handedOver -and $countGone -and $syncDone) {
|
|
Write-Host "All done - unregistering '$taskName'."
|
|
try { Unregister-ScheduledTask -TaskName $taskName -Confirm:$false -ErrorAction Stop } catch { Write-Warning "Could not unregister: $_" }
|
|
} else {
|
|
Write-Host ("Still to do: list={0} handover={1} autologoncount_cleared={2} sync_complete={3}" -f `
|
|
(Test-Path -LiteralPath $doneMarker), $handedOver, $countGone, $syncDone)
|
|
}
|
|
try { Stop-Transcript | Out-Null } catch {}
|
|
exit 0
|