Check Intune configuration drift with Microsoft365DSC
A read-only Azure Pipeline pattern for testing a compiled DSC configuration and saving the results for review.
A scheduled configuration check can catch Intune changes made outside the repository. Keep the check separate from the job that applies changes.
This is a design note for the classic Windows PowerShell DSC/MOF workflow. The pipeline has not been run against a live tenant. It requires an existing, reviewed configuration; it is not a complete Intune deployment.
Prepare one configuration
Start with one supported Intune resource. Export its configuration, review the generated settings and assignments, and record the resource identity.
Pin Microsoft365DSC and its dependencies on the Windows agent. Check the selected resource’s authentication and permission requirements. A certificate thumbprint works only when the agent account can access the installed certificate and private key.
Compile the configuration into a directory containing localhost.mof. Treat compiled configurations and reports as restricted artifacts. Keep credentials out of Git.
Run the check
The example expects:
- A self-hosted Windows pool named
intune-dsc-windows. - Windows PowerShell and a working DSC Local Configuration Manager.
- The pinned modules and required certificate installed for the agent account.
- A reviewed
dsc/Compile.ps1script that accepts-OutputPathand compiles the configuration. Supply tenant authentication through your existing secure configuration.
trigger: none
schedules: - cron: '0 6 * * *' displayName: Daily drift check branches: include: [main] always: true
pool: name: intune-dsc-windows
steps: - checkout: self
- task: PowerShell@2 displayName: Compile and test configuration inputs: targetType: inline pwsh: false script: | $ErrorActionPreference = 'Stop' $output = Join-Path '$(Build.ArtifactStagingDirectory)' 'drift' $mofPath = Join-Path $output 'mof' & '$(Build.SourcesDirectory)\dsc\Compile.ps1' -OutputPath $mofPath if (-not (Test-Path (Join-Path $mofPath 'localhost.mof'))) { throw 'Compilation did not produce localhost.mof.' } $reference = Join-Path $mofPath 'localhost.mof' $inDesiredState = Test-DscConfiguration -ReferenceConfiguration $reference -ErrorAction Stop if ($inDesiredState -isnot [bool]) { throw 'The DSC test did not return a Boolean result.' } [ordered]@{ checkedAt = (Get-Date).ToUniversalTime().ToString('o') inDesiredState = $inDesiredState } | ConvertTo-Json | Set-Content (Join-Path $output 'result.json') if (-not $inDesiredState) { Write-Host '##vso[task.logissue type=warning]Configuration drift detected.' }
- publish: '$(Build.ArtifactStagingDirectory)/drift' artifact: drift-report condition: succeededOrFailed()The schedule uses UTC. The job runs a DSC test and publishes its result; it contains no apply command. An execution error fails the task. A completed test reporting drift produces a warning and a report for review.
This reference-file test reports an overall match. It does not produce a property-by-property diff. Inspect the resource and tenant state to determine the actual change. The -Detailed switch belongs to a different parameter set and is not combined with -ReferenceConfiguration here.
Review before applying
A portal change may be an approved fix that has not reached source control. Review the report against change records before restoring the repository version.
Use a separate apply job with an Azure DevOps environment approval configured outside YAML. Merely naming an environment does not add an approval. Apply the artifact from the reviewed run, with the same module versions and authentication available to that job.
Keep rollback configuration and assignment changes in the review. Successful application still needs a follow-up tenant check.
Validate the design
In a test tenant, capture a clean check, a deliberate setting change, the resulting drift report, and a reviewed restore. Confirm that authentication failures appear as failed checks rather than clean results.
Keep existing deployment scripts and policy catalogs in place until that sequence works. Ownership, rollout phase, and assignment records may still belong in the catalog.