@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 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 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 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