Replaces the 3-step pass/fail polling that lived in the .bat with a
PowerShell monitor that renders a full status table for the SFLD
enrollment lifecycle and handles the pre-reboot -> reboot -> post-reboot
transition explicitly.
Three structural problems with the old script:
1. Step 3 ("SFLD - Consume Credentials task exists") fired too early.
The task is created by SetupCredentials.log around 08:52 in the
pre-reboot phase, NOT post-reboot, so passing all 3 gates didn't
actually mean "fully done" - it just meant "credential setup ran".
2. No detection of the pre-reboot -> reboot -> post-reboot transition.
The script never read DSCDeployment.log, so it couldn't tell the
user "you need to reboot now to start the install phase". A device
stuck waiting for reboot was indistinguishable from one still
syncing.
3. No visibility into Phase 4 (per-script wrappers like Install-eDNC,
Install-UDC, Install-VCRedists, Install-OpenText). When something
hung you had to manually grep C:\Logs\SFLD\.
New layout:
sync_intune.bat - thin launcher (~50 lines): self-elevate, invoke
Monitor-IntuneProgress.ps1, branch on exit code
(0 = done / 2 = reboot needed / else = error).
Monitor-IntuneProgress.ps1 - the actual monitor (~340 lines):
- 5-phase status table (Identity / SFLD config / DSC deployment +
install / Custom scripts / Final) updated every 30s via Clear-
Host + redraw, with the QR code anchored at the top.
- Phase 4 auto-discovers custom scripts by parsing DSCInstall.log
for "Downloading script: <name>" lines AND scanning C:\Logs\SFLD\
Install-*.log files - so Display PCs running entirely different
scripts surface their own list automatically without hardcoding.
Statuses: pending / running / done / failed (mtime + tail-based).
- Boot-loop-safe reboot detection via Test-RebootState: only signals
'needed' if DSCDeployment.log was modified AFTER LastBootUpTime.
Once we've rebooted past it, just waits for DSCInstall.log.
- Caches monotonic Phase 1 indicators (AzureAdJoined, IntuneEnrolled,
EnterpriseMgmt task) so dsregcmd /status (slow ~1-2s) only runs
until the flag flips true, not on every poll.
- Triggers Intune sync at startup, re-triggers every 3 minutes (was
every 15 seconds in the old loop, which actively interrupted
in-flight CSP work).
Exit codes consumed by sync_intune.bat:
0 - DSCInstall.log shows "Installation completed successfully"
2 - DSCDeployment.log shows "Deployment completed successfully" AND
the deploy log is newer than LastBootUpTime (= reboot needed)
1 - error
Detection markers (decoded from a captured run at /home/camp/pxe-images/
Logs/ - see comment block at top of Monitor-IntuneProgress.ps1).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
77 lines
2.3 KiB
Batchfile
77 lines
2.3 KiB
Batchfile
@echo off
|
|
REM sync_intune.bat - Thin launcher for Monitor-IntuneProgress.ps1
|
|
REM
|
|
REM All polling, status display, sync triggering, and reboot detection lives in
|
|
REM the PowerShell monitor. This .bat just handles:
|
|
REM 1. Self-elevate to admin
|
|
REM 2. Invoke the monitor (which renders QR + 5-phase status table)
|
|
REM 3. Branch on the monitor's exit code:
|
|
REM 0 = post-reboot install complete, "done" message and exit
|
|
REM 2 = pre-reboot deployment done, prompt for reboot
|
|
REM else = error, pause so the user can read it
|
|
REM
|
|
REM The monitor lives at C:\Enrollment\shopfloor-setup\Shopfloor\Monitor-IntuneProgress.ps1.
|
|
REM This .bat gets copied to the user's desktop by Run-ShopfloorSetup.ps1, so
|
|
REM %~dp0 doesn't necessarily point at the shopfloor-setup tree - we use the
|
|
REM absolute path to find the monitor instead.
|
|
|
|
setlocal
|
|
title Intune Policy Sync
|
|
|
|
set "MONITOR=C:\Enrollment\shopfloor-setup\Shopfloor\Monitor-IntuneProgress.ps1"
|
|
|
|
REM Self-elevate to administrator
|
|
net session >nul 2>&1
|
|
if errorlevel 1 (
|
|
powershell -Command "Start-Process '%~f0' -Verb RunAs"
|
|
exit /b
|
|
)
|
|
|
|
if not exist "%MONITOR%" (
|
|
echo ERROR: Monitor not found at:
|
|
echo %MONITOR%
|
|
echo.
|
|
echo Was the shopfloor-setup tree staged correctly?
|
|
pause
|
|
exit /b 1
|
|
)
|
|
|
|
powershell -NoProfile -ExecutionPolicy Bypass -File "%MONITOR%"
|
|
set "MONITOR_EXIT=%errorlevel%"
|
|
|
|
echo.
|
|
if "%MONITOR_EXIT%"=="0" (
|
|
echo ========================================
|
|
echo Setup complete - no reboot needed
|
|
echo ========================================
|
|
echo.
|
|
echo The post-reboot DSC install phase is finished. The device is ready.
|
|
echo.
|
|
pause
|
|
exit /b 0
|
|
)
|
|
|
|
if "%MONITOR_EXIT%"=="2" (
|
|
echo ========================================
|
|
echo REBOOT REQUIRED
|
|
echo ========================================
|
|
echo.
|
|
echo The pre-reboot deployment phase is complete. You must reboot now to
|
|
echo start the post-reboot DSC install phase, which downloads device-config.yaml
|
|
echo and runs the per-app wrappers (Install-eDNC, Install-UDC, Install-VCRedists,
|
|
echo Install-OpenText, etc).
|
|
echo.
|
|
choice /c YN /m "Reboot now"
|
|
if errorlevel 2 (
|
|
echo Cancelled - reboot manually when ready.
|
|
pause
|
|
exit /b 0
|
|
)
|
|
shutdown /r /t 5
|
|
exit /b 0
|
|
)
|
|
|
|
echo ERROR: Monitor exited with code %MONITOR_EXIT%
|
|
pause
|
|
exit /b %MONITOR_EXIT%
|