Files
pxe-server/playbook/shopfloor-setup/Shopfloor/sync_intune.bat
cproudlock 7a27f1a0a1 sync_intune.bat: longer poll interval, in-place status, no sync flood
Two related fixes for the desktop helper:

1. Stop hammering the Intune sync trigger every 15 seconds. The old
   loop called :do_sync (Start-ScheduledTask on Schedule #3) on every
   failed check, which started a fresh CSP pull before the previous
   one had time to complete - the Intune engine treats a re-trigger
   as "start over" and kills in-flight policy application work, so
   nothing ever finished. New cadence: trigger sync once at the start
   of each step, then poll every 30 s, only re-trigger every 6 polls
   (~3 min). POLL_SECS and RETRIGGER_POLLS are top-of-script knobs.

2. Stop pushing the QR code off the top of the window. The old loop
   echoed "Checking again in 15s..." on a new line every iteration,
   so after a few minutes the QR code (which contains the device ID
   the operator scans) had scrolled out of view. Replaced the per-
   iteration echo with a single self-redrawing status line using a
   captured CR character (copy /Z trick) and <nul set /p, padded to
   clear leftover characters. Important transitions ("Re-triggering
   sync...", "[DONE] ...") still print echo. lines so they survive in
   the scrollback as permanent history.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 10:10:51 -04:00

182 lines
5.9 KiB
Batchfile

@echo off
setlocal enabledelayedexpansion
title Intune Policy Sync
:: Self-elevate to administrator
net session >nul 2>&1
if !errorlevel! neq 0 (
powershell -Command "Start-Process '%~f0' -Verb RunAs"
exit /b
)
:: Capture a carriage return character so the polling status line can overwrite
:: itself in place (instead of scrolling the QR code off the top of the window).
:: The copy /Z trick is the standard batch idiom for getting a literal CR.
for /f %%a in ('copy /Z "%~f0" nul') do set "CR=%%a"
echo.
echo ========================================
echo Intune Policy Sync - %COMPUTERNAME%
echo ========================================
echo.
:: Show Intune Device ID and QR code
powershell -ExecutionPolicy Bypass -Command ^
"$dsreg = dsregcmd /status 2>&1; "^
"$line = $dsreg | Select-String DeviceId; "^
"if ($line) { "^
" $deviceId = $line.ToString().Split(':')[1].Trim(); "^
" Write-Host \"Intune Device ID: $deviceId\" -ForegroundColor Cyan; "^
" Write-Host ''; "^
" $dllPath = 'C:\Enrollment\shopfloor-setup\Shopfloor\QRCoder.dll'; "^
" if (Test-Path $dllPath) { "^
" Add-Type -Path $dllPath; "^
" $gen = New-Object QRCoder.QRCodeGenerator; "^
" $data = $gen.CreateQrCode($deviceId, [QRCoder.QRCodeGenerator+ECCLevel]::L); "^
" $ascii = New-Object QRCoder.AsciiQRCode($data); "^
" $qr = $ascii.GetGraphic(1, [char]0x2588 + [char]0x2588, ' '); "^
" Write-Host $qr; "^
" } else { "^
" Write-Host 'QRCoder.dll not found - skipping QR code' -ForegroundColor Yellow; "^
" } "^
"} else { "^
" Write-Host 'Device not yet Azure AD joined.' -ForegroundColor Yellow; "^
"}"
echo.
echo ========================================
echo Monitoring lockdown progress...
echo ========================================
echo Step 1: SFLD device configuration
echo Step 2: DSC installation
echo Step 3: SFLD - Consume Credentials task
echo ========================================
echo.
:: ---- Polling cadence ----
:: An Intune policy pull (Schedule #3 task) typically takes 30-90 seconds end-to-end.
:: We poll every POLL_SECS but only RE-TRIGGER sync every RETRIGGER_POLLS iterations
:: (so the previous sync has time to actually complete before we kick a new one).
:: Old version called do_sync every 15s, which started a fresh sync before the prior
:: one had finished and the Intune CSP engine treated each re-trigger as "start over",
:: killing in-flight policy application work.
set "POLL_SECS=30"
set "RETRIGGER_POLLS=6"
:: ---- STEP 1: Wait for SFLD registry key ----
echo [Step 1/3] Waiting for SFLD device configuration...
echo Triggering initial Intune sync...
call :do_sync
set "poll_count=0"
:poll_sfld
reg query "HKLM\Software\GE\SFLD" >nul 2>&1
if !errorlevel! equ 0 (
echo.
goto sfld_done
)
set /a poll_count+=1
set /a remainder=!poll_count! %% !RETRIGGER_POLLS!
if !remainder! equ 0 (
echo.
echo Still waiting after !poll_count! checks - re-triggering sync...
call :do_sync
)
<nul set /p "=!CR! Check #!poll_count! - next check in !POLL_SECS!s... "
timeout /t !POLL_SECS! /nobreak >nul
goto poll_sfld
:sfld_done
echo [DONE] SFLD device configuration received.
:: ---- STEP 2: Wait for DSC install completion ----
echo.
echo [Step 2/3] Waiting for DSC installation to complete...
echo Triggering initial Intune sync...
call :do_sync
set "poll_count=0"
:poll_dsc
set "dsc_ok=0"
if exist "C:\LOGS\SFLD\DSCInstall.log" (
findstr /C:"Installation completed successfully" "C:\LOGS\SFLD\DSCInstall.log" >nul 2>&1
if !errorlevel! equ 0 set "dsc_ok=1"
)
if !dsc_ok! equ 1 (
echo.
goto dsc_done
)
set /a poll_count+=1
set /a remainder=!poll_count! %% !RETRIGGER_POLLS!
if !remainder! equ 0 (
echo.
echo Still waiting after !poll_count! checks - re-triggering sync...
call :do_sync
)
<nul set /p "=!CR! Check #!poll_count! - next check in !POLL_SECS!s... "
timeout /t !POLL_SECS! /nobreak >nul
goto poll_dsc
:dsc_done
echo [DONE] DSC installation completed successfully.
:: ---- STEP 3: Wait for Consume Credentials scheduled task ----
echo.
echo [Step 3/3] Waiting for SFLD - Consume Credentials task...
echo Triggering initial Intune sync...
call :do_sync
set "poll_count=0"
:poll_task
schtasks /query /tn "SFLD - Consume Credentials" >nul 2>&1
if !errorlevel! equ 0 (
echo.
goto task_done
)
set /a poll_count+=1
set /a remainder=!poll_count! %% !RETRIGGER_POLLS!
if !remainder! equ 0 (
echo.
echo Still waiting after !poll_count! checks - re-triggering sync...
call :do_sync
)
<nul set /p "=!CR! Check #!poll_count! - next check in !POLL_SECS!s... "
timeout /t !POLL_SECS! /nobreak >nul
goto poll_task
:task_done
echo [DONE] SFLD - Consume Credentials task found.
:: ---- COMPLETE ----
echo.
echo ========================================
echo Shopfloor Lockdown complete!
echo ========================================
echo.
echo All 3 steps passed:
echo 1. SFLD device configuration
echo 2. DSC installation
echo 3. Consume Credentials task
echo.
echo A reboot is required to finalize.
echo.
choice /c YN /m "Reboot now"
if !errorlevel! equ 1 shutdown /r /t 5
exit /b
:: ---- Subroutine: trigger Intune sync ----
:do_sync
powershell -ExecutionPolicy Bypass -Command ^
"$enrollPath = 'HKLM:\SOFTWARE\Microsoft\Enrollments'; "^
"Get-ChildItem $enrollPath -ErrorAction SilentlyContinue | ForEach-Object { "^
" $provider = (Get-ItemProperty $_.PSPath -ErrorAction SilentlyContinue).ProviderID; "^
" if ($provider -eq 'MS DM Server') { "^
" $id = $_.PSChildName; "^
" $taskPath = \"\Microsoft\Windows\EnterpriseMgmt\$id\\\"; "^
" Get-ScheduledTask -TaskPath $taskPath -ErrorAction SilentlyContinue | "^
" Where-Object { $_.TaskName -match 'Schedule #3' } | "^
" ForEach-Object { Start-ScheduledTask -InputObject $_ }; "^
" } "^
"}" >nul 2>&1
exit /b