Files
pxe-server/playbook/shopfloor-setup/Shopfloor/Invoke-PostPpkg.ps1
cproudlock fa79f76951 Share accounts: per-site Samba passwords from the webapp
Tools > Share accounts sets the pxe-upload, blancco and clonezilla Samba
passwords. Saving one runs smbpasswd and writes it everywhere it is used:
startnet.cmd in boot.wim (pxe-upload), the served Blancco preferences and
the live config.img (blancco), the iPXE menu's Clonezilla entries
(clonezilla). Refused while a PC is imaging unless forced. Stored 0600 in
UPDATES_DIR/shares/accounts.json, never shown back.

- The stored values are the authority: the playbook only creates the
  Samba accounts, seeds the store from site-vars (pxe_upload_password,
  blancco_smb_password, clonezilla_smb_password) for accounts it does not
  hold, and runs "share_accounts apply" at the end of every run.
- Every startnet save re-pins SHAREPASS, so a restored snapshot cannot
  bring an old password back; new menu blocks use %SHAREUSER%/%SHAREPASS%.
- Shop floor unattend Order 4 reads the login from fetch-source.txt;
  Invoke-PostPpkg deletes that file once the PPKG is applied.
- Upload-Image.ps1 asks for the password unless -Pass is given.
- pxe_admin_password: the Linux pxe login. Required while the box still
  has the shipped "pxe"; set with chpasswd when it differs.
- Blancco site settings now also reach the live config.img (BIOS path).
2026-10-17 12:29:06 -04:00

102 lines
4.8 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.
# Also, once the PPKG is applied, delete C:\Enrollment\fetch-source.txt (the
# pxe-upload share login startnet leaves for the first-logon scripts).
# 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)."
}
}
# 1b. fetch-source.txt holds the pxe-upload share password (startnet writes
# it for the first-logon Fetch/Verify scripts). Once the PPKG has run the
# PC is off the imaging LAN and the file has no use left.
$fetchSource = 'C:\Enrollment\fetch-source.txt'
if ((Test-Path -LiteralPath $appliedMarker) -and (Test-Path -LiteralPath $fetchSource)) {
try {
Remove-Item -LiteralPath $fetchSource -Force -ErrorAction Stop
Write-Host "Removed $fetchSource (share login)."
} catch {
Write-Warning "Could not remove ${fetchSource}: $_"
}
}
# 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