diff --git a/playbook/shopfloor-setup/Run-ShopfloorSetup.ps1 b/playbook/shopfloor-setup/Run-ShopfloorSetup.ps1 index d380230..ded9c26 100644 --- a/playbook/shopfloor-setup/Run-ShopfloorSetup.ps1 +++ b/playbook/shopfloor-setup/Run-ShopfloorSetup.ps1 @@ -165,7 +165,7 @@ foreach ($name in $runAfterTypeSpecific) { Write-Host "Shopfloor setup complete for $pcType." # --- Copy utility scripts to SupportUser desktop --- -foreach ($tool in @('sync_intune.bat', 'Configure-PC.bat')) { +foreach ($tool in @('sync_intune.bat', 'Configure-PC.bat', 'Force-Lockdown.bat')) { $src = Join-Path $setupDir "Shopfloor\$tool" if (Test-Path $src) { Copy-Item -Path $src -Destination "C:\Users\SupportUser\Desktop\$tool" -Force @@ -254,6 +254,19 @@ if (Test-Path -LiteralPath $registerAcrobat) { Write-Host "Register-AcrobatEnforce.ps1 not found (optional) - skipping" } +# Map S: drive on user logon for every account in BUILTIN\Users. The +# vendor 'SFLD - Consume Credentials' task is principal-restricted and +# does not fire for the ShopFloor end-user, so this parallel task fills +# the gap. Cross-PC-type because every shopfloor account needs S:. +$registerMapShare = Join-Path $PSScriptRoot 'Shopfloor\Register-MapSfldShare.ps1' +if (Test-Path -LiteralPath $registerMapShare) { + Write-Host "" + Write-Host "=== Registering S: drive logon mapper ===" + try { & $registerMapShare } catch { Write-Warning "Map-SfldShare registration failed: $_" } +} else { + Write-Host "Register-MapSfldShare.ps1 not found (optional) - skipping" +} + # Standard-Machine gets a machine-apps enforcer (UDC, eDNC, NTLARS) that # replaced the Intune DSC path (DSC has no sub-type awareness and was # pushing these to Timeclocks). Timeclocks skip this registration. diff --git a/playbook/shopfloor-setup/Shopfloor/Force-Lockdown.bat b/playbook/shopfloor-setup/Shopfloor/Force-Lockdown.bat new file mode 100644 index 0000000..8671c15 --- /dev/null +++ b/playbook/shopfloor-setup/Shopfloor/Force-Lockdown.bat @@ -0,0 +1,69 @@ +@echo off +REM Force-Lockdown.bat - Manual SFLD lockdown trigger for SupportUser. +REM +REM Vendor-documented escape hatch: if the Intune-pushed Lockdown +REM configuration hasn't actually applied within ~30 minutes after the +REM device was added to the Lockdown group, run sfld_autologon.ps1 +REM directly as admin to force it. +REM +REM This wrapper exists so the tech doesn't have to remember the path +REM or open an elevated cmd by hand. It self-elevates to admin via UAC. + +REM ---- Self-elevate --------------------------------------------------- +net session >nul 2>&1 +if %errorLevel% neq 0 ( + echo Requesting admin rights... + powershell -Command "Start-Process '%~f0' -Verb RunAs" + exit /b +) + +setlocal +set "SCRIPT=C:\Program Files\Sysinternals\sfld_autologon.ps1" + +echo ============================================================ +echo Force SFLD Lockdown +echo ============================================================ +echo. +echo *** WARNING *** +echo. +echo Do NOT run this script unless an ARTS request has already +echo been submitted and approved for this device. +echo. +echo Forcing lockdown without an ARTS request bypasses the +echo normal Intune Lockdown-group push and will be flagged +echo in the audit trail. +echo. +echo ============================================================ +echo Target: %SCRIPT% +echo. + +set /p CONFIRM=Type YES (uppercase) to confirm ARTS request is in place: +if /i not "%CONFIRM%"=="YES" ( + echo. + echo Cancelled - no action taken. + echo. + pause + exit /b 2 +) +echo. + +if not exist "%SCRIPT%" ( + echo ERROR: %SCRIPT% not found. + echo Sysinternals Autologon PPKG step may not have completed yet. + echo. + pause + exit /b 1 +) + +echo Running sfld_autologon.ps1 ... +echo. +PowerShell.exe -NoProfile -ExecutionPolicy Bypass -File "%SCRIPT%" +set RC=%errorLevel% + +echo. +echo ============================================================ +echo Lockdown script exit code: %RC% +echo ============================================================ +echo. +pause +endlocal diff --git a/playbook/shopfloor-setup/Shopfloor/Register-MapSfldShare.ps1 b/playbook/shopfloor-setup/Shopfloor/Register-MapSfldShare.ps1 new file mode 100644 index 0000000..03894cf --- /dev/null +++ b/playbook/shopfloor-setup/Shopfloor/Register-MapSfldShare.ps1 @@ -0,0 +1,76 @@ +# Register-MapSfldShare.ps1 - Register a parallel logon task that runs +# the SFLD vendor's ConsumeCredentials.ps1 for ANY user in BUILTIN\Users. +# +# Why: the vendor's own 'SFLD - Consume Credentials' scheduled task is +# registered with a principal that excludes ShopFloor (admin/specific- +# user only), so when ShopFloor logs in, ConsumeCredentials never fires +# for that session and S: drive is never mapped (drive mappings are +# per-user-session, so SupportUser's mapping doesn't carry over). +# +# We don't reimplement the mapping logic - the vendor script at +# C:\ProgramData\SFLD\CredentialManager\ConsumeCredentials.ps1 already +# reads HKLM creds and runs net use when DriveLetter/ShareName are +# populated. We just register a second task with a wider principal +# (BUILTIN\Users + Limited) so the vendor script ALSO fires for the +# end-user logon. +# +# Trade-off: the vendor script's New-StoredCredential -Persist LocalMachine +# step requires admin to write Cred Manager. ShopFloor (Limited) will see +# that part throw, but the script catches per-cred and the net use step +# still runs and lands the drive in ShopFloor's session. + +$ErrorActionPreference = 'Continue' + +$logDir = 'C:\Logs\SFLD' +$logFile = Join-Path $logDir 'register-mapshare.log' +if (-not (Test-Path $logDir)) { New-Item -Path $logDir -ItemType Directory -Force | Out-Null } + +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-MapSfldShare start ===' + +$vendorScript = 'C:\ProgramData\SFLD\CredentialManager\ConsumeCredentials.ps1' + +try { + $action = New-ScheduledTaskAction ` + -Execute 'powershell.exe' ` + -Argument "-NoProfile -ExecutionPolicy Bypass -File `"$vendorScript`"" + + $trigger = New-ScheduledTaskTrigger -AtLogOn + + # BUILTIN\Users + Limited: any logged-in user triggers it; action + # runs in that user's session so net use lands the drive in the + # right place. + $principal = New-ScheduledTaskPrincipal -GroupId 'S-1-5-32-545' -RunLevel Limited + + $settings = New-ScheduledTaskSettingsSet ` + -AllowStartIfOnBatteries ` + -DontStopIfGoingOnBatteries ` + -StartWhenAvailable ` + -ExecutionTimeLimit (New-TimeSpan -Minutes 5) + + Write-RegLog "Registering 'GE Shopfloor Map S: Drive' (logon trigger, BUILTIN\Users -> $vendorScript)" + + Register-ScheduledTask ` + -TaskName 'GE Shopfloor Map S: Drive' ` + -Action $action ` + -Trigger $trigger ` + -Principal $principal ` + -Settings $settings ` + -Force ` + -Description 'Run vendor ConsumeCredentials.ps1 on any user logon (parallel to the principal-restricted SFLD-owned task) so ShopFloor and other end-user accounts get S: mapped' ` + -ErrorAction Stop | Out-Null + + Write-RegLog 'Scheduled task registered' +} catch { + Write-RegLog "FAILED to register task: $_" + exit 1 +} + +Write-RegLog '=== Register-MapSfldShare end ===' +exit 0