{"id":1854,"date":"2026-04-05T22:48:34","date_gmt":"2026-04-05T22:48:34","guid":{"rendered":"https:\/\/move2modern.uk\/?p=1854"},"modified":"2026-04-06T07:59:45","modified_gmt":"2026-04-06T07:59:45","slug":"move-aside-utcm-is-here-or-is-it","status":"publish","type":"post","link":"https:\/\/move2modern.uk\/index.php\/2026\/04\/05\/move-aside-utcm-is-here-or-is-it\/","title":{"rendered":"Move aside, UTCM is here! Or is it?"},"content":{"rendered":"\n<figure class=\"wp-block-image size-large is-resized\"><img decoding=\"async\" width=\"1024\" height=\"683\" src=\"https:\/\/move2modern.uk\/wp-content\/uploads\/2026\/03\/Designer-33-1024x683.png\" alt=\"\" class=\"wp-image-1875\" style=\"aspect-ratio:1.500026633995632;width:550px;height:auto\" srcset=\"https:\/\/move2modern.uk\/wp-content\/uploads\/2026\/03\/Designer-33-1024x683.png 1024w, https:\/\/move2modern.uk\/wp-content\/uploads\/2026\/03\/Designer-33-300x200.png 300w, https:\/\/move2modern.uk\/wp-content\/uploads\/2026\/03\/Designer-33-768x512.png 768w, https:\/\/move2modern.uk\/wp-content\/uploads\/2026\/03\/Designer-33-120x80.png 120w, https:\/\/move2modern.uk\/wp-content\/uploads\/2026\/03\/Designer-33.png 1536w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><strong>Drift Management with Microsoft\u2019s Unified Tenant Configuration Management<\/strong> <strong>(UTCM)<\/strong><\/p>\n\n\n\n<p style=\"font-size:16px\"><strong>PART 2 OF 2<\/strong><\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p><strong>Important Note: <\/strong><\/p>\n\n\n\n<p><em>Results captured for this blog are from my own hands-on testing only. UTCM is in public preview with a staged rollout. Your results may differ, and things may change before becoming GA.<\/em><\/p>\n\n\n\n<div class=\"guten-element guten-spacer guten-7eVaUO\"><\/div>\n\n\n\n<p style=\"font-size:16px\">If you\u2019ve come from Part 1 of this blog series, you hopefully have an insight into what configuration drift actually is and the DIY approaches available already. I first introduced the ideas for using PowerShell scripts, Power Apps, Automate flows and direct Graph API calls as alternative routes for drift management. These have been used used by many existing tools and solutions for some time now. For my own tool IntuneAutomate I also originally looked at the drift-detection functionality. It has to be said though that using what some regard as the a DIY approach like this can introduce maintenance hurdles, particularly when there\u2019s a Microsoft upgrade, updates to an API endpoint or maybe even the renaming to a property.<\/p>\n\n\n\n<div class=\"guten-element guten-spacer guten-rMqI7o\"><\/div>\n\n\n\n<p style=\"font-size:16px\">That&#8217;s exactly the problem Microsoft&#8217;s <strong>Unified Tenant Configuration Management<\/strong> (UTCM) has been designed to solve and why getting to know the capability better became top of mind despite it still being in preview and pending license and pricing announcements.<\/p>\n\n\n\n<div class=\"guten-element guten-spacer guten-HTKm88\"><\/div>\n\n\n\n<p style=\"font-size:16px\">UTCM if effectively a native, platform-level solution to the drift detection problem and includes automation built-in. When it was first announced I was immediately interested and after having had some time to try it out, I wanted to bring the details and results from my own testing into this blog. Two things were key targets for me &#8211; I wanted to identify how it works, essentially the mechanics of it and then confirm the current status or limitations to features.<\/p>\n\n\n\n<div class=\"guten-element guten-spacer guten-JJD8Mv\"><\/div>\n\n\n\n<p style=\"font-size:16px\">The short answer by the way (as of the start April 2026) is that UTCM can work cleanly for Conditional Access (CA) and Intune resource types (RT)- Although it did take lots of trial an error to prove this with Intune RTs. In order to reach my conclusions, I spent several weeks testing across two tenants, experiencing numerous hurdles along the way. I&#8217;m talking dead ends, drained monthly quotas (on the first day of the month) incorrect UTCM API calls with mistakes from undocumented routes.  This post looks to cover all of that &#8211; what UTCM is, how to deploy it, what I found, and what it means for your planning today.<\/p>\n\n\n\n<figure class=\"wp-block-table is-style-regular has-small-font-size\"><table class=\"has-background has-fixed-layout\" style=\"background-color:#fff3cd\"><tbody><tr><td><strong>Preview Notice<\/strong><br>UTCM is still a staged public preview as of April 2026. All findings in this post reflect personal testing from my own andy@move2modern.co.uk and other commercial tenant during March\u2013April 2026. Results will vary by tenant depending on preview ring assignment. What works or fails here may behave differently in your environment.<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<figure class=\"wp-block-table is-style-regular has-small-font-size\"><table class=\"has-background has-fixed-layout\" style=\"background-color:#fddede\"><tbody><tr><td><strong>Sovereign cloud note<\/strong><br>UTCM APIs are Global service only. They are not available in US Government L4\/L5 (DoD) or the China cloud operated by 21Vianet. Verify your own endpoint availability before investing time in setup.<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-white-color has-text-color has-background has-link-color has-fixed-layout\" style=\"background-color:#002060\"><tbody><tr><td><strong>Section 1 \u2022 What Is UTCM and Where Did It Come From?<\/strong><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h1 class=\"wp-block-heading has-text-color has-link-color wp-elements-e35dbd3b6a964293fb0c3221d0d1f62f\" style=\"color:#1a178e;font-size:30px\">A Different Kind of Monitoring<\/h1>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity has-midnight-gradient-background has-background is-style-wide\"\/>\n\n\n\n<p class=\"has-text-color has-link-color has-medium-font-size wp-elements-4eda83f7a774fc1cf4ca479356f985c8\" style=\"color:#3a6bc4\"><strong>A Different Kind of Monitoring<\/strong><\/p>\n\n\n\n<p style=\"font-size:16px\"><strong>Part 1 of this series was about device-level drift and asking<\/strong>: Are my devices in the right state? Compliance, policy assignment, configuration profile application.<\/p>\n\n\n\n<p style=\"font-size:16px\"><strong>UTCM asks a different but related question:<\/strong> Are my Microsoft 365 tenant configurations in the right state? Not the devices. If someone quietly changes a CA policy, alters an Exchange transport rule, or deletes a compliance policy baseline from your tenant, UTCM is designed to detect that. Think of it as version control for your tenant settings, which is exactly what I needed.<\/p>\n\n\n\n<h2 class=\"wp-block-heading has-text-color has-link-color wp-elements-2951318c3720b460f482d0301309cb5a\" style=\"color:#3a6bc4;font-size:20px\">The M365DSC Connection<\/h2>\n\n\n\n<p style=\"font-size:16px\"><strong>M365DSC Led the way: <\/strong> Microsoft 365 Desired State Configuration (M365DSC), an open-source PowerShell project that has existed since 2019, led the way for this concept covering the M365 ecosystem. UTCM will effectively be Microsoft&#8217;s officially-supported, Graph API-native successor to this, where solutions shift from PowerShell DSC modules to JSON baselines and REST endpoints. Key to note here is that <em>Nik Charlebois<\/em>, the Principal Program Manager behind UTCM, was also the original creator of M365DSC making it clear that UTCM is the evolution of that work into the product platform.<\/p>\n\n\n\n<div class=\"guten-element guten-spacer guten-sE5WqK\"><\/div>\n\n\n\n<p class=\"has-text-color has-link-color wp-elements-3245fb436c4a6ac1cea2ead01880c559\" style=\"color:#3a6bc4;font-size:20px\"><strong>The Three<\/strong> <strong>Core Concepts<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-table is-style-stripes\" style=\"font-size:13px\"><table class=\"has-fixed-layout\"><thead><tr><td><strong>What It Does<\/strong><\/td><td><strong>Key Constraint<\/strong><\/td><\/tr><\/thead><tbody><tr><td>Point-in-time capture of current tenant configuration for one or more resource types. This becomes your baseline.<\/td><td>Expires after 7 days \u2013 Recommended to export locally immediately.<\/td><\/tr><tr><td>Runs every 6 hours and compares live tenants against your stored snapshot baseline.<\/td><td>6-hour interval is fixed and not configurable in preview.<\/td><\/tr><tr><td>When live state differs from baseline, a drift event is created with the old value, new value, and resource details.<\/td><td>No automated remediation in preview &#8211; just detection only at this stage.<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading has-text-color has-link-color has-medium-font-size wp-elements-3bc8ebd7c529819ac87aca800bbc4d43\" style=\"color:#3a6bc4\">Where UTCM Lives in Microsoft&#8217;s Stack<\/h2>\n\n\n\n<p style=\"font-size:16px\">UTCM capabilities are exposed through Microsoft Graph (beta endpoint currently, with some core endpoints also available at v1.0). Microsoft Entra Tenant Governance also has a new UI feature in preview available in the Entra admin centre. Thiis provides capability for viewing permissions and monitors with run history, and drift results without any API calls. There is no equivalent UI at this point though in the Intune admin centre:<\/p>\n\n\n\n<p><strong>Tenant Governance \u2192 Configuration management<\/strong><\/p>\n\n\n\n<p style=\"font-size:16px\">REALLY key to note here is that UTCM is not an Intune only feature. In preview, UTCM is designed to cover six Microsoft 365 workloads, although coverage and maturity does vary by workload, at least with my own testing:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li style=\"font-size:16px\">Entra ID &#8211; Conditional Access policies (CA), authentication methods, named locations, and more<\/li>\n\n\n\n<li style=\"font-size:16px\">Intune &#8211; compliance policies, app protection, assignment filters, and more<\/li>\n\n\n\n<li style=\"font-size:16px\">Exchange Online &#8211; accepted domains, transport rules, anti-phish policies, and more<\/li>\n\n\n\n<li style=\"font-size:16px\">Microsoft Teams &#8211; calling policies, channel settings, app permissions<\/li>\n\n\n\n<li style=\"font-size:16px\">Microsoft Defender &#8211; alert policies and related settings<\/li>\n\n\n\n<li style=\"font-size:16px\">Microsoft Purview &#8211; compliance and information protection settings<\/li>\n<\/ul>\n\n\n\n<p style=\"font-size:16px\">You can find the Microsoft official overview here: <\/p>\n\n\n\n<p class=\"has-text-color has-link-color wp-elements-1fb678e95edb6eeefa2076a12523983c\" style=\"color:#3a6bc4;font-size:16px\"><a href=\"https:\/\/learn.microsoft.com\/en-us\/graph\/unified-tenant-configuration-management-concept-overview\">Overview of the Tenant Configuration Management APIs in Microsoft Graph &#8211; Microsoft Graph | Microsoft Learn<\/a><\/p>\n\n\n\n<div class=\"guten-element guten-spacer guten-sGgjCl\"><\/div>\n\n\n\n<p style=\"font-size:16px\">For my own testing, this post focuses on just two of the areas, CA and Intune RTs, but I\u2019m sure I\u2019ll expand out over time with more. Good to know off the bat is that CA works cleanly end-to-end. For Intune resource types however, the picture is more complex. Read on to see exactly what this means. The rest of the blog walks you through the necessary background to UTCM then follows a logical route to set it up and test, together with tips and key findings along the way.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-white-color has-text-color has-background has-link-color has-fixed-layout\" style=\"background-color:#002060\"><tbody><tr><td><strong>Section 2 \u2014 How to Deploy UTCM<\/strong><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<div class=\"guten-element guten-spacer guten-CBuy3S\"><\/div>\n\n\n\n<p class=\"has-text-color has-link-color has-medium-font-size wp-elements-aa4df836b21ba79556c59d7be317590d\" style=\"color:#3a6bc4\"><strong>Prerequisites<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li style=\"font-size:16px\">PowerShell 7.2 or later<\/li>\n\n\n\n<li style=\"font-size:16px\">Microsoft.Graph.Authentication module &#8211; Install-Module Microsoft.Graph.Authentication -Scope CurrentUser<\/li>\n\n\n\n<li style=\"font-size:16px\">An account with Global Administrator or Privileged Role Administrator in the target tenant<\/li>\n\n\n\n<li style=\"font-size:16px\">The ConfigurationMonitoring.ReadWrite.All Graph scope (delegated, not application &#8211; see Section 7)<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading has-text-color has-link-color has-medium-font-size wp-elements-b5c8eb1bb8d371419a8587bc87e316fc\" style=\"color:#3a6bc4\">The UTCM Service Principal<\/h2>\n\n\n\n<p style=\"font-size:16px\">First off, UTCM uses a dedicated service principal (SP) to read all the resources it monitors. This means before any snapshots or monitors can be created, your SP must exist in your tenant and with the correct permissions setup. There are two SPs to provision:<\/p>\n\n\n\n<figure class=\"wp-block-table is-style-stripes has-small-font-size\"><table class=\"has-fixed-layout\"><thead><tr><td><strong>Service Principal<\/strong><\/td><td><strong>App ID<\/strong><\/td><td><strong>Purpose<\/strong><\/td><\/tr><\/thead><tbody><tr><td>Unified Tenant Configuration Management<\/td><td>03b07b79-c5bc-4b5e-9bfa-13acf4a99998<\/td><td>The UTCM SP &#8211; does the actual monitoring work and is installed with a script or manually in Azure<\/td><\/tr><tr><td>M365 Admin Services<\/td><td>6b91db1b-f05b-405a-a0b2-e3f60b28d645<\/td><td>Required by Microsoft as a co-dependency &#8211; ensure the M365 Admin Services SP is provisioned in the tenant, should be provisioned automatically as part of M365 service activation but worth checking. &nbsp;<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p style=\"font-size:16px\">I produced and fine tuned Script 1 below to handle the provisioning for the UTCM SP, checking whether it already exists before attempting the setup.<\/p>\n\n\n\n<h2 class=\"wp-block-heading has-text-color has-link-color has-medium-font-size wp-elements-5fd29e6a18c2bd9784d10fa2def2e0ee\" style=\"color:#3a6bc4\">The Five-Script Pipeline<\/h2>\n\n\n\n<p style=\"font-size:16px\">Following a logical setup for UTCM I\u2019ve created and make available for you 5 PowerShell scripts to run.<\/p>\n\n\n\n<figure class=\"wp-block-table is-style-stripes has-small-font-size\"><table class=\"has-fixed-layout\"><thead><tr><td><strong>Script<\/strong><\/td><td><strong>What It Does<\/strong><\/td><td><strong>When to Run<\/strong><\/td><\/tr><\/thead><tbody><tr><td>Script 1<\/td><td>UTCM Inventory PowerShell script. Checks what you have setup already for UTCM with an option to delete existing Snapshots and Monitors as needed.<\/td><td>First script to run. Run as many times as needed to check on status of UTCM<\/td><\/tr><tr><td>Script 2<\/td><td>Checks for and creates the UTCM and M365 Service principal (SP) as required<\/td><td>One time at initial setup if required \u2013 Optional \u2013 see results from script 1 above<\/td><\/tr><tr><td>Script 3<\/td><td>Grant permissions for enabled resource types only. Enabled for CA and Intune resource types only. Add to this as required for more<\/td><td>One time, or again when enabling new RTs<\/td><\/tr><tr><td>Script 4<\/td><td>Create snapshot jobs, poll for completion, save JSON baselines locally<\/td><td>Each time you want a new baseline<\/td><\/tr><tr><td>Script 5<\/td><td>Create monitors, reading from the snapshot index created by Script 3<\/td><td>After Script 4 completes<\/td><\/tr><tr><td>Script 6<\/td><td>Query drift results for all active monitors, generate per-RT drift-check scripts<\/td><td>On a schedule for ongoing monitoring<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<figure class=\"wp-block-table is-style-regular has-small-font-size\"><table class=\"has-background has-fixed-layout\" style=\"background-color:#d5e8f0\"><tbody><tr><td><strong><strong>Scripts available on GitHub<\/strong><\/strong><br>All above scripts are available for download on the Move2Modern GitHub site &#8211; &nbsp;<a href=\"https:\/\/github.com\/Croxleyboy\/IntuneScripts\/tree\/master\/UTCM%20-%20Drift%20Monitoring\">https:\/\/github.com\/Croxleyboy\/IntuneScripts\/tree\/master\/UTCM%20-%20Drift%20Monitoring<\/a><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\" style=\"font-size:16px\">Script 1 \u2014 UTCM Inventory<\/h3>\n\n\n\n<p style=\"font-size:16px\">This is the first script to run as it lists all UTCM monitors, snapshot jobs, and latest drift results for a target Microsoft 365 tenant. It first asks for your tenant ID or domain to authenticate before progressing. The good thing here is at the end of the discovery it provides you with the option to delete all snapshots and monitors. If you\u2019re running this for testing initially then I recommend this. The added benefit is you can always run this again at any point to check on the status.<\/p>\n\n\n\n<div class=\"guten-element guten-spacer guten-1TuzLi\"><\/div>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" width=\"975\" height=\"975\" src=\"https:\/\/move2modern.uk\/wp-content\/uploads\/2026\/04\/image.png\" alt=\"\" class=\"wp-image-1928\" srcset=\"https:\/\/move2modern.uk\/wp-content\/uploads\/2026\/04\/image.png 975w, https:\/\/move2modern.uk\/wp-content\/uploads\/2026\/04\/image-300x300.png 300w, https:\/\/move2modern.uk\/wp-content\/uploads\/2026\/04\/image-150x150.png 150w, https:\/\/move2modern.uk\/wp-content\/uploads\/2026\/04\/image-768x768.png 768w\" sizes=\"(max-width: 975px) 100vw, 975px\" \/><\/figure>\n\n\n\n<p style=\"font-size:16px\"><\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" width=\"975\" height=\"975\" src=\"https:\/\/move2modern.uk\/wp-content\/uploads\/2026\/04\/image-1.png\" alt=\"\" class=\"wp-image-1929\" srcset=\"https:\/\/move2modern.uk\/wp-content\/uploads\/2026\/04\/image-1.png 975w, https:\/\/move2modern.uk\/wp-content\/uploads\/2026\/04\/image-1-300x300.png 300w, https:\/\/move2modern.uk\/wp-content\/uploads\/2026\/04\/image-1-150x150.png 150w, https:\/\/move2modern.uk\/wp-content\/uploads\/2026\/04\/image-1-768x768.png 768w\" sizes=\"(max-width: 975px) 100vw, 975px\" \/><\/figure>\n\n\n\n<p style=\"font-size:16px\"><strong>Script 2 \u2014 Setup Service Principals<\/strong><\/p>\n\n\n\n<p style=\"font-size:16px\">This step is probably the most straight forward and contains the easiest PowerShell steps. I say this as UTCM uses a fixed App Id for both SPs. The two are for UTCM and M365 although it is unlikely you will need to setup M365 as it is generally configured as part of your M365 onboarding. The script will check for the creation of these and if absent goes ahead and creates them.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" width=\"975\" height=\"86\" src=\"https:\/\/move2modern.uk\/wp-content\/uploads\/2026\/04\/image-2.png\" alt=\"\" class=\"wp-image-1930\" srcset=\"https:\/\/move2modern.uk\/wp-content\/uploads\/2026\/04\/image-2.png 975w, https:\/\/move2modern.uk\/wp-content\/uploads\/2026\/04\/image-2-300x26.png 300w, https:\/\/move2modern.uk\/wp-content\/uploads\/2026\/04\/image-2-768x68.png 768w\" sizes=\"(max-width: 975px) 100vw, 975px\" \/><\/figure>\n\n\n\n<div class=\"guten-element guten-spacer guten-qsb11u\"><\/div>\n\n\n\n<div class=\"guten-element guten-spacer guten-wHsoyx\"><\/div>\n\n\n\n<p class=\"has-black-color has-text-color has-link-color wp-elements-d282511a6b0d07f0ed26db340c08e5e4\" style=\"font-size:16px\">Fixed Microsoft app IDs (do not change)<\/p>\n\n\n\n<p style=\"font-size:16px\">UTCM AppId = &#8217;03b07b79-c5bc-4b5e-9bfa-13acf4a99998&#8242;<\/p>\n\n\n\n<p style=\"font-size:16px\">M365 AdminSPId = &#8216;6b91db1b-f05b-405a-a0b2-e3f60b28d645&#8217;<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" style=\"font-size:16px\">Script 3 \u2014 Grant Permissions<\/h3>\n\n\n\n<p style=\"font-size:16px\">The permissions scripts is clean and simple \u2013 It runs a check for the required permissions to see if they already exist in your tenant for both CA and Intune resource types \u2013 then creates them if not present. Naturally any additional resource types will need to be setup manually using a script or using the new Tenant Governance settings within Entra.Microsoft.com &#8211; recently added UI (in preview).<\/p>\n\n\n\n<p style=\"font-size:16px\">Find script 3 here: <a href=\"https:\/\/github.com\/Croxleyboy\/IntuneScripts\/blob\/master\/UTCM%20-%20Drift%20Monitoring\/3%20-%20Grant%20permissions%20for%20CA%20and%20Intune%20resource%20Types.ps1\">https:\/\/github.com\/Croxleyboy\/IntuneScripts\/blob\/master\/UTCM%20-%20Drift%20Monitoring\/3%20-%20Grant%20permissions%20for%20CA%20and%20Intune%20resource%20Types.ps1<\/a><\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" width=\"975\" height=\"344\" src=\"https:\/\/move2modern.uk\/wp-content\/uploads\/2026\/04\/image-3.png\" alt=\"\" class=\"wp-image-1931\" srcset=\"https:\/\/move2modern.uk\/wp-content\/uploads\/2026\/04\/image-3.png 975w, https:\/\/move2modern.uk\/wp-content\/uploads\/2026\/04\/image-3-300x106.png 300w, https:\/\/move2modern.uk\/wp-content\/uploads\/2026\/04\/image-3-768x271.png 768w\" sizes=\"(max-width: 975px) 100vw, 975px\" \/><\/figure>\n\n\n\n<p style=\"font-size:16px\">If and when the permissions have been configured, you will get confirmation of this using the script.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" width=\"975\" height=\"331\" src=\"https:\/\/move2modern.uk\/wp-content\/uploads\/2026\/04\/image-4.png\" alt=\"\" class=\"wp-image-1932\" srcset=\"https:\/\/move2modern.uk\/wp-content\/uploads\/2026\/04\/image-4.png 975w, https:\/\/move2modern.uk\/wp-content\/uploads\/2026\/04\/image-4-300x102.png 300w, https:\/\/move2modern.uk\/wp-content\/uploads\/2026\/04\/image-4-768x261.png 768w\" sizes=\"(max-width: 975px) 100vw, 975px\" \/><\/figure>\n\n\n\n<p class=\"has-text-color has-link-color wp-elements-c90049276e932b78293b89c7e8647e35\" style=\"color:#3a6bc4;font-size:20px\"><strong>Permissions Required<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-table is-style-stripes\" style=\"font-size:12px\"><table class=\"has-dark-gray-color has-text-color has-link-color has-fixed-layout\"><thead><tr><td><strong>Permission<\/strong><\/td><td><strong>Required for<\/strong><\/td><td><strong>Granted on<\/strong><\/td><\/tr><\/thead><tbody><tr><td><strong>Policy.Read.All<\/strong><\/td><td>Reading CA policies for snapshot capture<\/td><td>Microsoft Graph SP<\/td><\/tr><tr><td><strong>Policy.Read.ConditionalAccess<\/strong><\/td><td>CA policy monitoring (both are needed &#8211; neither alone is sufficient)<\/td><td>Microsoft Graph SP<\/td><\/tr><tr><td><strong>ConfigurationMonitoring.ReadWrite.All<\/strong><\/td><td>Creating and managing snapshots and monitors<\/td><td>Microsoft Graph SP &#8211; confirmed required in testing<\/td><\/tr><tr><td><strong>ConfigurationMonitoring.Read.All<\/strong><\/td><td>Unlocks additional Entra resource types (authenticationStrengthPolicy, authorizationPolicy, crossTenantAccessPolicy)<\/td><td>Microsoft Graph SP &#8211; confirmed required in testing<\/td><\/tr><tr><td><strong>Application.ReadWrite.All<\/strong><\/td><td>Creating the UTCM SP (admin running setup only)<\/td><td>Delegated at consent<\/td><\/tr><tr><td><strong>AppRoleAssignment.ReadWrite.All<\/strong><\/td><td>Granting permissions to the UTCM SP (admin running setup only)<\/td><td>Delegated at consent<\/td><\/tr><tr><td><strong>DeviceManagementConfiguration.Read.All<\/strong><\/td><td>Intune configuration policies (backend pending activation)<\/td><td>Microsoft Graph SP<\/td><\/tr><tr><td><strong>DeviceManagementApps.Read.All<\/strong><\/td><td>Intune app management (backend pending activation)<\/td><td>Microsoft Graph SP<\/td><\/tr><tr><td><strong>DeviceManagementRBAC.Read.All<\/strong><\/td><td>Intune role definitions (backend pending activation)<\/td><td>Microsoft Graph SP<\/td><\/tr><tr><td><strong>DeviceManagementManagedDevices.Read.All<\/strong><\/td><td>Intune managed devices (backend pending activation)<\/td><td>Microsoft Graph SP<\/td><\/tr><tr><td><strong>DeviceManagementServiceConfig.Read.All<\/strong><\/td><td>Intune service configuration (backend pending activation)<\/td><td>Microsoft Graph SP<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<figure style=\"font-size:13px\" class=\"wp-block-table\"><table class=\"has-background has-fixed-layout\" style=\"background-color:#fff3cd\"><tbody><tr><td><strong>Both CA permissions are required<\/strong><\/td><\/tr><tr><td>Policy.Read.ConditionalAccess alone is not sufficient. Policy.Read.All must also be granted to the UTCM SP. This is not clearly documented \u2014 I confirmed it through testing.<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"has-black-color has-text-color has-link-color wp-elements-6acd06e1c2159926e5ba3254779baf0b\" style=\"font-size:16px\"><strong>Script 4 &#8211; Create Snapshots<\/strong><\/p>\n\n\n\n<p class=\"has-black-color has-text-color has-link-color wp-elements-fa0b6635e14a3bf6b67ce0b57036b9eb\" style=\"font-size:16px\">The creation of snapshots is the next step in the logical order or things. We can do this using the included script 4 added to the Github site. The thing to note here is that because:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li style=\"font-size:16px\">There\u2019s a <strong>20,000<\/strong> resources per tenant per month<\/li>\n\n\n\n<li style=\"font-size:16px\">Snapshots are retained only<strong> ~7 days<\/strong><\/li>\n\n\n\n<li style=\"font-size:16px\">Excess probing can block legitimate use<\/li>\n<\/ul>\n\n\n\n<p style=\"font-size:16px\">The script first checks if a snapshot exists and only proceeds per Resource type if not. It will also poll for completion and saves the snapshot JSON to .\\out\\snapshots\\. Ensuring you have a copy. UTCM is not intended for long-term storage of configurations. An important architectural decision was made by Microsoft in that, the next logical step is to create a Monitor from the created snapshot. BUT once the monitor baseline JSON has been captured and embedded within each monitor, the originating snapshot has done its job and you no longer need it. So, the deletion is just Microsoft&#8217;s way of keeping the platform clean and within limits.<\/p>\n\n\n\n<div class=\"guten-element guten-spacer guten-7zO6Lq\"><\/div>\n\n\n\n<p style=\"font-size:16px\"><strong>Test discoveries<\/strong>: To hep you navigate the snapshot stage, as a result of my own testing I eventually came to the conclusion that I needed to put a check into this script to test if there were any existing and related policies available in the tenant before creating a snapshot. This is because a snapshot would complete successfully even with no policies in the tenant, MEANING the corresponding Monitor script would fail to create when using an empty resource JSON from the corresponding snapshot.<\/p>\n\n\n\n<div class=\"guten-element guten-spacer guten-KaCBMK\"><\/div>\n\n\n\n<p style=\"font-size:16px\"><strong>Important notes:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li style=\"font-size:16px\">Creating a snapshot is optional. As the monitor baseline (see below) and the displayName are the only required properties when creating a new monitor. The baseline is essentially just a JSON blob which can also be hand-crafted and used by a monitor without ever running a snapshot job. HOWEVER The snapshot is just the easiest and most reliable way to <em>generate<\/em> that JSON, as it captures the real structure and property names that UTCM expects.<\/li>\n\n\n\n<li style=\"font-size:16px\">DisplayName must be letters, numbers and spaces only &#8211; no hyphens, dots or underscores<\/li>\n\n\n\n<li style=\"font-size:16px\">DisplayName must be between 8\u201332 characters. &#8216;CA Baseline 20260401&#8217; works; &#8216;CA-Baseline_01&#8217; does not<\/li>\n\n\n\n<li style=\"font-size:16px\">Snapshots have a 7 day expiry \u2013 so having a local JSON copy is optional but recommended for application uses.<\/li>\n\n\n\n<li style=\"font-size:16px\">Snapshot jobs are asynchronous. They poll every 5\u201315 seconds until status is succeeded, partiallySuccessful, or failed (You should see this when the script runs)<\/li>\n\n\n\n<li style=\"font-size:16px\">When attempting to test for available policies per resource type the graph calls may need to use the beta rather than v1.0 path and this will be changing over time meaning the script will need updating.<\/li>\n<\/ul>\n\n\n\n<p class=\"has-black-color has-text-color has-link-color wp-elements-d9fb6ce5722b737ed3c74c8955e840fb\" style=\"font-size:16px\">Download script 4 here: <a href=\"https:\/\/github.com\/Croxleyboy\/IntuneScripts\/blob\/master\/UTCM%20-%20Drift%20Monitoring\/4%20-%20New-UTCMSnapshotProbe-QuotaAwareV4.ps1\">https:\/\/github.com\/Croxleyboy\/IntuneScripts\/blob\/master\/UTCM%20-%20Drift%20Monitoring\/4%20-%20New-UTCMSnapshotProbe-QuotaAwareV4.ps1<\/a><\/p>\n\n\n\n<p style=\"font-size:16px\"><\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" width=\"975\" height=\"605\" src=\"https:\/\/move2modern.uk\/wp-content\/uploads\/2026\/04\/image-5.png\" alt=\"\" class=\"wp-image-1935\" srcset=\"https:\/\/move2modern.uk\/wp-content\/uploads\/2026\/04\/image-5.png 975w, https:\/\/move2modern.uk\/wp-content\/uploads\/2026\/04\/image-5-300x186.png 300w, https:\/\/move2modern.uk\/wp-content\/uploads\/2026\/04\/image-5-768x477.png 768w\" sizes=\"(max-width: 975px) 100vw, 975px\" \/><\/figure>\n\n\n\n<p style=\"font-size:16px\"><\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" width=\"975\" height=\"726\" src=\"https:\/\/move2modern.uk\/wp-content\/uploads\/2026\/04\/image-6.png\" alt=\"\" class=\"wp-image-1936\" srcset=\"https:\/\/move2modern.uk\/wp-content\/uploads\/2026\/04\/image-6.png 975w, https:\/\/move2modern.uk\/wp-content\/uploads\/2026\/04\/image-6-300x223.png 300w, https:\/\/move2modern.uk\/wp-content\/uploads\/2026\/04\/image-6-768x572.png 768w\" sizes=\"(max-width: 975px) 100vw, 975px\" \/><\/figure>\n\n\n\n<p style=\"font-size:16px\"><\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" width=\"975\" height=\"725\" src=\"https:\/\/move2modern.uk\/wp-content\/uploads\/2026\/04\/image-7.png\" alt=\"\" class=\"wp-image-1937\" srcset=\"https:\/\/move2modern.uk\/wp-content\/uploads\/2026\/04\/image-7.png 975w, https:\/\/move2modern.uk\/wp-content\/uploads\/2026\/04\/image-7-300x223.png 300w, https:\/\/move2modern.uk\/wp-content\/uploads\/2026\/04\/image-7-768x571.png 768w\" sizes=\"(max-width: 975px) 100vw, 975px\" \/><\/figure>\n\n\n\n<p style=\"font-size:16px\"><strong>Script 5 \u2014 Create Monitors<\/strong><\/p>\n\n\n\n<div class=\"guten-element guten-spacer guten-8YDyTZ\"><\/div>\n\n\n\n<p style=\"font-size:16px\">So, you have your Snapshots the next step here is setup Monitors \u2013 The key purpose of this step and associated script is to first discover if a monitor already exists for your resource types and attempt to create new monitors using the resources identified and saved as JSON with the snapshot. As mentioned previously taking this approach is optional but that\u2019s the way the script has been developed here for convenience. The key to this is again down to save quota\u2019s and secondly to ensure one exists to help maintain control on what\u2019s running. Multiple monitors are also possible for the same resource type as shown below in Entra but not recommended for the same resource type. For this reason, the script avoids setting up more than one monitor per resource type. If by chance this happens rather than scripting this, you can access:<\/p>\n\n\n\n<p style=\"font-size:16px\"><strong>Entra.Microsoft.com &gt; Tenant Governance &gt; Monitors<\/strong><\/p>\n\n\n\n<p style=\"font-size:16px\">and delete the monitor no longer required.<\/p>\n\n\n\n<p class=\"has-text-color has-link-color wp-elements-cf5cf2c394d2c9a45abdb0afc2ba91d4\" style=\"color:#3a6bc4\"><\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" width=\"975\" height=\"422\" src=\"https:\/\/move2modern.uk\/wp-content\/uploads\/2026\/04\/image-8.png\" alt=\"\" class=\"wp-image-1939\" srcset=\"https:\/\/move2modern.uk\/wp-content\/uploads\/2026\/04\/image-8.png 975w, https:\/\/move2modern.uk\/wp-content\/uploads\/2026\/04\/image-8-300x130.png 300w, https:\/\/move2modern.uk\/wp-content\/uploads\/2026\/04\/image-8-768x332.png 768w\" sizes=\"(max-width: 975px) 100vw, 975px\" \/><\/figure>\n\n\n\n<p class=\"has-black-color has-text-color has-link-color wp-elements-254e991358cfe59ccf1270f9f065edd4\" style=\"font-size:16px\">From my own testing this step is really what caused the greatest pain navigating the various scenarios. If as mentioned with script \u20184 \u2013 Snapshots\u2019, a snapshot for a given resource type utilises the snapshot for its JSON definition BUT the baseline contains an empty resources as shown below, this would make the monitor useless as it would be monitoring a policy that doesn\u2019t exist. This is exactly what happened for me. Worse still it was the reason why trying to create some of my Intune resource type monitors initially <strong>failed<\/strong>. This is a strong message in relation to the current status &#8211; It means a \u2018succeeded\u2019 snapshot is not the same as a usable snapshot by a monitor creation. As a consequence of the considerable debugging time spent on this, I therefore built into the monitor script a check to see if the snapshot JSON is empty before trying to proceed. <strong>(see Section 4 \u2014 My Journey).<\/strong><\/p>\n\n\n\n<p class=\"has-black-color has-text-color has-link-color wp-elements-edebebf55a0c90cf3d1800f386d1bc6b\" style=\"font-size:16px\">Example of empty Resources:<\/p>\n\n\n\n<p style=\"font-size:15px\">{<\/p>\n\n\n\n<p style=\"font-size:15px\">&nbsp; &#8220;description&#8221;: &#8220;UTCM resource type probe 4 of 16: microsoft.intune.devicecompliancepolicyandroidworkprofile | move2modern.co.uk&#8221;,<\/p>\n\n\n\n<p style=\"font-size:15px\"><strong>&nbsp; &#8220;resources&#8221;: [],<\/strong><\/p>\n\n\n\n<p style=\"font-size:15px\">&nbsp; &#8220;parameters&#8221;: [],<\/p>\n\n\n\n<p style=\"font-size:15px\">&nbsp; &#8220;id&#8221;: &#8220;194582d3-22d6-494f-b1f6-f7e027707ced&#8221;,<\/p>\n\n\n\n<p style=\"font-size:15px\">&nbsp; &#8220;@odata.context&#8221;: &#8220;https:\/\/graph.microsoft.com\/beta\/$metadata#admin\/configurationManagement\/configurationSnapshots\/$entity&#8221;,<\/p>\n\n\n\n<p style=\"font-size:15px\">&nbsp; &#8220;displayName&#8221;: &#8220;Probe 4 04011559&#8221;<\/p>\n\n\n\n<p style=\"font-size:15px\">}<\/p>\n\n\n\n<p>Find the PowerShell script here: <a href=\"https:\/\/github.com\/Croxleyboy\/IntuneScripts\/blob\/master\/UTCM%20-%20Drift%20Monitoring\/5%20-%20New-UTCMAllMonitorSetup.ps1\">https:\/\/github.com\/Croxleyboy\/IntuneScripts\/blob\/master\/UTCM%20-%20Drift%20Monitoring\/5%20-%20New-UTCMAllMonitorSetup.ps1<\/a><\/p>\n\n\n\n<p style=\"font-size:16px\"><strong>Added benefit:<\/strong> &nbsp;When complete you will see the different monitors appear in Tenant Governance.<\/p>\n\n\n\n<p style=\"font-size:16px\"><\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" width=\"975\" height=\"507\" src=\"https:\/\/move2modern.uk\/wp-content\/uploads\/2026\/04\/image-9.png\" alt=\"\" class=\"wp-image-1940\" srcset=\"https:\/\/move2modern.uk\/wp-content\/uploads\/2026\/04\/image-9.png 975w, https:\/\/move2modern.uk\/wp-content\/uploads\/2026\/04\/image-9-300x156.png 300w, https:\/\/move2modern.uk\/wp-content\/uploads\/2026\/04\/image-9-768x399.png 768w\" sizes=\"(max-width: 975px) 100vw, 975px\" \/><\/figure>\n\n\n\n<p style=\"font-size:16px\">And over time you\u2019ll see the results of the monitors be populated.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" width=\"975\" height=\"843\" src=\"https:\/\/move2modern.uk\/wp-content\/uploads\/2026\/04\/image-10.png\" alt=\"\" class=\"wp-image-1942\" srcset=\"https:\/\/move2modern.uk\/wp-content\/uploads\/2026\/04\/image-10.png 975w, https:\/\/move2modern.uk\/wp-content\/uploads\/2026\/04\/image-10-300x259.png 300w, https:\/\/move2modern.uk\/wp-content\/uploads\/2026\/04\/image-10-768x664.png 768w\" sizes=\"(max-width: 975px) 100vw, 975px\" \/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\" style=\"font-size:16px\">Script 5 \u2014 Collect Drift Results<\/h3>\n\n\n\n<p style=\"font-size:16px\">The first thing to add here is that the easy route to view the collected data is through the tenant governance portal UI:<\/p>\n\n\n\n<p style=\"font-size:16px\"><strong>Entra.microsoft.com &gt; Tenant Governance (Preview) &gt; Monitors (Preview) &gt; Monitor results &amp; Configuration drifts<\/strong><\/p>\n\n\n\n<p style=\"font-size:16px\">Both of the available tabs will deliver updates and changes to the policies over time too.<\/p>\n\n\n\n<p style=\"font-size:16px\">Drifts Report script: https:\/\/github.com\/Croxleyboy\/IntuneScripts\/blob\/master\/UTCM%20-%20Drift%20Monitoring\/6%20-%20Get-UTCMDriftReport.ps1<\/p>\n\n\n\n<p style=\"font-size:16px\">The other way to check in on your running monitors and maybe for you to use for your apps is to run a PowerShell script which:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li style=\"font-size:16px\">Connects to the tenant and discovers all active UTCM monitors directly from the API<\/li>\n\n\n\n<li style=\"font-size:16px\">For all your running monitors discovered, the last run result is queried along with all active configuration drifts &#8211; extracting the resource type from the monitor&#8217;s embedded baseline JSON<\/li>\n\n\n\n<li style=\"font-size:16px\">It prints a live per-monitor status to the console as it runs and produces a formatted summary table showing a drift count per monitor<\/li>\n\n\n\n<li style=\"font-size:16px\">Finally it writes a full JSON export (drifts.all.json) and a timestamped CSV summary locally to .\\out\\<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" width=\"972\" height=\"703\" src=\"https:\/\/move2modern.uk\/wp-content\/uploads\/2026\/04\/image-11.png\" alt=\"\" class=\"wp-image-1944\" srcset=\"https:\/\/move2modern.uk\/wp-content\/uploads\/2026\/04\/image-11.png 972w, https:\/\/move2modern.uk\/wp-content\/uploads\/2026\/04\/image-11-300x217.png 300w, https:\/\/move2modern.uk\/wp-content\/uploads\/2026\/04\/image-11-768x555.png 768w\" sizes=\"(max-width: 972px) 100vw, 972px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" width=\"975\" height=\"533\" src=\"https:\/\/move2modern.uk\/wp-content\/uploads\/2026\/04\/image-12.png\" alt=\"\" class=\"wp-image-1945\" srcset=\"https:\/\/move2modern.uk\/wp-content\/uploads\/2026\/04\/image-12.png 975w, https:\/\/move2modern.uk\/wp-content\/uploads\/2026\/04\/image-12-300x164.png 300w, https:\/\/move2modern.uk\/wp-content\/uploads\/2026\/04\/image-12-768x420.png 768w\" sizes=\"(max-width: 975px) 100vw, 975px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-white-color has-text-color has-background has-link-color has-fixed-layout\" style=\"background-color:#002060\"><tbody><tr><td><strong>Section 3 \u2014 Test Results: April 2026<\/strong><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading has-text-color has-link-color wp-elements-9ef4a2dfe4fbbef08db23fec36a965bd\" style=\"color:#3a6bc4;font-size:16px\">Testing Setup<\/h2>\n\n\n\n<p style=\"font-size:16px\">All tests were run against my move2modern.co.uk tenant during March 2026 and on 1 April after the monthly snapshot quota had been reset. I used two purpose-built scripts: a snapshot probe script that submits one snapshot job per resource type and polls for completion, and an inventory script that lists existing monitors, snapshot jobs, and drift results. Both are available on GitHub.<\/p>\n\n\n\n<p style=\"font-size:16px\">The testing approach was deliberately systematic: fix the display name format, run all 16 resource types in a single pass, and let the results speak for themselves with no manual retry, no cherry-picking.<\/p>\n\n\n\n<h2 class=\"wp-block-heading has-text-color has-link-color wp-elements-5d8dd597c71cdd6f1a18eb144f3391ae\" style=\"color:#3a6bc4;font-size:16px\">Snapshot Results &#8211; 14 of 16 Succeeded<\/h2>\n\n\n\n<p>After fixing the display name validation issue (see Section 4), the snapshot probe returned the following:<\/p>\n\n\n\n<p><\/p>\n\n\n\n<figure style=\"font-size:13px\" class=\"wp-block-table\"><table class=\"has-background has-fixed-layout\" style=\"background-color:#fff3cd\"><tbody><tr><td><strong>Notes on the two non-successes<\/strong><br>Conditional Access: the job returned partiallySuccessful (not failed) and a valid snapshot URL was generated. The timeout was a script poll timeout, not an API failure. The CA snapshot and monitor were created successfully via a separate run.<\/td><\/tr><tr><td>For devicecompliancepolicywindows10: the job was accepted, ran for 61 seconds, and returned failed with no error detail. No diagnostic information was surfaced by the API. All other Windows 10 compliance variants (Android, iOS, macOS) succeeded &#8211; this one failed silently for this specific type.<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading has-text-color has-link-color wp-elements-68a320e6414b52489d04ae8251cd98fd\" style=\"color:#3a6bc4;font-size:16px\">Monitor Results &#8211; CA Works, Intune came through eventually<\/h2>\n\n\n\n<p style=\"font-size:16px\">Snapshot success turned out to be only half the story. When I attempted to use the Intune snapshot JSON files as baselines for monitor creation, every Intune type failed at first, but in a very specific and informative way as per below.<\/p>\n\n\n\n<p style=\"font-size:16px\">Testing with microsoft.intune.devicecompliancepolicyandroidworkprofile as a representative case revealed the root cause:<\/p>\n\n\n\n<figure class=\"wp-block-table is-style-stripes\" style=\"font-size:13px\"><table class=\"has-fixed-layout\"><thead><tr><td><strong>CA (conditionalaccesspolicy)<\/strong><\/td><td><strong>Intune (devicecompliancepolicyandroidworkprofile)<\/strong><\/td><\/tr><\/thead><tbody><tr><td>\u2705 Accepted and completes<\/td><td>\u2705 Accepted and completes<\/td><\/tr><tr><td>\u2705 resourceLocation returns baseline JSON<\/td><td>\u2705 resourceLocation returns JSON<\/td><\/tr><tr><td>\u2705 Yes \u2014 resources array present with properties<\/td><td>\u274c No \u2014 resources[] array is absent from the JSON<\/td><\/tr><tr><td>\u2705 Succeeds \u2014 baseline is valid<\/td><td>\u274c Fails \u2014 baseline not valid for monitor use<\/td><\/tr><tr><td>\u2705 Live \u2014 1 drift detected in testing<\/td><td>\u274c Not possible without a valid monitor<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<figure style=\"font-size:13px\" class=\"wp-block-table\"><table class=\"has-background has-fixed-layout\" style=\"background-color:#d5e8f0\"><tbody><tr><td><strong>The critical distinction: export vs baseline<\/strong><\/td><\/tr><tr><td>Early testing showed cases where snapshot jobs completed successfully but produced baseline JSON with an empty resources[] array. In those cases, monitor creation either failed or resulted in a monitor that was effectively monitoring \u201cnothing\u201d.<br><br>In later testing, that behaviour changed. Intune monitors were successfully created and drift evaluation ran end-to-end. However, execution metadata was inconsistent: some monitors reported the resource type as \u201c(unknown)\u201d, and querying monitoring results sometimes returned BadRequest even though drift checks completed successfully.<br><br>The most accurate description as of April 2026 is that Intune monitoring works, but parts of the execution and reporting pipeline are still maturing. Snapshot success alone isn\u2019t sufficient &#8211; A usable baseline must contain populated resources, and scripts should validate this before monitor creation. In my testing, \u201c(unknown)\u201d didn\u2019t stop drift evaluation; it appears to be a reporting\/telemetry issue rather than a functional failure.<\/td><\/tr><tr><td>&nbsp;<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" width=\"856\" height=\"658\" src=\"https:\/\/move2modern.uk\/wp-content\/uploads\/2026\/04\/image-13.png\" alt=\"\" class=\"wp-image-1952\" srcset=\"https:\/\/move2modern.uk\/wp-content\/uploads\/2026\/04\/image-13.png 856w, https:\/\/move2modern.uk\/wp-content\/uploads\/2026\/04\/image-13-300x231.png 300w, https:\/\/move2modern.uk\/wp-content\/uploads\/2026\/04\/image-13-768x590.png 768w\" sizes=\"(max-width: 856px) 100vw, 856px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading has-text-color has-link-color wp-elements-f9c04990614e69d58b031b66d04054af\" style=\"color:#3a6bc4;font-size:16px\">What This Means in Practice<\/h2>\n\n\n\n<p style=\"font-size:16px\">Multiple test cases revealed a number of results as shown below which through understanding the mechanics and what some may regard as the minor limitations OR maybe just the way UTCM operates allowed me to navigate the process we will ultimately see working.<\/p>\n\n\n\n<figure class=\"wp-block-table is-style-stripes\" style=\"font-size:13px\"><table class=\"has-fixed-layout\"><thead><tr><td><strong>Status (April 2026)<\/strong><\/td><td><strong>Notes<\/strong><\/td><\/tr><\/thead><tbody><tr><td>\u2705 Working<\/td><td>Confirmed in both tenants<\/td><\/tr><tr><td>\u2705 Working<\/td><td>Runs every 6 hours, drift detected in testing<\/td><\/tr><tr><td>\u2705 Working<\/td><td>1 drift found in testing &#8211; correct delta captured<\/td><\/tr><tr><td>\u2705 Working<\/td><td>16\/16 types succeeded &#8211; export format only<\/td><\/tr><tr><td>\u274c Blocked<\/td><td>Baseline missing resources[] &#8211; cannot create monitor<\/td><\/tr><tr><td>\u274c Not available<\/td><td>No monitor possible without valid baseline<\/td><\/tr><tr><td>\u274c Failed<\/td><td>Silent failure &#8211; no error detail from API<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-white-color has-text-color has-background has-link-color has-fixed-layout\" style=\"background-color:#002060\"><tbody><tr><td><strong>Section 4 \u2014 My Testing Journey: What I Got Wrong and Why It Matters<\/strong><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p style=\"font-size:16px\">Getting to the clean results took several weeks and several wrong turns. So by documenting them here they may be genuinely useful for you approaching UTCM for the first time. It\u2019s clear the traps are not obvious when building this for yourself even when using the Microsoft documentation.<\/p>\n\n\n\n<h2 class=\"wp-block-heading has-text-color has-link-color wp-elements-3ffdf48e0688b4d32d19719dcfa68a1e\" style=\"color:#3a6bc4;font-size:16px\">Wrong API Endpoint Path<\/h2>\n\n\n\n<p style=\"font-size:16px\">In my early scripts, I was calling the <strong>wrong UTCM API path<\/strong>. The correct endpoint is:<\/p>\n\n\n\n<p style=\"font-size:16px\">I\u2019d mistakenly used <strong>configurationMonitoring instead of configurationManagement<\/strong>, and <strong>monitors instead of configurationMonitors<\/strong>. Either mistake on its own was enough to break the request, and together they resulted in repeated <strong>400 BadRequest<\/strong> responses.<\/p>\n\n\n\n<div class=\"guten-element guten-spacer guten-3O0SB3\"><\/div>\n\n\n\n<p style=\"font-size:16px\">What made this particularly frustrating is that the error message &#8211; <em>\u201cResource not found for the segment\u201d<\/em> &#8211; doesn\u2019t tell you <strong>which part of the path is wrong<\/strong>, so it wasn\u2019t immediately obvious whether the issue was the workload, the resource name, or the base path itself. That lack of precision is what turned a simple typo into a much longer debugging exercise than it should have been.<\/p>\n\n\n\n<h2 class=\"wp-block-heading has-text-color has-link-color wp-elements-a71c1b502ba1e9980c3e7d3f1c87a237\" style=\"color:#3a6bc4;font-size:16px\">Snapshot Job ID vs Snapshot Reference<\/h2>\n\n\n\n<p style=\"font-size:16px\">When creating a monitor, the baseline must reference a configuration snapshot albeit from the captured snapshot as per my scripts or via a JSON created manually &#8211; the downloaded JSON PLUS be aware not to use the snapshot job ID. I initially assumed the monitor creation call would take the job ID and retrieve the snapshot itself. BUT It doesn\u2019t. The workflow is:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li style=\"font-size:16px\">Create snapshot job &#8211; get job ID<\/li>\n\n\n\n<li style=\"font-size:16px\">Poll job until completed &#8211; get resourceLocation URL<\/li>\n\n\n\n<li style=\"font-size:16px\">Fetch the actual snapshot JSON from resourceLocation<\/li>\n\n\n\n<li style=\"font-size:16px\">Pass that JSON as the baseline body to POST \/configurationMonitors<\/li>\n<\/ol>\n\n\n\n<p style=\"font-size:16px\">Passing a job ID to the monitor creation endpoint returns a validation error that looks like a permission or schema error rather than a &#8216;wrong input type&#8217; error. This wasted several debugging sessions.<\/p>\n\n\n\n<h2 class=\"wp-block-heading has-text-color has-link-color wp-elements-8283e7b5468741bfdc0c00ae51acf71c\" style=\"color:#3a6bc4;font-size:16px\">Display Name Validation \u2014 Undocumented Rules<\/h2>\n\n\n\n<p style=\"font-size:16px\">My probe script was generating display names like &#8216;Probe microsoft.entra.conditionalaccesspolicy 20260401 1250&#8217;. Every single request returned 400. The error body, once I surfaced it properly, revealed two validation rules that are not documented in the Microsoft UTCM documentation at the time of writing:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li style=\"font-size:16px\">Display names must contain only alphabetic characters, numbers and spaces \u2014 no dots, hyphens, underscores or any other special characters<\/li>\n\n\n\n<li style=\"font-size:16px\">Display names must be between 8 and 32 characters<\/li>\n<\/ul>\n\n\n\n<p style=\"font-size:16px\">The fix was simple once identified &#8211; generate names like &#8216;Probe 1 04011250&#8217; &#8211; but diagnosing it required surfacing the raw Graph API response body, which the PowerShell exception message obscures. The fix is included in all scripts published on GitHub.<\/p>\n\n\n\n<figure class=\"wp-block-table is-style-stripes\" style=\"font-size:13px\"><table class=\"has-background has-fixed-layout\" style=\"background-color:#f2f2f2\"><tbody><tr><td><strong>What the error actually says<\/strong><\/td><\/tr><tr><td>&#8220;The field DisplayName must be a string with a minimum length of 8 and a maximum length of 32.&#8221;<\/td><\/tr><tr><td>&#8220;Snapshot Job displayName contains invalid characters. Only alphabets, numbers, and spaces are allowed.&#8221;<\/td><\/tr><tr><td>Both messages appear in the error details array within the 400 response body, not in the top-level exception message.<\/td><\/tr><tr><td>&nbsp;<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading has-text-color has-link-color wp-elements-42d63fe7c38cd2082ff45bbee7b7d6bc\" style=\"color:#3a6bc4;font-size:16px\">Wrong Resource Type Strings<\/h2>\n\n\n\n<p style=\"font-size:16px\">In my early testing I used shortened, Graph API-style resource type strings derived from my knowledge of the standard Intune Graph API &#8211; things like microsoft.intune.configurationpolicy and microsoft.intune.compliancepolicy. These all returned 400 validation errors, which I initially interpreted as those types not being supported currently.<\/p>\n\n\n\n<div class=\"guten-element guten-spacer guten-RUMT0B\"><\/div>\n\n\n\n<p style=\"font-size:16px\">The actual issue was that the UTCM resource type naming convention is different to the standard Graph API naming convention. The official UTCM Intune resource catalog at learn.microsoft.com\/en-us\/graph\/utcm-intune-resources uses fully-qualified, platform-specific type names such as:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li style=\"font-size:16px\">microsoft.intune.devicecompliancepolicyandroidworkprofile (not microsoft.intune.compliancepolicy)<\/li>\n\n\n\n<li style=\"font-size:16px\">microsoft.intune.antiviruspolicywindows10settingcatalog (not microsoft.intune.antiviruspolicy)<\/li>\n\n\n\n<li style=\"font-size:16px\">microsoft.intune.attacksurfacereductionrulespolicywindows10configmanager (note the configmanager suffix &#8211; this is the ConfigMgr co-managed variant)<\/li>\n<\/ul>\n\n\n\n<p style=\"font-size:16px\">The last one is particularly worth noting. The resource type <em>attacksurfacereductionrulespolicywindows10configmanager<\/em> was explicitly confirmed as not supported by the API \u2013 The correct naming, genuinely unsupported type: <em>devicecleanuprule<\/em> has the same status &#8211; listed in the docs but rejected at runtime as &#8216;not supported&#8217;. These are two where the documentation is ahead of the API implementation.<\/p>\n\n\n\n<p style=\"font-size:16px\">The key lesson here: always use the official UTCM catalog as your source for resource type strings, not the Graph API reference.<\/p>\n\n\n\n<div class=\"guten-element guten-spacer guten-KyZ7Uy\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading has-text-color has-link-color wp-elements-1af61ebe2caae0287f86f976dafc7f10\" style=\"color:#3a6bc4;font-size:16px\">Quota Exhaustion \u2014 First Day of the Month Problem<\/h2>\n\n\n\n<p style=\"font-size:16px\">UTCM has a quota of 20,000 resources per tenant per month at the time of testing. In my initial probe sessions I was submitting 30+ snapshot jobs to test which resource types worked, and those jobs, even when they returned empty results, consumed quota. I unfortunately exhausted the monthly quota on the first day by running systematic tests, which blocked all subsequent CA baseline operations for the rest of the month. Important to know right, although polling, listing, and reading existing jobs can be done all day long and these have zero quota impact. Only creation counts towards the quota. <strong>NOTE<\/strong>: The API does not surface a quota error when this happens. A snapshot job that hits quota exhaustion is accepted, runs, and returns partiallySuccessful or succeeded with zero resources. There is no indication that quota was the cause. The quota resets on the first of each month, which is why I was able to run the clean April results above.<\/p>\n\n\n\n<figure class=\"wp-block-table is-style-regular has-small-font-size\"><table class=\"has-background has-fixed-layout\" style=\"background-color:#fff3cd\"><tbody><tr><td><strong>Protect your quota<\/strong><br>Run probe and test scripts against a secondary or test tenant where possible.<br>If you see snapshot jobs returning 0 resources for types that should have data, quota exhaustion is the most likely cause.<br>Production baseline operations should be prioritised.<br><strong>Guide:<\/strong> A CA snapshot of a tenant with 20 CA policies consumes 20 of the 20,000 monthly resource quota.<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" style=\"font-size:16px\">The Wrong Drift Endpoint<\/h2>\n\n\n\n<p style=\"font-size:16px\">Some community examples reference a driftRecords subresource under configurationMonitors. In testing, GET \/configurationMonitors\/{id}\/driftRecords returns 400. <strong>BUT<\/strong> the correct endpoint for querying drift is configurationDrifts filtered by monitorId:<\/p>\n\n\n\n<figure style=\"font-size:13px\" class=\"wp-block-table\"><table class=\"has-background has-fixed-layout\" style=\"background-color:#ebeaea\"><tbody><tr><td>GET $BaseUri\/configurationDrifts?`$filter=monitorId eq &#8216;{your-monitor-id}&#8217;<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p style=\"font-size:16px\">Similarly, <em>configurationMonitoringResults<\/em> is a useful endpoint that surfaces per-run history including timestamps, status, and drift counts per run. This will be useful for confirming the monitor is actually executing, independent of any drift records.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-white-color has-text-color has-background has-link-color has-fixed-layout\" style=\"background-color:#002060\"><tbody><tr><td><strong>Section 5 &#8211; The Entra Tenant Governance UI<\/strong><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading has-text-color has-link-color wp-elements-647142dde6b83c2f38018270f43698b7\" style=\"color:#3a6bc4;font-size:16px\">When It Arrived<\/h2>\n\n\n\n<p style=\"font-size:16px\">The Good News is the Entra admin centre preview UI for UTCM has now arrived as part of the Microsoft Entra Tenant Governance preview- in January 2026. The configuration management section can be found under:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li style=\"font-size:16px\">Tenant Governance \u2192 Configuration management (Preview)<\/li>\n\n\n\n<li style=\"font-size:16px\">Configuration Management \u2192 Monitors (Preview).<\/li>\n<\/ul>\n\n\n\n<p style=\"font-size:16px\">Both are now added in the Entra admin centre menu options.<\/p>\n\n\n\n<p class=\"has-text-color has-link-color wp-elements-e3b8c79f0010a80988a816cfb8480ad4\" style=\"color:#3a6bc4;font-size:16px\"><strong>What the UI Provides<\/strong><\/p>\n\n\n\n<p style=\"font-size:16px\">It\u2019s important to be clear here. The portal is split into three straightforward views:<\/p>\n\n\n\n<div class=\"wp-block-group\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<ul style=\"font-size:16px\" class=\"wp-block-list\">\n<li>Monitors \u2013 Where you can see what\u2019s being monitored, when it last ran, and create or delete monitors.<\/li>\n<\/ul>\n\n\n\n<ul style=\"font-size:16px\" class=\"wp-block-list\">\n<li>Monitor results \u2013 Provides a run\u2011by\u2011run view showing execution times, status, and drift counts.<\/li>\n<\/ul>\n\n\n\n<ul style=\"font-size:16px\" class=\"wp-block-list\">\n<li>Configuration drifts \u2013 Includes a single list of everything that\u2019s drifted, including what changed and when it was first detected.<\/li>\n<\/ul>\n<\/div><\/div>\n\n\n\n<p style=\"font-size:16px\">When creating a new monitor, the wizard first shows the permissions currently assigned to the UTCM service principal as a quick sanity check, and then lets you upload a JSON baseline directly. That means you can bypass the snapshot\u2011to\u2011baseline issues covered earlier and you provide the JSON and the UI handles the rest.<\/p>\n\n\n\n<div class=\"guten-element guten-spacer guten-WjN5w0\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\" style=\"font-size:16px\">Where PowerShell or Graph is still needed<\/h2>\n\n\n\n<p style=\"font-size:16px\">The UI can now cover most of your day\u2011to\u2011day UTCM tasks, but setup still involves two permission layers:<\/p>\n\n\n\n<ul style=\"font-size:16px\" class=\"wp-block-list\">\n<li>The UTCM service principal permissions define what the monitors can read (for example, Conditional Access and Intune). These are visible and manageable in the Entra UI.<\/li>\n<\/ul>\n\n\n\n<ul style=\"font-size:16px\" class=\"wp-block-list\">\n<li>Calling user or app permissions define who can create and manage snapshots and monitors. So permissions like ConfigurationMonitoring.ReadWrite.All will still need to be manually granted to your admin user or app registration.<\/li>\n<\/ul>\n\n\n\n<p style=\"font-size:16px\">The result, setup still comes down to two steps:<\/p>\n\n\n\n<ul style=\"font-size:16px\" class=\"wp-block-list\">\n<li>Use the Entra UI to assign workload permissions to the UTCM service principal.<\/li>\n<\/ul>\n\n\n\n<ul style=\"font-size:16px\" class=\"wp-block-list\">\n<li>Grant ConfigurationMonitoring.ReadWrite.All (and related permissions) to the user or app managing UTCM.<\/li>\n<\/ul>\n\n\n\n<p style=\"font-size:16px\">Overall, yes UTCM is now much easier to work with. Permissions are now clearer, monitor creation is simpler, and baseline management is far more approachable. The scripts in this post are still useful for automation and scale, but for a single\u2011tenant setup or first evaluation, the UI alone is now a solid starting point.<\/p>\n\n\n\n<div class=\"guten-element guten-spacer guten-SpJY0n\"><\/div>\n\n\n\n<p style=\"font-size:16px\"><strong>A few current UI limitations to be aware of<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li style=\"font-size:16px\">Snapshot jobs are still created and managed via Graph, which makes scripting the most reliable option when working at scale.<\/li>\n\n\n\n<li style=\"font-size:16px\">There\u2019s no Intune\u2011specific UTCM UI in the Intune admin centre and all Intune monitoring flows through Tenant Governance.<\/li>\n\n\n\n<li style=\"font-size:16px\">When monitor creation fails, detailed error information is only available via the API.<\/li>\n\n\n\n<li style=\"font-size:16px\">Snapshot job history isn\u2019t currently surfaced in the UI; the portal focuses on monitors and drift results rather than the underlying snapshot operations.<\/li>\n<\/ul>\n\n\n\n<p style=\"font-size:16px\">These are all preview\u2011stage gaps rather than hard limitations, but they\u2019re worth knowing if you\u2019re troubleshooting or automating UTCM today.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-white-color has-text-color has-background has-link-color has-fixed-layout\" style=\"background-color:#002060\"><tbody><tr><td><strong>Section 6 &#8211; Where Do Third-Party Tools Stand<\/strong><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p style=\"font-size:16px\">A reasonable question to throw into the ring here is how do third\u2011party tools achieve comprehensive Intune drift detection, especially given the current preview limitations of UTCM.<\/p>\n\n\n\n<div class=\"guten-element guten-spacer guten-9v3IkL\"><\/div>\n\n\n\n<p style=\"font-size:16px\">In practice, <strong>most established tools are not built around UTCM<\/strong>. They predate it entirely and work directly against the standard Intune Graph API endpoints. This reflects the same approach described in Part 1 of this series. Those APIs have been stable and production\u2011ready for years, which is why these tools already offer deep and reliable Intune coverage.<\/p>\n\n\n\n<div class=\"guten-element guten-spacer guten-dchWFx\"><\/div>\n\n\n\n<p style=\"font-size:16px\">Where tools have started to adopt UTCM though, they\u2019re effectively wrapping the same APIs used in my scripts above so I\u2019m talking configurationMonitors, snapshot creation, and configurationDrifts. As a result, for sure they have encounter the <strong>same structural constraints and validation rules<\/strong>. These are enforced server\u2011side, which means client code can\u2019t work around them.<\/p>\n\n\n\n<div class=\"guten-element guten-spacer guten-W1uCAf\"><\/div>\n\n\n\n<p style=\"font-size:16px\">The TenantBaseline project as an example by Ugur Koc (Microsoft MVP) is a good example. Its changelog documents a real\u2011world BadRequest issue caused by submitting the IsSingleInstance property for Intune resource types. It shows history where something the UTCM API explicitly rejects because Intune policies are non\u2011singleton. That\u2019s a Layer\u20111 validation failure, and it\u2019s the same class of issue I ran into during my own testing.<\/p>\n\n\n\n<div class=\"guten-element guten-spacer guten-KCQTOi\"><\/div>\n\n\n\n<p style=\"font-size:16px\">The takeaway is that UTCM doesn\u2019t magically unlock new Intune capabilities for third\u2011party tools yet. Where UTCM works, it works the same way for everyone. Where it\u2019s limited, those limits apply equally. This happens whether you\u2019re using your own scripts or a packaged tool.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-white-color has-text-color has-background has-link-color has-fixed-layout\" style=\"background-color:#002060\"><tbody><tr><td><strong>Section 7 &#8211; Current Limitations and Preview Gotchas<\/strong><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p style=\"font-size:16px\">One thing that caught me out during testing is that <strong>UTCM <\/strong>doesn\u2019t yet behave reliably with app\u2011only authentication for write actions.<\/p>\n\n\n\n<div class=\"guten-element guten-spacer guten-hMZ6ap\"><\/div>\n\n\n\n<p style=\"font-size:16px\">When I tried creating snapshots and monitors using a Managed Identity (application\u2011only token), the calls consistently came back with <strong>403 Forbidden<\/strong>, even though ConfigurationMonitoring.ReadWrite.All was correctly assigned. Interestingly, read\u2011only actions worked just fine. I could list snapshot jobs and download baselines without any issues. It was only the write operations that were blocked.<\/p>\n\n\n\n<div class=\"guten-element guten-spacer guten-3AZD9w\"><\/div>\n\n\n\n<p style=\"font-size:16px\">In practical terms, this means you can\u2019t fully automate UTCM end\u2011to\u2011end today. Detection, reporting, and things like SharePoint or Power Automate workflows can all run unattended. But when it comes to resetting or creating a baseline, you still do need an interactive sign\u2011in, so someone logged as an <strong>Intune Administrator or Global Administrator<\/strong> permissions.<\/p>\n\n\n\n<div class=\"guten-element guten-spacer guten-KZ0Jaw\"><\/div>\n\n\n\n<p style=\"font-size:16px\">It\u2019s not a big task, but it is manual. If you\u2019re aiming for fully automated drift remediation, this is one of the current preview limitations you\u2019ll need to design around. From what I can see, this looks like a <strong>preview\u2011stage constraint<\/strong>, not a confirmed long\u2011term design decision.<\/p>\n\n\n\n<figure style=\"font-size:13px\" class=\"wp-block-table\"><table class=\"has-background has-fixed-layout\" style=\"background-color:#fff3cd\"><tbody><tr><td><strong>Conflict with Microsoft documentation<\/strong><\/td><\/tr><tr><td>Microsoft&#8217;s published authentication documentation states that application permissions are supported for snapshot and monitor creation. My experience contradicts this. This may reflect a preview ring behaviour, a missing prerequisite, or a temporary limitation. If you test application-only auth and find it working, please share your results &#8211; that would help confirm whether this was specific to my setup or a general preview constraint.<\/td><\/tr><tr><td>&nbsp;<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading has-text-color has-link-color wp-elements-f8e66d3f2ed60311a8d4ade7ddcd5533\" style=\"color:#3a6bc4;font-size:16px\">No Automated Remediation in Preview<\/h2>\n\n\n\n<p style=\"font-size:16px\">UTCM in preview mode is detection-only. When a drift is detected, resolution still requires manual action using the relevant admin tool. Microsoft has however signalled automated remediation (write-back) on the roadmap for post-GA, but it is not available today.<\/p>\n\n\n\n<div class=\"guten-element guten-spacer guten-ME0QSJ\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading has-text-color has-link-color wp-elements-c2cdd88bcdf38aeaf68990f21e1ef10c\" style=\"color:#3a6bc4;font-size:16px\">UTCM Is Not a Replacement for Device-Level Monitoring<\/h2>\n\n\n\n<figure style=\"font-size:13px\" class=\"wp-block-table\"><table class=\"has-background has-fixed-layout\" style=\"background-color:#d5e8f0\"><tbody><tr><td><strong>Important architectural distinction<\/strong><\/td><\/tr><tr><td>UTCM answers: has this Conditional Access policy or compliance policy baseline changed from its baseline definition?<\/td><\/tr><tr><td>Device compliance monitoring answers: is this specific device compliant right now?<\/td><\/tr><tr><td>These are different questions at different layers. UTCM does not replace device compliance monitoring and is not designed to. You need both. Even when UTCM reaches full Intune coverage, Part 1 device-level monitoring remains necessary.<\/td><\/tr><tr><td>&nbsp;<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"has-text-color has-link-color wp-elements-41e80167444fd84a016fda5b9b8c1a1e\" style=\"color:#3a6bc4;font-size:16px\"><strong>Quota Reference<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-table is-style-stripes\" style=\"font-size:13px\"><table class=\"has-fixed-layout\"><thead><tr><td><strong>Limit<\/strong><\/td><td><strong>Value<\/strong><\/td><td><strong>Notes<\/strong><\/td><\/tr><\/thead><tbody><tr><td>Max snapshot resources per month<\/td><td>20,000 across all jobs<\/td><td>Resets 1st of each month \u2014 not surfaced when exhausted<\/td><\/tr><tr><td>Max monitors per tenant<\/td><td>30<\/td><td>Across all resource types<\/td><\/tr><tr><td>Monitor run frequency<\/td><td>Every 6 hours<\/td><td>Fixed \u2014 not configurable in preview<\/td><\/tr><tr><td>Daily resource quota<\/td><td>800 resources\/day across all monitors<\/td><td>Each monitor run \u00d7 resource count consumes quota<\/td><\/tr><tr><td>Snapshot expiry<\/td><td>7 days<\/td><td>Export locally immediately \u2014 resourceLocation returns 404 after expiry<\/td><\/tr><tr><td>Max visible snapshot jobs<\/td><td>12 per docs \u2014 higher in practice<\/td><td>My tenant showed 18+ during testing<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"has-text-color has-link-color wp-elements-6e4b53d8f8ebc22c0723e9a39a664e8e\" style=\"color:#3a6bc4;font-size:16px\"><strong>Licensing<\/strong><\/p>\n\n\n\n<p style=\"font-size:16px\">UTCM Graph API access is available during preview. GA licensing is not yet confirmed at the time of writing (April 2026). The expected landing place could be Intune Plan 2 or the Intune Suite add-on for full governance features, but there are no formal announcements. Refer to Microsoft&#8217;s Tenant Governance licensing documentation at the time you evaluate for the latest position.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-white-color has-text-color has-background has-link-color has-fixed-layout\" style=\"background-color:#002060\"><tbody><tr><td><strong>Section 8 \u2014 Summary: Part 1 vs Part 2 \u2014 Which Approach When?<\/strong><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p style=\"font-size:16px\">Both approaches are valid today and serve different purposes. This comparison is based on the state of both the DIY Graph API approach and UTCM as of April 2026.<\/p>\n\n\n\n<figure class=\"wp-block-table is-style-stripes\" style=\"font-size:13px\"><table class=\"has-fixed-layout\"><tbody><tr><td><strong>Requirement<\/strong><\/td><td><strong>Part 1 \u2013 DIY (Graph API \/ Custom tooling)<\/strong><\/td><td><strong>Part 2 \u2013 UTCM (Preview \u2013 current reality)<\/strong><\/td><\/tr><tr><td><strong>Conditional Access policy drift detection<\/strong><\/td><td>\u2705 Possible, but requires custom logic and ongoing maintenance<\/td><td>\u2705 Fully working end\u2011to\u2011end (snapshots, monitors, drifts confirmed)<\/td><\/tr><tr><td><strong>Configuration snapshot \/ baseline creation<\/strong><\/td><td>\u2705 Graph API \u2014 stable, production\u2011ready<\/td><td>\u2705 Snapshots confirmed across CA and multiple Intune workloads<\/td><\/tr><tr><td><strong>Intune configuration policy monitoring<\/strong><\/td><td>\u2705 Fully achievable via Graph<\/td><td>\u2705 Monitors and drift checks run successfully; execution metadata may be incomplete (preview limitation)<\/td><\/tr><tr><td><strong>Intune app protection policy monitoring<\/strong><\/td><td>\u2705 Supported via Graph API<\/td><td>\u2705 Snapshots + monitors + drift evaluation confirmed, but execution telemetry is incomplete<\/td><\/tr><tr><td><strong>Teams \/ Exchange workload monitoring<\/strong><\/td><td>\u2705 Achievable via Graph with correct permissions<\/td><td>\u26a0\ufe0f Not validated in this test set; behaviour still workload\u2011dependent<\/td><\/tr><tr><td><strong>Per\u2011device compliance state monitoring<\/strong><\/td><td>\u2705 Supported (device\u2011centric Graph APIs)<\/td><td>\u274c Out of scope by design &#8211; UTCM monitors tenant configuration, not device state<\/td><\/tr><tr><td><strong>Multi\u2011tenant \/ cross\u2011tenant monitoring<\/strong><\/td><td>\u274c Complex and requires orchestration<\/td><td>\u26a0\ufe0f Technically possible, but depends on delegated auth and correct UTCM SP permissions<\/td><\/tr><tr><td><strong>Automated drift remediation<\/strong><\/td><td>\u2705 Build yourself or use a SaaS tool<\/td><td>\u274c Not available &#8211; detection only in preview<\/td><\/tr><tr><td><strong>Maintenance overhead<\/strong><\/td><td>\u274c High as you own scripts, schema changes, API drift<\/td><td>\u2705 Low operational overhead, but higher diagnostic effort during preview<\/td><\/tr><tr><td><strong>Operational confidence today<\/strong><\/td><td>\u2705 High \u2014 behaviour deterministic<\/td><td>\u26a0\ufe0f Medium &#8211; results are correct, but diagnostics and metadata are unreliable with some resource types<\/td><\/tr><tr><td><strong>When to use today<\/strong><\/td><td>\u2705 Best for full Intune + device\u2011level control<\/td><td>\u2705 Viable now for CA and Intune, if you accept preview limitations<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"has-text-color has-link-color wp-elements-8121fe0c07302f8a279d63d998d3859c\" style=\"color:#3a6bc4;font-size:16px\"><strong>My Practical Recommendation<\/strong><\/p>\n\n\n\n<p style=\"font-size:16px\">Deploy both. They are complementary, not competing.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li style=\"font-size:16px\">You can run Scripts 1\u20136 with CA enabled today. CA drift detection is working, valuable, and has a low maintenance burden. A changed or deleted CA policy is one of the most impactful security events in a tenant and having a 6-hour detection cycle for it is worth the 30-minute setup.<\/li>\n\n\n\n<li style=\"font-size:16px\">Definitely keep Part 1 tooling for Intune. Until all Intune monitors are proven and working as needed via UTCM, the Graph API approach from Part 1 is the only reliable route for Intune drift detection. Do not remove that coverage waiting for UTCM Intune monitoring to be ready and GA.<\/li>\n\n\n\n<li style=\"font-size:16px\">Test Intune resource types monthly across the full UTCM stack to verify and changes.<\/li>\n\n\n\n<li style=\"font-size:16px\">Share your results. If you get different findings in your tenant, especially if Intune monitor creation succeeds and please share in the comments. UTCM is still a in staged rollout, which means backend availability varies. Your results add to the collective picture.<\/li>\n<\/ul>\n\n\n\n<p class=\"has-text-color has-link-color wp-elements-b36b7eb50065e2908284947c809cb927\" style=\"color:#3a6bc4;font-size:16px\"><strong>My Closing Thoughts<\/strong><\/p>\n\n\n\n<p style=\"font-size:16px\">During my extensive testing the focus was around CA and Intune. UTCM is genuinely useful today for Conditional Access monitoring and my testing was consistent throughout. What this means is there are other M365 resource types un-tested for which this blog hasn\u2019t covered.<\/p>\n\n\n\n<p style=\"font-size:16px\">For Intune, the picture is mixed. All sixteen tested resource types now generate successful snapshots following early results. This showed meaningful progress from the early preview state. After taking a few wrong configuration paths and understanding some minor limitations, scripting proved successful and Monitors ran along with associated drifts.&nbsp;<\/p>\n\n\n\n<p style=\"font-size:16px\">The most important thing I can say from this testing is: verify everything in your own tenant. UTCM is in staged preview with varying backend availability. My two-tenant results gave a consistent picture, but your tenant may be in a different preview ring. The tools to probe and verify are all published on GitHub and can help. PLEASE run them, share your results, and help the community build the complete picture.<\/p>\n\n\n\n<div class=\"guten-element guten-spacer guten-iuAjoa\"><\/div>\n\n\n\n<p class=\"has-text-color has-link-color wp-elements-8dd8781875d85f801f9675df9d7c5629\" style=\"color:#3a6bc4;font-size:16px\"><strong>Technical References<\/strong><\/p>\n\n\n\n<p style=\"font-size:16px\">UTCM API overview: <a href=\"https:\/\/learn.microsoft.com\/en-us\/graph\/unified-tenant-configuration-management-concept-overview\">learn.microsoft.com\/en-us\/graph\/unified-tenant-configuration-management-concept-overview<\/a><\/p>\n\n\n\n<p style=\"font-size:16px\">UTCM Intune resource catalog: <a href=\"https:\/\/learn.microsoft.com\/en-us\/graph\/utcm-intune-resources\">learn.microsoft.com\/en-us\/graph\/utcm-intune-resources<\/a><\/p>\n\n\n\n<p style=\"font-size:16px\">UTCM Entra resource catalog: <a href=\"https:\/\/learn.microsoft.com\/en-us\/graph\/utcm-entra-resources\">learn.microsoft.com\/en-us\/graph\/utcm-entra-resources<\/a><\/p>\n\n\n\n<p style=\"font-size:16px\">UTCM authentication setup: <a href=\"https:\/\/learn.microsoft.com\/en-us\/graph\/utcm-authentication-setup\">learn.microsoft.com\/en-us\/graph\/utcm-authentication-setup<\/a><\/p>\n\n\n\n<p style=\"font-size:16px\">Entra Tenant Governance configuration management: <a href=\"https:\/\/learn.microsoft.com\/en-us\/entra\/id-governance\/tenant-governance\/configuration-management\">learn.microsoft.com\/en-us\/entra\/id-governance\/tenant-governance\/configuration-management<\/a><\/p>\n\n\n\n<p style=\"font-size:16px\">TenantBaseline (Ugur Koc): <a href=\"https:\/\/github.com\/ugurkocde\/TenantBaseline\">github.com\/ugurkocde\/TenantBaseline<\/a><\/p>\n\n\n\n<p style=\"font-size:16px\">UTCM introduction (Tony Redmond, Office 365 for IT Pros, Feb 2026): <a href=\"https:\/\/office365itpros.com\/2026\/02\/03\/utcm-beta\/\">office365itpros.com\/2026\/02\/03\/utcm-beta\/<\/a><\/p>\n\n\n\n<p style=\"font-size:16px\">Scripts used in this post: <a href=\"https:\/\/github.com\/Croxleyboy\/IntuneScripts\">https:\/\/github.com\/Croxleyboy\/IntuneScripts<\/a><\/p>\n\n\n\n<div class=\"guten-element guten-spacer guten-H3vOez\"><\/div>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-white-color has-text-color has-background has-link-color has-fixed-layout\" style=\"background-color:#002060\"><tbody><tr><td><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong><strong>\u2190 Part 1: DIY Drift Management<\/strong>&nbsp; :  <a href=\"https:\/\/move2modern.uk\/index.php\/2026\/03\/08\/alternative-approaches-to-utcm\/\" title=\"Open Part 1\">Open Part 1<\/a><br><\/strong><\/strong><\/strong><\/strong><\/strong><\/strong><\/strong><\/strong><\/strong><\/strong><\/strong><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Drift Management with Microsoft\u2019s Unified Tenant Configuration Management (UTCM) PART 2 OF 2 Important Note: Results captured for this blog<\/p>\n","protected":false},"author":1,"featured_media":1875,"comment_status":"open","ping_status":"open","sticky":true,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"footnotes":""},"categories":[3,7,15],"tags":[],"class_list":["post-1854","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-intune","category-m365","category-powershell"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/move2modern.uk\/index.php\/wp-json\/wp\/v2\/posts\/1854","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/move2modern.uk\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/move2modern.uk\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/move2modern.uk\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/move2modern.uk\/index.php\/wp-json\/wp\/v2\/comments?post=1854"}],"version-history":[{"count":108,"href":"https:\/\/move2modern.uk\/index.php\/wp-json\/wp\/v2\/posts\/1854\/revisions"}],"predecessor-version":[{"id":1989,"href":"https:\/\/move2modern.uk\/index.php\/wp-json\/wp\/v2\/posts\/1854\/revisions\/1989"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/move2modern.uk\/index.php\/wp-json\/wp\/v2\/media\/1875"}],"wp:attachment":[{"href":"https:\/\/move2modern.uk\/index.php\/wp-json\/wp\/v2\/media?parent=1854"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/move2modern.uk\/index.php\/wp-json\/wp\/v2\/categories?post=1854"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/move2modern.uk\/index.php\/wp-json\/wp\/v2\/tags?post=1854"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}