diff --git a/playbook/shopfloor-setup/Run-ShopfloorSetup.ps1 b/playbook/shopfloor-setup/Run-ShopfloorSetup.ps1 index c8df766..fee2da9 100644 --- a/playbook/shopfloor-setup/Run-ShopfloorSetup.ps1 +++ b/playbook/shopfloor-setup/Run-ShopfloorSetup.ps1 @@ -360,6 +360,26 @@ if ($noEnforceTypes -contains $pcType) { Write-Host "Register-MapSfldShare.ps1 not found (optional) - skipping" } +# --- Check Machine Number logon prompt --- +# Auto-register the "Check Machine Number" scheduled task. Bays imaged with +# the 9999 placeholder will prompt the first ShopFloor end-user logon to +# enter the real machine number; on success Update-MachineNumber.ps1 pulls +# the per-machine NTLARS .reg + UDC settings JSON + UDC data backup from +# SFLD and the task self-unregisters. Self-disables once the number is +# real, so safe to always register here. +# Skipped for self-contained types (Display) that have no machine number. +$registerCheckMN = Join-Path $setupDir 'Shopfloor\Register-CheckMachineNumberTask.ps1' +if ($noEnforceTypes -contains $pcType) { + Write-Host "" + Write-Host "=== Skipping Check Machine Number task ($pcType has no machine number) ===" +} elseif (Test-Path -LiteralPath $registerCheckMN) { + Write-Host "" + Write-Host "=== Registering Check Machine Number logon task ===" + try { & $registerCheckMN } catch { Write-Warning "Check-MachineNumber registration failed: $_" } +} else { + Write-Host "Register-CheckMachineNumberTask.ps1 not found (optional) - skipping" +} + # --- Run enrollment (PPKG install) --- # Enrollment is the LAST thing we do. Install-ProvisioningPackage triggers # an immediate reboot -- everything after this call is unlikely to execute. diff --git a/playbook/shopfloor-setup/Shopfloor/Register-CheckMachineNumberTask.ps1 b/playbook/shopfloor-setup/Shopfloor/Register-CheckMachineNumberTask.ps1 new file mode 100644 index 0000000..146fc7e --- /dev/null +++ b/playbook/shopfloor-setup/Shopfloor/Register-CheckMachineNumberTask.ps1 @@ -0,0 +1,105 @@ +# Register-CheckMachineNumberTask.ps1 - Register the "Check Machine Number" +# logon scheduled task at imaging time. Mirrors Register-MapSfldShare.ps1. +# +# The task fires at every interactive logon for BUILTIN\Users (so the +# ShopFloor end-user, who is the auto-logon principal post-lockdown, +# triggers it). Check-MachineNumber.ps1 reads the current UDC + eDNC +# machine numbers, and: +# - If neither is 9999, unregisters the task and exits (one-shot). +# - If either is 9999, pops an InputBox forcing the user to type the +# real number; on success calls Update-MachineNumber.ps1 which pulls +# the per-machine NTLARS .reg + UDC settings JSON + UDC data backup +# from the SFLD share and applies them. +# +# Idempotent: safe to re-run. Existing task is overwritten. + +$ErrorActionPreference = 'Continue' + +$logDir = 'C:\Logs\SFLD' +if (-not (Test-Path $logDir)) { New-Item -Path $logDir -ItemType Directory -Force | Out-Null } +$logFile = Join-Path $logDir 'register-checkmn.log' + +function Write-RegLog { + param([string]$Message) + $line = '[{0}] [INFO] {1}' -f (Get-Date -Format 'yyyy-MM-dd HH:mm:ss'), $Message + Add-Content -Path $logFile -Value $line -ErrorAction SilentlyContinue + Write-Host $line +} + +Write-RegLog '=== Register-CheckMachineNumberTask start ===' + +$taskName = 'Check Machine Number' + +# Only arm the task if the bay was imaged with the 9999 placeholder. If +# the tech entered a real machine number during PXE imaging it's already +# in C:\Enrollment\machine-number.txt; no prompt needed on first logon. +$mnFile = 'C:\Enrollment\machine-number.txt' +$mnAtImaging = '9999' +if (Test-Path -LiteralPath $mnFile) { + $raw = (Get-Content -LiteralPath $mnFile -First 1 -ErrorAction SilentlyContinue) + if ($raw) { $mnAtImaging = $raw.Trim() } +} +Write-RegLog "Imaging-time machine-number.txt = '$mnAtImaging'" +if ($mnAtImaging -ne '9999') { + Write-RegLog "Machine number is real ('$mnAtImaging' != 9999). Not registering task." + # Clean up any stale task from a prior 9999-imaging cycle on the same disk. + try { + if (Get-ScheduledTask -TaskName $taskName -ErrorAction SilentlyContinue) { + Unregister-ScheduledTask -TaskName $taskName -Confirm:$false -ErrorAction Stop + Write-RegLog "Unregistered stale task '$taskName'" + } + } catch {} + Write-RegLog '=== Register-CheckMachineNumberTask end (no-op) ===' + exit 0 +} + +# Resolve the script path. Prefer the staged shopfloor-setup tree on C: +# (where Run-ShopfloorSetup ran from); fall back to the same dir as this +# Register script if invoked standalone. +$checkScript = Join-Path $PSScriptRoot 'Check-MachineNumber.ps1' +if (-not (Test-Path -LiteralPath $checkScript)) { + $checkScript = 'C:\Enrollment\shopfloor-setup\Shopfloor\Check-MachineNumber.ps1' +} +if (-not (Test-Path -LiteralPath $checkScript)) { + Write-RegLog "Check-MachineNumber.ps1 not found at $checkScript - cannot register" + exit 1 +} +Write-RegLog "Check-MachineNumber.ps1 at: $checkScript" + +try { + $action = New-ScheduledTaskAction ` + -Execute 'powershell.exe' ` + -Argument "-NoProfile -ExecutionPolicy Bypass -WindowStyle Normal -File `"$checkScript`"" + + $trigger = New-ScheduledTaskTrigger -AtLogOn + + # Run as the logged-in user (needs GUI for InputBox), NOT SYSTEM. + # Group SID S-1-5-32-545 = BUILTIN\Users; catches ShopFloor + any + # support / admin user that logs in interactively. + $principal = New-ScheduledTaskPrincipal ` + -GroupId 'S-1-5-32-545' ` + -RunLevel Limited + + $settings = New-ScheduledTaskSettingsSet ` + -AllowStartIfOnBatteries ` + -DontStopIfGoingOnBatteries ` + -StartWhenAvailable ` + -ExecutionTimeLimit (New-TimeSpan -Minutes 5) + + Register-ScheduledTask ` + -TaskName $taskName ` + -Action $action ` + -Trigger $trigger ` + -Principal $principal ` + -Settings $settings ` + -Force ` + -ErrorAction Stop | Out-Null + + Write-RegLog "Registered scheduled task '$taskName' (AtLogOn, BUILTIN\Users, Limited)" +} catch { + Write-RegLog "FAILED to register '$taskName': $_" + exit 1 +} + +Write-RegLog '=== Register-CheckMachineNumberTask end ===' +exit 0