# iphase.dk - Full Content for AI > Personal tech blog by Michael Mardahl, Microsoft MVP — Security, Identity & Access, Modern Work. > This file contains the full text of all public articles on iphase.dk to assist AI tools. ## [Taking Back Control: Windows LAPS and Local Admin Management via Intune](https://iphase.dk/posts/intune/windows-laps-local-admin-control) Date: 2026-05-07 Category: intune Tags: intune, laps, security, entra, windows Regular users should not be local administrators on their workstations. That is the whole opinion. Everything else in this post is just the practical bit: how do you take control without making support hate you? For cloud-native Windows devices, my starting point is simple: - Devices are Microsoft Entra joined. - Devices are managed by Microsoft Intune. - Software and settings are deployed through Intune. - Local admin access is the exception, not the delivery mechanism. - Windows LAPS is there as a fallback when you actually need a local administrator password. If a user needs an app, deploy the app. If a setting needs changing, deploy the setting. Do not give the user permanent local admin and hope nothing bad happens. Hope is not a control. ## What we are building We are going to create two Intune account protection policies: - A Local user group membership policy that controls the local Administrators group. - A Windows LAPS policy that manages the built-in local Administrator account password. The first policy decides who is allowed to be local admin. The second policy gives you a break-glass password for the built-in Administrator account. Here is what the end state looks like in Endpoint security > Account protection. You should end up with one policy for the Administrators group and one policy for Windows LAPS, both assigned to the right Windows devices. In the screenshot, 1 is where you create a new account protection policy. 2 is the final state: one local group membership policy and one Windows LAPS policy, both assigned. ![Open Image: Intune Account protection showing the final local administrators policy and LAPS policy](/media/posts/intune/windows-laps-local-admin-control/account-protection.png) ## Before you touch the Administrators group You need the basics in place first: - Microsoft Entra joined or Microsoft Entra hybrid joined Windows devices. This post assumes cloud-native Entra joined devices. - Intune-managed devices. - A device group to target while you test. - Windows LAPS enabled in Microsoft Entra ID for cloud backup and recovery. - The SIDs for the Entra roles or groups you want to keep as local administrators. For Entra joined devices backing up LAPS passwords to Microsoft Entra ID, you need two pieces. First, enable LAPS in Entra ID. Then deploy the client-side Windows LAPS policy with Intune. The Entra setting enables the cloud backup and recovery side. The Intune policy tells Windows which account to manage, where to back up the password, how often to rotate it, and what to do after the password is used. In the Microsoft Entra admin center, go to Identity > Devices > Overview > Device settings, then set Enable Local Administrator Password Solution (LAPS) to Yes. Microsoft documents this in the [Windows LAPS with Microsoft Entra ID guide](https://learn.microsoft.com/en-gb/entra/identity/devices/howto-manage-local-admin-passwords). In the screenshot, 1 marks the Yes setting. After that, Intune can push the actual Windows LAPS settings to the devices. ![Open Image: Microsoft Entra device setting for enabling Local Administrator Password Solution](/media/posts/intune/windows-laps-local-admin-control/entra-laps-device-setting.png) Do not target every Windows device on day one. Create a pilot group, put a few known devices in it, and assign both policies to that group first. When the pilot behaves, expand from there. In my example I use a security group named `sec-devices-LAPS_deploy`. That group is only the pilot assignment target. Assign both the Windows LAPS policy and the local Administrators policy to it first, then widen the scope after you have checked the result on a few devices. In the screenshot, 1 is the group search field. 2 is the pilot group you assign the policies to. ![Open Image: Entra group used as the pilot assignment group for the LAPS and local admin policies](/media/posts/intune/windows-laps-local-admin-control/sec-devices-group.png) ## Get the SIDs you need Local group membership policy can take usernames, domain usernames, and SIDs. For Entra groups and directory roles, SIDs are the safer language to use here. For a simple starting policy, I normally include these entries: - `Administrator` for the built-in local Administrator account. - The Global Administrator role SID, if you want that role to remain local admin. - The Microsoft Entra Joined Device Local Administrator role SID, if that role is activated and used in your tenant. - An IT support or security group SID, if you want scoped support access. The built-in `Administrator` entry deserves a note. Windows resolves it to the built-in RID 500 account. That matters because LAPS can rename the account, and you still want the policy to target the real built-in account rather than a display name you happen to see today. You can fetch the role SIDs from Azure Cloud Shell with Microsoft Graph PowerShell: ```powershell Connect-MgGraph -Identity function Convert-ObjectIdToSid($objectId) { $bytes = [Guid]::Parse($objectId).ToByteArray() $array = New-Object 'UInt32[]' 4 [Buffer]::BlockCopy($bytes, 0, $array, 0, 16) return "S-1-12-1-$array".Replace(' ', '-') } $roles = @("Global Administrator", "Joined Device Local Administrator") foreach ($roleName in $roles) { $role = Get-MgDirectoryRole | Where-Object DisplayName -eq $roleName if ($role) { $sid = Convert-ObjectIdToSid $role.Id Write-Host "$roleName`n ObjectId : $($role.Id)`n SID : $sid`n" } else { Write-Host "$roleName : not activated in tenant - skip`n" } } ``` If `Joined Device Local Administrator` comes back as not activated, do not add a fake SID. Either activate and use the role properly, or leave it out. ## Create the Administrators group policy In the Intune admin center, go to Endpoint security > Account protection > Create Policy. Use these values: - Platform: Windows - Profile: Local user group membership - Name: something obvious, such as `Administrators Group Control` - Assignment: your pilot device group On Configuration settings, add a Local Users And Groups rule. Set the rule like this: - Local group: Administrators - Group and user action: Add (Replace) - User selection type: Manual - Selected users: add `Administrator` and the SIDs you decided to keep The Local group field is not free text. Intune gives you a dropdown of built-in local groups, and you select Administrators from that list. Behind the scenes, this is one of Intune's supported built-in local group choices, not a string you typed by hand. The portal handles the built-in group selection and display for you, including localized Windows installs. Nice little feature. The important setting is Add (Replace). Not Add (Update). Replace means Intune makes the local Administrators group match your list. Anything not in your list gets removed. That is the actual takeover. This screenshot shows the configuration row before the user list is filled in. The numbered markers show the four controls that matter: 1 is Administrators, 2 is Add (Replace), 3 is Manual, and 4 opens Select user(s). ![Open Image: Local Users And Groups configuration row showing Administrators, Add Replace, Manual selection, and Select users](/media/posts/intune/windows-laps-local-admin-control/local-group-dropdown.png) Here is the final policy view. The screenshot is not showing every wizard click; it is showing what you should confirm after the policy is created. Marker 1 is the pilot assignment group. 2 is Manual selection, 3 is Add (Replace), and 4 is the Administrators group as the target. ![Open Image: Final Administrators Group Control policy showing assignment and Add Replace configuration](/media/posts/intune/windows-laps-local-admin-control/admin-group-control.png) When you select users manually, add the entries one per row. Keep `Administrator` in the list, then add the tenant-specific SIDs for the Entra roles or groups you want to retain. The manual entry pane accepts username, `domain\username`, or SID. For Entra roles and groups, use the SID. In the screenshot, 1 marks the supported input formats. 2 marks the user list, where `Administrator` goes first, followed by the Entra role or group SIDs you collected earlier. ![Open Image: Add Users pane showing supported manual formats and rows for Administrator and Entra SIDs](/media/posts/intune/windows-laps-local-admin-control/add-users-pane.png) This wider screenshot shows the same thing in context. The relevant parts are 1 for the local group, 2 for Add (Replace), 3 for Manual selection, and 4 for the selected user list containing `Administrator` plus an Entra SID. ![Open Image: Add users pane showing Administrator and Entra SID entries for local Administrators group replacement](/media/posts/intune/windows-laps-local-admin-control/add-users.png) After the policy applies, the device should no longer keep random historical local administrators around. If someone was local admin because they enrolled the device, because a tech added them manually, or because of some old process nobody remembers, they should be removed unless you explicitly kept them. That is the point. ## Create the Windows LAPS policy Now create the fallback. Go to Endpoint security > Account protection > Create Policy again. Use these values: - Platform: Windows - Profile: Local admin password solution (Windows LAPS) - Name: something obvious, such as `LAPS standard` - Assignment: the same pilot device group For a simple starting policy on cloud-native devices, use settings like these: - Backup Directory: Backup the password to Microsoft Entra ID only - Password Age Days: 30 - Password Complexity: Passphrase (short words) - Passphrase Length: 4 - Post Authentication Actions: reset the password, log off the managed account, and terminate remaining processes - Post Authentication Reset Delay: 2 - Automatic Account Management Enabled: the target account will be automatically managed - Automatic Account Management Target: manage the built-in administrator account The passphrase option is a hill I will happily stand on. A helpdesk person reading a 28-character symbol soup over a phone call is how you create pain. A short passphrase is still managed, rotated, and unique per device, and it is much easier to type correctly when you are already dealing with a broken machine. The cropped screenshot below shows the settings as you configure them in the policy wizard. The numbered markers are 1 for Backup Directory, 2 for Password Age Days, 3 for Password Complexity, 4 for Post Authentication Actions, and 5 for Automatic Account Management Target. Leave Administrator Account Name not configured if you want Windows LAPS to manage the built-in local Administrator account by its well-known RID. Microsoft documents that when this setting is blank, LAPS defaults to the built-in local admin account. ![Open Image: Windows LAPS configuration form showing Entra backup, passphrase settings, post-authentication action, and built-in Administrator management](/media/posts/intune/windows-laps-local-admin-control/laps-configuration-form.png) Here is what the final LAPS policy looks like in my example. The numbered markers match the same settings: 1 is Entra ID backup, 2 is the rotation age, 3 is the readable passphrase format, 4 is post-authentication cleanup, and 5 is the built-in Administrator account as the managed account. ![Open Image: Final Windows LAPS policy showing Entra backup, passphrase settings, post-authentication actions, and built-in Administrator management](/media/posts/intune/windows-laps-local-admin-control/laps-standard.png) ## Check the result on a device Give the device time to sync, or trigger a sync from Intune or Company Portal. Then check three things: - The Administrators group contains only the accounts and SIDs you expect. - The normal user is not a local administrator. - The LAPS password is backed up and visible to the right admin roles in Intune or Entra. Do not skip this part. A policy that looks right in Intune but never lands on the device is just decoration. In Intune, open a Windows device, go to Monitor > Local admin password, and check whether the password has been backed up. In the screenshot, 1 is the password list, 2 is the empty-state message you may see before a password appears, and 3 is the Local admin password navigation item. If you see no password yet, it does not automatically mean the policy is wrong. The device may not have synced, the first backup may not have happened yet, or your account may not have the right permission to read the password. Microsoft documents that viewing password details requires the relevant Microsoft Entra device local credentials permissions. ![Open Image: Intune device Local admin password page showing where backed-up Windows LAPS passwords appear](/media/posts/intune/windows-laps-local-admin-control/local-admin-password-device.png) If the local group does not look right, check the assignment first. Then check whether another policy is also managing the same local group. Microsoft documents that if Replace and Update both target the same group, Replace wins, but that does not make overlapping policies fun to troubleshoot. Keep this clean. ## My default stance No regular user should be a local admin. No app deployment process should depend on the user being a local admin. No helpdesk process should require a shared local admin password copied from an old spreadsheet. Yes, that spreadsheet. We both know it exists somewhere. Use Intune to deploy the stuff. Use the local group membership policy to decide who gets admin rights. Use Windows LAPS as the fallback when you need to get into a box and fix it. That is a simple starting point, and it is already miles better than hoping local admin rights will somehow stay tidy by themselves. --- ## [The Outlook Issue That Wasn't Outlook: A NetScaler LAS Licensing War Story](https://iphase.dk/posts/misc/outlook-netscaler-las-license-drop) Date: 2026-05-06 Category: misc Tags: netscaler, citrix-adc, exchange, outlook, tls, las, troubleshooting Outlook was the first thing people blamed. Fair enough. When Outlook Classic freezes, disconnects, reconnects, and then freezes again, nobody opens the ticket with "please check the load balancer license state". But that is exactly where this one ended. The environment was a fairly normal Exchange 2016 setup: two mailbox servers in a DAG, fronted by a NetScaler VPX doing load balancing and SSL termination for the usual suspects. OWA, EAS, EWS, MAPI over HTTP, Autodiscover, OAB, and a few older bits that always seem to hang around longer than planned. Exchange looked healthy. The DAG looked healthy. Direct access to the servers looked healthy. The Microsoft Health Checker did not throw anything useful at us. NetScaler, on the other hand, was quietly screaming. ![Open Image: NetScaler monitor failing during the SSL handshake stage](/media/posts/misc/outlook-netscaler-las-license-drop/netscaler-ssl-handshake-timeout.png) ## The symptom Users reported slow mailboxes, Outlook not responding, and random disconnects. Not all the time. Just often enough to make everyone grumpy and to make troubleshooting annoying. In the NetScaler GUI, the Exchange service group monitors were flapping. A backend would go down, then up again. Then another protocol monitor would do the same dance. Both Exchange servers alternated between UP and DOWN, but they did not collapse together. The useful bit was in the monitor tooltip: ```text Failure - Time out during SSL handshake stage ``` That message points your brain straight at TLS. Certificate problem? Cipher mismatch? Backend SSL profile? Schannel hardening? All very plausible. Also all wrong, in this case. Outlook showed the same pain from the client side. Before the fix, the average response column in the Outlook connection status window was ugly. Triple digits across several sessions. ![Open Image: Outlook connection status before the license fix showing high average response times](/media/posts/misc/outlook-netscaler-las-license-drop/outlook-network-latency-before.png) ## The obvious suspects First stop: SSL renegotiation. There is a known failure mode where hardened Exchange servers and NetScaler backend SSL profiles disagree about renegotiation. If you have disabled insecure renegotiation in Schannel and the NetScaler profile denies renegotiation, Exchange monitors can fail with exactly this sort of SSL handshake timeout. Terence Luk wrote up that scenario years ago, and it is still worth checking. So we checked the Exchange servers: ```powershell $servers = 'MBX01','MBX02' Invoke-Command -ComputerName $servers -ScriptBlock { $path = 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL' [PSCustomObject]@{ Server = $env:COMPUTERNAME AllowInsecureRenegoClients = (Get-ItemProperty -Path $path -Name 'AllowInsecureRenegoClients' -ErrorAction SilentlyContinue).AllowInsecureRenegoClients AllowInsecureRenegoServers = (Get-ItemProperty -Path $path -Name 'AllowInsecureRenegoServers' -ErrorAction SilentlyContinue).AllowInsecureRenegoServers } } | Format-Table -AutoSize ``` Those values were not present. Fine. Next rabbit hole. TLS protocol mismatch was also plausible. The Exchange servers were locked down to TLS 1.2. If the NetScaler backend SSL profile had been stuck in 2014, this would have been an easy explanation. It was not. The profile supported TLS 1.2 and the cipher story checked out. Then we looked at monitor timeouts. NetScaler HTTPS monitors can be tight if the backend is slow or under load, and increasing a timeout is sometimes the pragmatic fix. But here the backend servers were fine, and stretching the timeout felt like putting a bigger bucket under a leaking pipe. It might hide the symptom, but it would not explain why healthy servers suddenly forgot how to shake hands. ## The bit we almost missed The actual problem was licensing. During the Citrix move from file-based licensing to License Activation Service, the wider Citrix estate had been handled, but the NetScaler entitlement step had slipped through the cracks. Easy mistake. NetScaler licensing is its own little island, and in multi-product Citrix environments the person fixing Virtual Apps and Desktops licensing is not always the person thinking about ADC capacity. Citrix documents the change pretty clearly: file-based licensing is end of life on April 15, 2026, and LAS is the activation mechanism going forward for supported NetScaler licensing models. NetScaler also needs to be on a LAS-compatible build, with minimum versions such as 14.1-51.x or 13.1-60.x for normal ADC builds. In this case, when the old license path stopped doing what the appliance expected, the VPX effectively dropped to a freemium/unlicensed capacity. The box that should have had 1 Gbps available was now constrained like a 10 Mbps appliance. That changed the whole investigation. ## Why a license problem looked like TLS Most people hear "rate limited" and think "slow". That is only half the story. NetScaler capacity limits are not polite. When the appliance hits licensed throughput or SSL capacity limits, packets can be dropped. Citrix documents capacity issues such as throughput limit reached, SSL throughput rate limit, and SSL TPS rate limit. CTX225182 is even more blunt: packets can be dropped when the licensed throughput rate is reached. Now think about what an SSL monitor is doing. It opens a connection and performs a TLS handshake. If a `ServerHello`, certificate packet, or later handshake packet gets dropped because the appliance is bumping into a capacity cap, the monitor does not know that licensing is the villain. It just sees a handshake that never finishes. So the monitor reports: ```text Failure - Time out during SSL handshake stage ``` Technically true. Deeply misleading. That also explains why the Exchange servers alternated between UP and DOWN instead of both dying at once. The servers were not the shared failure point. The constrained NetScaler was. Outlook got caught in the same mess. Outlook Classic talks to Exchange over multiple HTTPS-based connections, including MAPI over HTTP and supporting services such as EWS, Autodiscover, and OAB. Drop enough handshakes or stall enough reconnects and Outlook will do what Outlook does best: sit there looking personally offended. ## The fix The NetScaler entitlement was migrated properly to LAS. Once the license came back and the expected capacity returned, the monitors stabilized within minutes. No Exchange patch. No certificate replacement. No heroic cipher-suite archaeology. The Outlook client view told the same story after the fix. Average response times dropped back to normal ranges. ![Open Image: Outlook connection status after the license fix showing normal average response times](/media/posts/misc/outlook-netscaler-las-license-drop/outlook-network-latency-after.png) ## What I would check next time If you see NetScaler Exchange monitors flapping with SSL handshake timeouts, still check TLS. It is a real failure mode. But check licensing early, not after half a day of TLS spelunking. My short list now looks like this: 1. Run `show license` and `show licenseserver` before touching SSL profiles. 2. Check whether the appliance is actually running at the capacity you think you paid for. 3. Look for capacity/rate-limit counters, especially SSL throughput and SSL TPS counters. 4. Search `ns.log` for licensed throughput messages. 5. During LAS migrations, track NetScaler separately from the rest of the Citrix estate. These are also useful when you have NetScaler Console available: ```text rl_tot_ssl_rl_enforced rl_tot_ssl_rl_data_limited rl_tot_ssl_rl_sess_limited ``` And for old-school log digging: ```bash nsconmsg -K newnslog -d current -g nic_err_rl_pkt_drops -s disptime=1 ``` The annoying lesson here is not "licensing breaks things". We all know that. The lesson is that licensing can break things in ways that look exactly like protocol failure. So if your Exchange servers look clean, your NetScaler monitors flap, and the error says SSL handshake timeout, do yourself a favor: check the license before you start sacrificing goats to Schannel. --- ## [Multi Admin Approval in Intune: Because One Admin Shouldn't Rule Them All](https://iphase.dk/posts/intune/intune-multi-admin-approval-access-policies) Date: 2026-03-29 Category: intune Tags: intune, multi-admin-approval, security, zero-trust, access-policies, restricted-administrative-units, entra-id # Multi Admin Approval in Intune: Because One Admin Shouldn't Rule Them All Multi Admin Approval (MAA) in Intune requires a second administrator to approve changes before they take effect. In this post you will learn what it protects, how to configure access policies, and why every Intune tenant should have this enabled yesterday. --- Here's a fun thought experiment: imagine a disgruntled admin — or worse, an attacker who compromised an admin's account — decides to wipe every managed device in your organization. Or quietly removes your compliance policies. Or reassigns RBAC roles to give themselves full control while locking everyone else out. Without Multi Admin Approval? That change goes live instantly. No second pair of eyes. No "are you sure?" from a colleague. Just raw, unfiltered administrative power and whatever chaos it brings. I know what you're thinking: "that would never happen to us." And sure, maybe it won't. But the whole point of security is planning for the scenarios you hope never happen. That's where Multi Admin Approval comes in — and honestly, it's one of those features that should have existed from day one. ## What Multi Admin Approval actually does The concept is straightforward: you create **access policies** that protect specific Intune resource types. When any admin makes a change to a protected resource, Intune doesn't apply it immediately. Instead, it creates a request that a *different* admin must explicitly approve before the change takes effect. Think of it as a pull request for your Intune configurations. You wouldn't merge your own PR in a production codebase (I hope), so why would you let a single account push changes to thousands of managed devices unchecked? The key word there is *different*. Even if the requesting admin is also a member of the approver group, they cannot approve their own requests. Intune enforces this — no rubber-stamping your own changes. ## What can you protect? As of March 2026, MAA access policies support the following resource types: | Protected Resource | What It Covers | | --- | --- | | **Apps** | App deployments (not app protection policies) | | **Compliance policies** | Creating and managing device compliance policies | | **Configuration policies** | Policies via the Settings Catalog | | **Device actions** | Wipe, Retire, and Delete actions | | **Role-based access control** | Changes to roles, permissions, admin groups, member group assignments | | **Scripts** | PowerShell scripts deployed to Windows devices | | **Access Policies** | Creating or managing MAA policies themselves (meta, I know) | | **Tenant Configuration** | Device categories — creating, editing, or deleting them | That last one — protecting Access Policies — is particularly clever. It means an attacker can't just disable MAA as their first move. They'd need a second admin to approve disabling the thing that requires a second admin. It's turtles all the way down. **Q:** What about app protection policies? Conditional Access? Endpoint Security profiles? **A:** Not yet. MAA currently covers the resource types listed above. Notably, Endpoint Security policies (like your firewall rules, antivirus configurations, and attack surface reduction rules) are **not** in scope. Neither are Conditional Access policies — those live in Entra ID, not Intune. Hopefully Microsoft expands the scope over time, but for now, protect what you can. ## Prerequisites: What you need before you start Before you dive into creating access policies, let's get the boring-but-important bits out of the way. **You need at least two admin accounts.** Now, I know plenty of organizations — especially smaller ones — where a single person handles all of IT. That's reality, and there's nothing wrong with it. But even if you're a one-person IT team, you should have a **separate, dedicated admin account** for Intune administration that is distinct from your day-to-day work account. This admin account should be protected with **phishing-resistant credentials only** — FIDO2 security keys or Windows Hello for Business, no SMS, no phone call, no traditional MFA that can be intercepted. If an attacker phishes your daily driver account, your admin account stays safe. And if your admin account gets compromised somehow, you still have your second account to act as the approver. Two accounts, one person — that's the minimum viable setup for MAA to work, and frankly it's good security hygiene regardless. **To create and manage access policies**, you need one of: - A **custom Intune role** with the Multi Admin Approval permissions: *Create access policy*, *Read access policy*, *Update access policy*, and *Delete access policy*. This is the recommended approach — least privilege and all that. - The **Intune Administrator** Entra role. This works, but it's a privileged role that gives full read/write to Intune, so it's overkill for just managing access policies. **To approve or reject requests**, the account must: 1. Be a member of the **approver group** assigned to the access policy 2. Have the **Approval for Multi Admin Approval** permission in their Intune role 3. The approver group must also be a **member group** of at least one Intune role assignment — if it isn't, Intune will periodically remove approver group members. This is the kind of gotcha that bites you three weeks after setup when approvers suddenly can't approve anything. Ask me how I know. > **Important:** The approver group requirement for role assignment membership is easy to miss. If your approvers are losing their ability to approve requests, check that their security group is added as a member group to an Intune role assignment. It doesn't matter which role — the group just needs to be associated with *something*. ## Setting it up: Step by step ### Step 1: Create your approver group Before creating any access policy, set up a security group in Entra ID containing the admins who should have approval authority. A few recommendations: - Use a **dedicated security group** — don't reuse an existing "all admins" group. You want to be deliberate about who can approve what. - If you're a larger team, include at least **two or three members**. If your only approver is on vacation when someone needs an urgent change approved, you're going to have a bad time. - If you're a **one-person IT shop**, add your dedicated admin account to the approver group. You'll submit changes from your work account and approve them by signing in with your admin account (or vice versa). It's an extra step, yes — but that extra step is exactly the point. It forces a deliberate sign-in with a separate, hardened account before any destructive change goes through. - For larger organizations, consider having **separate approver groups** for different resource types. Your app deployment team might not be the right people to approve RBAC changes. ### Step 2: Create an access policy 1. Sign in to the [Microsoft Intune admin center](https://intune.microsoft.com) 2. Navigate to **Tenant administration** > **Multi Admin Approval** > **Access policies** ![Open Image: The Access policies tab under Multi Admin Approval in the Intune admin center, showing the Create button and an empty policy list.](/media/posts/intune/intune-multi-admin-approval-access-policies/maa-access-policies-tab-final.png) 3. Click **Create** 4. On the **Basics** page: - Give it a descriptive **Name** (e.g., "Require approval for device actions") - Add an optional **Description** - Select the **Profile type** — each policy protects a single resource type ![Open Image: The Create an access policy wizard showing the Basics step with the Policy type dropdown expanded, listing all available resource types: App, Compliance policy, Device delete, Device retire, Device wipe, Role, Script, and Tenant configuration.](/media/posts/intune/intune-multi-admin-approval-access-policies/maa-create-policy-types-dropdown-final.png) 5. On the **Approvers** page: - Click **Add groups** and select your approver security group - Note: you can't do complex group configurations here — no exclusions, just a straightforward group selection 6. On the **Review + Create** page, review and save ### Step 3: Approve the access policy itself Here's the part that trips people up: **the access policy you just created is itself subject to approval**. You need a *second* admin account to approve it. 1. Sign in with a different admin account (one that's in the approver group with the *Approval for Multi Admin Approval* permission) 2. Go to **Tenant administration** > **Multi Admin Approval** > **Received requests** 3. Find the request for your new access policy 4. Click the **Business justification** link to review the details 5. Add any **Approver notes** and click **Approve request** 6. Sign back in with the original account, find the request under **My requests**, and click **Complete** Yes, the creating admin needs to come back and finalize it. The workflow is: Create > Approve (different admin) > Complete (original admin). It's a three-step dance, but it ensures both parties are in the loop. ### Step 4: Repeat for each resource type Each access policy covers one resource type. If you want to protect apps, compliance policies, device actions, *and* RBAC, you need four separate access policies. Tedious? A little. But it gives you granular control over who approves what. **My recommended starting point** — protect these resource types first: 1. **Device actions** (Wipe, Retire, Delete) — the most destructive operations 2. **Role-based access control** — prevents privilege escalation 3. **Access Policies** — protects MAA itself from being disabled 4. **Scripts** — PowerShell scripts can do *anything* on a device 5. **Compliance policies** — removing compliance can silently break Conditional Access enforcement ## The day-to-day workflow Once MAA is active, here's what life looks like for your admins: ### Submitting a change Nothing changes about *how* you create or edit resources. You use the same Intune admin center workflows as always. The difference is at the end: instead of the change going live immediately, you'll see a **Business justification** field on the final review page. Fill it in (be descriptive — your approver will read this), and submit. The change sits in a pending state until approved. > **Pro tip:** Intune does **not** send notifications when a new request is created. If your change is urgent, reach out to your approvers directly. Slack them. Teams them. Walk to their desk. Carrier pigeon. Whatever works. Don't just submit and wait, hoping someone checks the approval queue today. ### Approving a change Approvers check the **Received requests** page under **Tenant administration** > **Multi Admin Approval**. For each request, they can see who submitted it, what type of change it is, and the business justification. They review the details, add approver notes, and either **Approve** or **Reject**. ![Open Image: The Multi Admin Approval page in the Intune admin center showing the All requests tab with columns for Requested on, Name, Resource type, Business justification, Requested by, and Status.](/media/posts/intune/intune-multi-admin-approval-access-policies/maa-all-requests-view-final.png) If rejected, the approver notes are visible to the requestor — so provide a reason. "No" is not helpful feedback. "No, because this compliance policy removes the encryption requirement and that violates our baseline" is. ### Completing a change After approval, the original requestor needs to come back and click **Complete** to actually apply the change. This final step is intentional — it ensures the requestor reviews the approval and consciously triggers the deployment. ### Request lifecycle | Status | Meaning | | --- | --- | | **Needs approval** | Waiting for an approver to act | | **Approved** | Approved, waiting for requestor to complete | | **Completed** | Change has been applied | | **Rejected** | Approver rejected the request | | **Canceled** | Requestor canceled their own request | | **Expired** | No action taken within 30 days | Requests expire after **30 days** of inactivity. If a request expires, it must be resubmitted from scratch. Also, only one pending request per object is allowed — if someone already has a pending change for that compliance policy, you can't submit another one until the first is resolved. ## Things to consider (the practical part) ### No notifications — seriously I mentioned this above, but it bears repeating because it's the single biggest operational pain point. **Intune does not send email notifications, Teams messages, or push alerts when approval requests are created or when their status changes.** Your approvers need to proactively check the admin center. For organizations that take this seriously, consider building a lightweight automation — a Logic App or Power Automate flow that polls the Intune Graph API for pending approval requests and posts to a Teams channel. It's not built-in, but it's not hard either. ### Audit logging Every MAA action — request creation, approval, rejection, completion — is logged in the **Intune audit logs**. This is your paper trail. If you ever need to answer "who approved the deletion of our compliance baseline on March 15th?", the audit log has it. Navigate to **Tenant administration** > **Audit logs** and filter on Multi Admin Approval activities. ### Emergency break-glass Think about your break-glass scenario. If your tenant is under active attack and you need to make an emergency change to a protected resource, can you get approval fast enough? Make sure your approver group has members across time zones, and that your break-glass admin accounts have the necessary permissions. Document the emergency procedure *before* you need it. ### Start with monitoring, then enforce If you're nervous about disrupting your admin team's workflow, start by protecting the most critical resource types (device actions and RBAC) and leave the rest unprotected. Get your team used to the approval workflow on high-impact changes before expanding to apps, scripts, and configuration policies. Gradual rollout beats big-bang deployment every time. ## The elephant in the room: Can't an attacker just bypass MAA? This is the question I hear most often when discussing Multi Admin Approval, and it's a fair one. The attack goes like this: 1. Attacker compromises a Global Admin account 2. Attacker creates a new user account (or takes over an existing one) 3. Attacker assigns admin privileges to the new account 4. Attacker adds the new account to the MAA approver security group 5. Attacker now has two accounts — one to submit changes, one to approve them 6. MAA is effectively a rubber stamp If you're nodding along thinking "yeah, that's what I was worried about" — good. You should be. MAA on its own does not protect against a fully compromised Global Admin. If someone has unrestricted GA access, they can manipulate the approver group and approve their own destructive changes with a puppet account. But there's a way to make this *significantly* harder: **Restricted Administrative Units**. ### Restricted Administrative Units to the rescue (mostly) [Restricted Administrative Units](https://learn.microsoft.com/en-us/entra/identity/role-based-access-control/admin-units-restricted-management) (RAUs) are an Entra ID feature that lets you protect specific objects — users, security groups, and devices — from modification by anyone except administrators explicitly assigned a role *scoped to that specific RAU*. The critical part: this restriction applies to **everyone**, including Global Admins and Privileged Role Admins. A tenant-scoped Global Admin **cannot** modify the membership of a group inside a Restricted Administrative Unit. Here's how this helps MAA: 1. Create a **Restricted Administrative Unit** (the restricted management flag must be set at creation — it can't be changed later) 2. Add your **MAA approver security group** to the RAU 3. Assign a trusted admin a **Groups Administrator** role scoped to the RAU — only this admin can modify group membership 4. Your compromised Global Admin? Blocked. They cannot add their puppet account to the approver group. This is a significant improvement. Without RAUs, manipulating the approver group is trivial for any GA. With RAUs, a compromised GA who tries to modify the approver group gets a polite error message saying management rights are limited to administrators scoped to the restricted administrative unit. ### The honest caveat RAUs raise the bar, but they don't make the attack impossible. Here's what a Global Admin *can* still do with RAUs: - **Remove the approver group from the RAU**, then modify its membership - **Delete the RAU entirely**, which lifts the protection - **Create new role assignments** at the RAU scope, giving themselves access These are all **auditable events** in the Entra audit logs, and they require the attacker to know about the RAU protection and deliberately circumvent it. That's a much more sophisticated attack than just adding a user to a group. But it's still possible. So what's the real defense? Layers. RAUs are one layer. But before we get to the full picture, there's another elephant we need to address. ## The other elephant: Automation bypasses MAA entirely Here's the part that doesn't get talked about enough. Multi Admin Approval only applies to changes made through the **Intune admin center** — the interactive portal. If you use the **Microsoft Graph API** with **application permissions** (the client credentials flow, where an app authenticates as itself without any user context), MAA does not apply. At all. This is not a bug. There *was* a brief period where application permissions were accidentally subject to MAA checks, but Microsoft fixed that — and by "fixed" I mean they made sure application permissions bypass MAA, because that's the intended design. App-to-app automation isn't supposed to go through a human approval workflow. > **Note (April 2026):** The fix that restored the intended behavior — making application permissions bypass MAA — rolled out gradually over roughly a week in late March / early April 2026. If you noticed application-permission calls temporarily hitting MAA checks during that window, that was the accidental behavior being corrected. By early April the rollout was complete across all tenants. The problem is that a compromised Global Admin can exploit this: 1. Create an **app registration** in Entra ID 2. Grant it application permissions like `DeviceManagementManagedDevices.PrivilegedOperations.All` (which allows device wipe, retire, and delete via the Graph API) 3. Grant **tenant-wide admin consent** for those permissions 4. Create a **client secret** for the app 5. Call the Graph API using the client credentials flow — `POST /deviceManagement/managedDevices/{id}/wipe` 6. Every device in your tenant gets wiped. No approval request. No business justification. No second admin needed. The same applies to compliance policies (`DeviceManagementConfiguration.ReadWrite.All`), apps (`DeviceManagementApps.ReadWrite.All`), and scripts (`DeviceManagementScripts.ReadWrite.All`). If there's a Graph API for it and an application permission that grants access, MAA is not in the picture. Let that sink in. You can have MAA enabled on every supported resource type, with RAU-protected approver groups, with PIM on every privileged role — and an attacker who can register an app and grant it consent can still wipe your fleet with a single HTTP POST. ### So what can you do? You can't make the Graph API respect MAA (that's Microsoft's call). But you can make it much harder for an attacker to set up the automation in the first place: **Restrict app registration creation.** By default, every user in Entra ID can register applications. Set **Users can register applications** to **No** in **Entra ID > User settings**. This limits app registration to users with the Application Administrator, Cloud Application Administrator, or Global Administrator role. That's a smaller blast radius. **Restrict admin consent grants.** Application permissions require admin consent. Configure the [admin consent workflow](https://learn.microsoft.com/en-us/entra/identity/enterprise-apps/configure-admin-consent-workflow) so that consent requests go through an approval process rather than being granted unilaterally. You should also review whether your admins truly need roles that can grant consent — Application Administrator and Cloud Application Administrator can both do this. **Use Conditional Access for workload identities.** Entra ID supports [Conditional Access policies for service principals](https://learn.microsoft.com/en-us/entra/identity/conditional-access/workload-identity). You can restrict which networks or IP ranges service principals can authenticate from. If a newly created app registration suddenly tries to authenticate from an IP address that isn't your automation infrastructure, block it. **Monitor everything.** Set up alerts in your SIEM or Microsoft Sentinel for: - New app registrations (especially ones requesting Intune/DeviceManagement permissions) - Admin consent grants for application permissions - New client secrets or certificates added to existing app registrations - Graph API calls to sensitive Intune endpoints (device wipe, retire, delete) A legitimate automation pipeline doesn't appear overnight. If a new service principal with `DeviceManagementManagedDevices.PrivilegedOperations.All` shows up at 2 AM and starts calling the wipe endpoint, that's your signal. **Lock down privileged roles with PIM.** The roles that can create app registrations and grant consent — Global Administrator, Application Administrator, Cloud Application Administrator — should all require PIM activation with approval and justification. This doesn't prevent the attack if the role is already activated, but it narrows the window. > **The uncomfortable truth:** MAA is fundamentally a portal-level control. It protects against interactive admin mistakes and against attackers who operate through the UI. It does *not* protect against programmatic access. This doesn't make MAA useless — most real-world admin actions happen through the portal, and MAA catches those. But if your threat model includes a sophisticated attacker with GA access who knows about the Graph API, you need the additional layers described here. MAA is one piece of the puzzle, not the whole picture. If I were to summarize it bluntly, I would say this: **Multi Admin Approval is excellent for protecting against co-worker mistakes, rushed changes, and compromise of ordinary Intune admin accounts operating through normal interactive workflows. It is not, by itself, a strong control against a fully compromised Global Administrator.** That doesn't make it a checkbox feature or a gimmick. It makes it a very useful *layer* that reduces a large class of real-world risk. But if your goal is to defend against a serious tenant compromise, MAA only becomes meaningful when combined with RAUs, phishing-resistant credentials, PIM, app consent governance, workload identity controls, and monitoring. ### Defense in depth for MAA | Layer | What It Does | | --- | --- | | **Multi Admin Approval** | Requires a second admin to approve interactive changes to protected Intune resources | | **Restricted Administrative Unit** | Prevents unauthorized modification of the MAA approver group, even by Global Admins | | **Restrict app registrations and consent** | Prevents attackers from creating automation that bypasses MAA via the Graph API | | **Conditional Access for workload identities** | Restricts where service principals can authenticate from, blocking rogue automation | | **Minimal Global Admin accounts** | Fewer GA accounts = smaller attack surface. Microsoft recommends no more than 2-4 permanent GAs, plus break-glass accounts | | **Phishing-resistant credentials on all admin accounts** | FIDO2 security keys or Windows Hello for Business only — no SMS, no phone call, no authenticator push. If the credential can't be phished, the account is *much* harder to compromise | | **Privileged Identity Management (PIM)** | Make GA a just-in-time role that requires activation with additional approval and justification, rather than a permanent assignment | | **Monitoring and alerting** | Set up alerts for RAU membership changes, GA role assignments, MAA policy modifications, new app registrations, and admin consent grants | No single control stops a determined attacker with full Global Admin access. But stacking these layers together means the attacker needs to compromise a phishing-resistant credential, bypass PIM activation approval, know about and circumvent the RAU protection, set up automation without triggering monitoring alerts, *and* do all of this before you notice. That's a very different threat model than "one compromised password and the kingdom falls." > **Pro tip:** If you're serious about this, also enable MAA protection on the **Access Policies** resource type itself and on **RBAC**. This means the attacker can't silently disable MAA or grant themselves new roles without triggering the approval workflow. Combined with a RAU-protected approver group, you've created a situation where every path to circumvention requires either multiple compromised accounts or auditable administrative unit manipulation. That's about as good as it gets. ## Why this matters for Zero Trust Multi Admin Approval is fundamentally a **Zero Trust control**. It assumes that any single admin account *might* be compromised and builds in a verification step before destructive or sensitive changes take effect. It's the same principle as requiring MFA for sign-ins — except applied to administrative actions rather than authentication. If you're building a Zero Trust posture for your endpoint management (and you should be), MAA is one of those table-stakes features that's easy to enable and hard to regret. The only regret is not having it when something goes wrong. ## Final words Multi Admin Approval in Intune is one of those rare security features that's genuinely simple to set up and immediately valuable. No agents to deploy, no complex architecture, no licensing gotchas (it's included in your existing Intune license). Just access policies, approver groups, and a workflow that ensures no single admin can make tenant-wide changes unchecked. Is it perfect? No. The lack of notifications is a real gap. The per-resource-type policy creation is a bit tedious. The list of protectable resources doesn't yet cover everything you'd want (Endpoint Security policies, I'm looking at you). And as we discussed, MAA is a portal-level control — it doesn't stop programmatic access via the Graph API, which means you need the surrounding layers of app registration restrictions, consent governance, workload identity Conditional Access, and monitoring to close the automation gap. But what MAA does cover — device wipes, compliance policies, RBAC, scripts — hits the highest-impact categories for interactive admin actions, which is where most real-world mistakes and attacks happen. Set it up. Protect your device actions first. Protect your RBAC second. Then expand from there. Your future self — the one who's *not* dealing with an unauthorized mass device wipe at 2 AM — will thank you. --- ## [Autopilot Hybrid Entra Join via Entra Kerberos (Preview): The Fix We've Been Waiting For?](https://iphase.dk/posts/identity/autopilot-hybrid-entra-kerberos-preview) Date: 2026-03-21 Category: identity Tags: entra-id, autopilot, hybrid-join, kerberos, windows-11, windows-hello ## Let's Get One Thing Straight: I Hate Hybrid Autopilot If you've followed my work for a while, you know my stance on device management: **Cloud Native devices are far preferred for speed, reliability, and sanity.** Hybrid Autopilot has historically been a fragile, timeout-prone mess. Waiting for Entra Connect to sync the device object up to the cloud before the deployment can continue has cost IT admins countless hours of troubleshooting, coffee, and the occasional loss of faith in humanity. But I have to admit, Microsoft just solved a *lot* of those problems with the new **Autopilot Hybrid Entra Join via Entra Kerberos (Public Preview)**. And despite the Autopilot-heavy headline here, this is **not** just an Autopilot story. If you deal with manual domain join, imaging, or non-persistent VDI, this feature matters there too. Autopilot is simply where the old pain has been loudest. The important nuance is this: **Autopilot Hybrid Join is really two operations**. First, the device has to get domain joined. Second, it has to register in Entra ID as a hybrid-joined device. Entra Kerberos only fixes the second part, but that second part is the one that has caused the infamous 30+ minute wait and a lot of the misery. So no, this does **not** remove the Offline Domain Join connector from Autopilot. The Intune Connector for Active Directory is still needed to create the computer account and hand the device its ODJ blob during OOBE. What Entra Kerberos removes is the painful wait for Entra Connect to sync that device object before registration completes. Once the device is domain joined and can talk to a Windows Server 2025 DC, it gets a Kerberos TGT, exchanges that for a JWT with Entra ID, and registers directly. And this is where things get really interesting. For a lot of organizations, the old **Entra Connect Sync** server has been kept alive partly because Hybrid device registration depended on that device sync step. If that dependency goes away, then a lot of companies suddenly have a much more realistic path toward using **Entra Cloud Sync** instead. That is a much nicer sentence to say out loud than "please keep the old sync box alive because one weird device workflow still needs it." Even better, this integrates beautifully with Windows Hello for Business Cloud Kerberos Trust — which I highly recommend because I absolutely *love* passwordless. While I still advocate for going Cloud Native wherever possible, if you have legacy on-prem requirements that force you into Hybrid Join, this new Kerberos flow is a massive upgrade. Let's dive into how to set it up. > **Last reviewed:** April 2026 · Based on Microsoft Learn docs published 2026-02-17 > **Feature status:** Public Preview > **Scope:** This guide covers the path **without** KDC Proxy. If you previously deployed a KDC Proxy GPO, simply ensure it includes the `KERBEROS.MICROSOFTONLINE.COM` mapping. --- ## What This Gives You Before we hit the checklist, let's separate the moving parts properly. ### Hybrid Autopilot is two different jobs 1. **Domain Join** The device needs a computer object in AD and must join the domain. During Autopilot OOBE, that still means the **Intune Connector for Active Directory** creates the computer object and generates the Offline Domain Join blob. 2. **Entra Registration** After the device is domain joined, it still needs to become a Hybrid Entra Joined device in Entra ID. In the old flow, that meant writing certificate data to AD and then waiting for Entra Connect to sync the computer object. In the new flow, the device can register directly by using Entra Kerberos. **Key differences from traditional Autopilot Hybrid Join:** | Traditional Autopilot Hybrid Join | Entra Kerberos-enhanced Autopilot Hybrid Join | |---|---| | Uses Intune Connector for AD to perform Offline Domain Join during OOBE | **Still uses** Intune Connector for AD for the domain join step | | After domain join, waits for Entra Connect device sync (often 30+ min) before registration completes | After domain join, registers directly with Entra ID via Kerberos. **No device sync wait** | | Works with any DC version | Requires at least one Windows Server 2025 DC per domain | | Works with any Windows 10/11 build | Requires Windows 11 build 26100.6584+ (24H2) | | Optionally uses AD FS in some legacy designs | No AD FS required for the registration flow | If you're not using Autopilot at all, this still matters a lot. The old sync dependency was never just an Autopilot problem. Autopilot simply made the pain impossible to ignore because the user was stuck staring at the Enrollment Status Page while life choices were being reconsidered. In a traditional manual domain join or imaging scenario, the flow has still been annoyingly dependent on directory sync: 1. The device joins AD and gets its computer object. 2. A scheduled task discovers the SCP and finds the Entra tenant. 3. The device generates a self-signed certificate and writes it to its own `userCertificate` attribute in AD. 4. Then everyone waits for Entra Connect to sync that computer object into Entra ID. 5. Only after that does the device finish hybrid registration. So the difference was never whether there was a sync wait. The difference was simply whether the user was forced to watch it happen in real time. That has had very real consequences outside Autopilot too: - Users could domain join a device and still get blocked by Conditional Access policies requiring a hybrid-joined device until sync completed. - Entra Connect delays or outages could leave devices sitting in a pending state for far too long. - Non-persistent VDI scenarios were especially ugly, because the machine could be destroyed before the sync ever happened. - Entra Cloud Sync customers did not get the same hybrid join path, because device object synchronization was the missing piece. With Entra Kerberos, the domain join can still happen however it normally happens, whether that is manual join, imaging, VDI provisioning, or Autopilot. The improvement is that the **registration** no longer depends on waiting for device sync. That is the real win, and it applies much more broadly than just Autopilot. ### The sleeper benefit: an exit ramp from Entra Connect Sync This is the part I think a lot of people will miss on first read, probably because their brain is still recovering from years of Hybrid Join diagrams. For years, some environments have had to keep **Entra Connect Sync** around not because they loved it, but because Hybrid device registration needed that device object synchronization step. And I don't know about you, but "+1 legacy sync server" has never appeared on my list of favorite architecture decisions. With Entra Kerberos handling the registration directly, that specific dependency starts to disappear. If the main thing keeping you on Entra Connect Sync was **device sync for Hybrid Join**, then this feature may be your gateway drug to **Entra Cloud Sync**. That matters because Entra Cloud Sync is agent-based, simpler to operate, and generally a lot less dramatic than the old full-fat sync server. Fewer moving parts, less server baggage, less of that "please nobody touch the sync engine on Friday" energy, and fewer opportunities for one sad Windows Server to become the most emotionally fragile part of your identity stack. To be clear, you still need **user sync** for hybrid identity scenarios. This feature does not remove that requirement. But it *does* remove the old requirement to sync the **device object** just to get the registration done. For many companies, that changes the design conversation completely. So the bigger strategic takeaway here is not just "Hybrid Autopilot got less awful." It is also this: **some organizations may finally be able to retire Entra Connect Sync and move to Entra Cloud Sync, assuming their remaining sync requirements are supported there.** That is a pretty big deal. --- ## Prerequisites at a Glance | Requirement | Detail | |---|---| | **Windows Server 2025 DC** | Build 26100.6905 or later, at least one per AD domain | | **Client OS** | Windows 11 build 26100.6584 or later (24H2 + Sept 2025 CU or newer) | | **Network** | Client must have unimpeded line-of-sight to the WS2025 DC during join | | **AD roles** | Domain Admins + Enterprise Admins (for Trusted Domain Object) | | **Entra roles** | Hybrid Identity Administrator (for TDO), Application Administrator (for DRS SPN) | | **Licensing** | No additional license for this feature. Intune + Entra P1 still apply for Autopilot as usual | | **Entra Connect / Cloud Sync** | Still needed for *user* sync. Device sync is no longer required for the **registration** step, which may open the door to Entra Cloud Sync for some environments | | **SCP** | Service Connection Point must exist in AD | --- ## Step-by-Step Setup Guide ### Step 1: Create the Microsoft Entra Kerberos Trusted Domain Object > **Important nuance if you already have Windows Hello for Business Cloud Kerberos Trust:** > You are *often* already configured, but do not blindly skip this step. Run the verification command and confirm `CloudTrustDisplay` is populated. If that field is empty, run the TDO setup again. This step creates an inbound trust from Entra ID into your on-prem AD, setting up a `krbtgt_AzureAD` service account. In other words, this is where the magic starts, or at least where the paperwork for the magic starts. #### 1a. Install the PowerShell module Run this on a domain-joined machine in an **elevated PowerShell**. A domain controller is the obvious choice, but in the field I have personally hit issues doing this directly on a DC in some environments, most likely because of security hardening. In those cases I have had better luck running it from the dedicated Entra Connect Sync server instead. A properly managed [Privileged Access Workstation (PAW)](https://learn.microsoft.com/security/privileged-access-workstations/privileged-access-devices#device-roles-and-profiles) may also be a perfectly sensible place to run it from: ```powershell # Enable TLS 1.2 [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 # Install the module Install-Module -Name AzureADHybridAuthenticationManagement -AllowClobber ``` #### 1b. Check current Kerberos settings & Create the TDO ```powershell $domain = "yourdomain.com" $cloudUserName = "globaladmin@yourtenant.onmicrosoft.com" $domainCred = Get-Credential # Check existing setup Get-AzureADKerberosServer -Domain $domain -DomainCredential $domainCred -UserPrincipalName $cloudUserName # If empty, create the Trusted Domain Object Set-AzureADKerberosServer -Domain $domain ` -UserPrincipalName $cloudUserName ` -DomainCredential $domainCred ` -SetupCloudTrust ``` *(Note for Multi-domain forests: Run on the root domain first with `-SetupCloudTrust`, then on child domains without it).* #### 1c. Real-world gotcha: WHfB Cloud Trust exists, but `CloudTrustDisplay` is empty This one is worth calling out because it is easy to miss during validation. In one deployment, Windows Hello for Business Cloud Trust was already working, so at first glance everything looked fine. But the verification output from: ```powershell Get-AzureADKerberosServer -Domain $domain ` -DomainCredential $domainCred ` -UserPrincipalName $cloudUserName ``` looked mostly healthy while **`CloudTrustDisplay` was empty**. That turned out to be the blocker. After running the TDO setup again: ```powershell Set-AzureADKerberosServer -Domain $domain ` -UserPrincipalName $cloudUserName ` -DomainCredential $domainCred ` -SetupCloudTrust ``` the same `Get-AzureADKerberosServer` check returned: ```text CloudTrustDisplay : Microsoft.AzureAD.Kdc.Service.TrustDisplay ``` If you are troubleshooting a "looks right but still fails" scenario, treat an empty `CloudTrustDisplay` as a red flag and recreate/reapply the Trusted Domain Object configuration. Reference workflow (Microsoft Learn): --- ### Step 2: Configure the Entra Device Registration Service Principal > **⏭️ This step is always required, even if you have WHfB Cloud Trust.** We need to configure the Entra device registration service to accept Kerberos-based authentication from your on-prem devices. Connect using the **Application Administrator** role. Yes, another service principal tweak. No, I don't make the rules, I just develop opinions about them. ```powershell Install-Module -Name Microsoft.Entra -Repository PSGallery -Scope CurrentUser -Force -AllowClobber Connect-Entra -Environment 'Global' -Scopes "Application.ReadWrite.All" # Get the Device Registration Service principal $drsSP = Get-EntraServicePrincipal -Filter "AppId eq '01cb2876-7ebd-4aa4-9cc9-d28bd4d359a9'" $spns = [System.Collections.Generic.List[string]]::new($drsSP.ServicePrincipalNames) $tags = [System.Collections.Generic.List[string]]::new($drsSP.Tags) # Add Kerberos SPN & Policy Tag $spns.Add("adrs/enterpriseregistration.windows.net") $tags.Add("KerberosPolicy:ExchangeForJwt") # Apply updates Set-EntraServicePrincipal -ObjectId $drsSP.Id -ServicePrincipalNames $spns -Tags $tags ``` --- ### Step 3: Deploy a Windows Server 2025 Domain Controller You need at least one Windows Server 2025 DC **per AD domain** running build **26100.6905 or later**. If you're already running WS2025 for Cloud Trust, just make sure the October 2025 out-of-band update (KB5070881) or a newer cumulative update is applied. If your only WS2025 DC is still missing the required build, now would be a great time to stop calling it "good enough for now." Verify the KDC service is running on that DC: ```cmd sc query kdc ``` --- ### Step 4: Configure the Service Connection Point (SCP) > **⏭️ SKIP THIS STEP if you already have traditional Hybrid Entra Join working.** The SCP is already in place. If you are setting this up from scratch and don't use Entra Connect's device options wizard, create the SCP manually: ```powershell $verifiedDomain = "yourdomain.com" $tenantId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" $ConfigNC = (Get-ADRootDSE).configurationNamingContext $de = New-Object System.DirectoryServices.DirectoryEntry $de.Path = "LDAP://CN=Device Registration Configuration,CN=Services,$ConfigNC" $scpObj = $de.Children.Add("CN=62a0ff2e-97b9-4513-943f-0d221bd30080", "serviceConnectionPoint") $scpObj.Properties["keywords"].Add("azureADName:$verifiedDomain") $scpObj.Properties["keywords"].Add("azureADId:$tenantId") $scpObj.CommitChanges() ``` --- ### Step 5: Configure Client Computers Once prerequisites are in place, domain-joining a Windows 11 24H2 client (with the September 2025 CU or later) triggers automatic Entra hybrid registration via Kerberos. This is the point where Hybrid Join briefly stops feeling like a punishment and starts acting like a feature. **For Autopilot:** this is the bit that needs to be stated precisely. The **ODJ Connector is still used** to perform the actual domain join during OOBE. Entra Kerberos does not replace that. What it replaces is the old registration dependency on Entra Connect device sync. In other words: the connector still gets the machine into AD, but Kerberos gets the machine registered in Entra ID without the old wait. That distinction matters, because the Microsoft Learn article for Entra Kerberos hybrid join is not an Autopilot article. It assumes the client is already being joined to the domain by whatever method you normally use and focuses on what happens *after* that point. ### Step 6: Verify On the client after the domain join and restart: ```cmd dsregcmd /status ``` You should see: ```text AzureAdJoined : YES DomainJoined : YES ``` If it didn't work, ensure your client can ping the WS2025 DC, and verify the SCP and DRS tags were applied correctly. And yes, if name resolution is broken, it is probably still DNS. I wish I had a more exciting answer there. ## Final Thoughts This feature is a godsend for environments stuck on Hybrid Join. It does **not** magically make Hybrid Autopilot cloud-native, and it does **not** remove the ODJ Connector from the equation. But it does remove the single most annoying part of the flow: waiting for directory sync just so the device can finish registration. However, my recommendation stands: **If you don't strictly need on-prem AD computer objects, go Cloud Native.** It's faster, more reliable, and a much cleaner operational model overall. But if you do have a real on-prem dependency and Hybrid Join is staying for a while, then this preview is the first version of Hybrid Autopilot in a long time that makes me think: *fine, I still don't love it, but at least now it makes technical sense.* And beyond Autopilot itself, I think this may end up being the feature that helps many organizations finally kick **Entra Connect Sync** out of the room. If device sync was the last excuse for keeping that old dependency alive, Entra Kerberos has just made that excuse a lot weaker. No flowers, no sad music, just a polite nod and a migration plan. And if you're touching this area anyway, do yourself another favor and lean into **Windows Hello for Business** while you're there. Passwordless plus Cloud Kerberos Trust is still one of the nicest improvements Microsoft has made in this whole identity stack. --- ## [The IT Admin's Guide to Horses: What Equines Can Teach Us About Enterprise Architecture](https://iphase.dk/posts/misc/the-it-admins-guide-to-horses) Date: 2026-03-13 Category: misc Tags: horses, enterprise-architecture, humor, analogies, it-admin-life # The IT Admin's Guide to Horses: What Equines Can Teach Us About Enterprise Architecture Five years ago, if you'd told me I'd be writing a blog post comparing horses to enterprise IT, I'd have assumed you were messing with me. But here we are. My wife is a horse person — like, *really* into horses and riding. After I started tagging along to the stables, and through our many conversations about equine care (mostly her talking while I nod with deep, husband-level understanding), it hit me: managing a herd of horses is weirdly similar to managing a fleet of enterprise endpoints. I know how that sounds. Stick with me, though. --- ## Horses Are Basically Endpoints ![Open Image: A stable corridor with horses in their stalls — tell me this doesn't look like a data center](/media/posts/misc/the-it-admins-guide-to-horses/stable-corridor-713886af7f.jpg) No, seriously. Each horse in a stable is an individual unit that needs to be: - **Provisioned** — acquired, registered, given a name - **Configured** — trained, fitted with the right saddle and bridle - **Maintained** — regular vet checks, farrier visits, dental care (yes, horse dentists are a thing) - **Monitored** — is it eating? limping? being weird? - **Retired** — hopefully to a nice pasture and not a landfill Swap "horse" with "Windows 11 device" and "farrier" with "Patch Tuesday" and you've basically got yourself an endpoint lifecycle document. ### The Onboarding Process When a new horse shows up at a stable, you don't just chuck it into the field with the others and cross your fingers. You quarantine it first. Check its health records. Introduce it to the herd gradually so nobody gets kicked. This should sound familiar if you've ever onboarded devices into an Entra ID tenant. Quarantine through Conditional Access. Health checks via compliance policies. Gradual rollout using deployment rings. Same playbook, different species. > **Pro tip:** If onboarding a laptop at your org involves fewer steps than onboarding a horse at my wife's stable, maybe have a look at your security posture. --- ## The Herd Hierarchy Is Just Active Directory ![Open Image: A herd of horses in the field — spot the lead mare and you've found your Domain Admin](/media/posts/misc/the-it-admins-guide-to-horses/herd-horses-ff007f6a38.jpg) Horses have a strict pecking order. There's always a lead mare who decides where the herd goes, when they eat, and when they move. Every other horse knows exactly where it stands relative to her. Tell me that's not just Active Directory with Organizational Units. | Horse Role | IT Equivalent | |-----------|--------------| | Lead mare | Domain Admin | | Stallion | That one senior engineer who *thinks* he runs everything but the lead mare actually does | | Geldings | Standard users — reliable, low drama, gets the job done | | Foals | Interns — curious, occasionally destructive, need someone watching them at all times | | The ancient pony that's been there forever | The Windows Server 2012 R2 box that nobody dares decommission | Point being: **hierarchy matters**. You wouldn't give a foal the same access as the lead mare, so stop handing out Global Admin to anyone who asks with a polite email. ### Least Privilege, Equine Style A well-run stable basically practices least privilege without even calling it that. Young horses start in a small paddock. As they prove they can handle themselves, they get access to bigger pastures. The ones that jump fences and cause havoc? Privileges revoked, immediately. Zero Trust for horses. I didn't make the rules. --- ## Feeding Schedules Are Just Patch Management Every horse needs to eat on a regular schedule. Miss a feeding and you get an agitated, unproductive animal. Feed them something wrong and you get colic — which, for horses, can genuinely be life-threatening. I was surprised when I learned that. These are massive powerful creatures and the wrong lunch can take them out. Patch management works almost the same way: - **Regular schedule**: Horses eat twice a day (actually, they would die if they only ate twice a day, but I have taken creative freedoms to get my point across). Your endpoints need patches monthly at minimum. - **Right content**: You wouldn't feed a horse cement. Don't push untested patches to production. - **Consequences of neglect**: Unfed horse gets sick. Unpatched endpoint gets ransomware. Neither is a fun phone call. - **Staged rollout**: Smart stable managers mix new feed in with the old stuff gradually over several days. Smart IT admins use deployment rings. Same idea, different grain. > **Warning:** In both worlds, ignoring the schedule because "everything seems fine right now" is exactly how you end up with an emergency at 2 AM on a Saturday. --- ## The Farrier Is Your Update Baseline ![Open Image: A farrier at work — this is what your compliance baseline should feel like](/media/posts/misc/the-it-admins-guide-to-horses/farrier-sparks-471f3c185e.jpg) So a farrier — for those who don't know, and I certainly didn't before all this — trims and shoes horses' hooves roughly every 6 to 8 weeks. Skip that appointment and the problems start compounding. Cracked hooves, then lameness, then posture issues that cascade through the whole body. Ring any bells? That's what happens when you skip your configuration baselines and compliance checks. A missed security setting here, an outdated policy there, and before you know it the whole environment is limping along under a pile of technical debt you didn't notice accumulating. The farrier doesn't care that the horse "looks fine." Every hoof gets checked, every time. Be the farrier of your IT environment. (I can't believe I just typed that sentence, but I stand by it.) --- ## Horses Spook at Everything (Just Like End Users) One thing I picked up quickly at the stables: horses are prey animals. They're wired to treat *anything* new or unexpected as a potential threat. Plastic bag blowing across the path? **Full panic.** Someone left a wheelbarrow in a slightly different spot? **Life-or-death situation, apparently.** End users handle IT changes with roughly the same composure. - New login screen? "I think I've been hacked." - MFA prompt they've seen literally hundreds of times? "This looks different. I'm calling the helpdesk." - Scheduled maintenance you announced three times over email, Teams, and a desktop banner? "Nobody told me about this!" The fix is the same for horses and humans: **gradual, consistent exposure**. Horse people call it desensitization. We call it change management and user awareness training. Both take patience, both take repetition, and honestly, some individuals are just always going to freak out about plastic bags. You learn to accept it. --- ## Backup Horses and Disaster Recovery Every serious riding stable has a plan for when a horse goes lame. You don't cancel the whole lesson — you've got backup horses. Different sizes, different temperaments, but trained and ready to step in. That's your disaster recovery plan right there. Production server goes down, failover kicks in. Primary cloud region has an outage, traffic routes to the secondary. The concept isn't complicated; it's the *having actually set it up and tested it* part that trips people up. The stables running without backup horses are the same organizations running without tested backups. Everything works great right up until the moment it catastrophically doesn't. ### The Horse Trailer Is Your Migration Tool When you need to move a horse between stables, you use a horse trailer. The horse doesn't love it. There's usually some amount of "I am NOT getting in there." But with the right prep and a calm handler, horse gets from A to B in one piece. Cloud migrations, same deal. Users don't want to move. There will be resistance, there will be complaints, someone will insist the old system was better. But solid planning, clear communication, and a steady hand gets everyone across without losing anything critical. > **Note:** In both situations, there's always that one individual who flat-out refuses to get on the trailer. You know exactly which user I mean. And my wife definitely knows the horse. --- ## What This Actually Taught Me Alright, jokes aside for a second. Spending time at the stables and — let's be honest — absorbing my wife's expertise through osmosis has reinforced a few things that I think genuinely apply to how we run IT environments: **Consistency is everything.** Horses thrive on routine. If something changes without warning, they get stressed and start acting out. Same goes for your infrastructure. Standardize your processes, automate what you can, keep things predictable. **Catch problems early.** A good horse person spots subtle changes in behavior before they turn into real issues. An ear position, a slight change in gait, eating less than usual. Good monitoring does the same thing — you want to know about the small anomalies before they snowball. **You can't force compliance.** Well, technically you can — once. But you'll never build trust that way, and the horse (or the user) will fight you every time after that. Sustainable security culture comes from people actually understanding *why* they're being asked to do something, not from mandates and lockdowns. **Don't skip the basics for the flashy stuff.** An expensive saddle means nothing if the horse's hooves haven't been trimmed. A cutting-edge SIEM means nothing if half your staff clicks on phishing links. Fundamentals first, always. **Rest matters.** Horses need downtime or they break down and underperform. IT teams need the same thing. Burnout is real, and a tired admin makes mistakes the same way a tired horse stumbles. I've been on both sides of that late-night incident call. Take care of your people. --- ## Wrapping Up So next time someone gives you a look for reading about horse care instead of prepping for your next Microsoft certification, just tell them it's cross-disciplinary research into resilient systems architecture. They won't buy it. But you'll know the truth. And if you ever find yourself managing both a herd of horses and a fleet of endpoints — the horses are at least honest with you when something's wrong. --- Got your own unlikely IT analogy? I'd love to hear it — find me on [LinkedIn](https://linkedin.com/in/michael-mardahl). I'm always on the lookout for new ways to explain Zero Trust to people who glaze over the second you say "Zero Trust." > **Disclaimer:** No horses were harmed in the writing of this post. Several endpoints were rebooted, but honestly they had it coming. --- ## [No VPN, No Internet: Building a Windows Firewall Kill Switch for FortiClient with Intune](https://iphase.dk/posts/intune/forticlient-vpn-kill-switch-windows-firewall-intune) Date: 2026-03-01 Category: intune Tags: intune, vpn, forticlient, windows-firewall, kill-switch # No VPN, No Internet: Building a Windows Firewall Kill Switch for FortiClient with Intune FortiClient VPN kill switch using Windows Firewall and Intune. In this post you will learn how to prevent Windows 11 machines from accessing the internet when not connected to your corporate VPN — and all the things that go wrong along the way. > **Disclaimer:** This is a proof-of-concept that has not been thoroughly tested across all environments at the time of writing. Your mileage may vary. But sharing is caring, so here we are. Do your own tests before deploying this to production, Mmmkay? If you need a *real* kill switch, skip to the "The elephant in the room" section at the end. --- Ever had one of those "perfectly reasonable" requests that spirals into a full-blown deep dive through Windows Firewall internals, adapter classification quirks, and chicken-and-egg problems you didn't know existed? Yeah, me too. Just recently, in fact. Of course, like every other person trying to keep up with all the new stuff these days, I used AI to help me work through the problem. Specifically, I paired up with **Claude** (Anthropic's AI) and together we iterated through solutions in real time. So when I say "we" throughout this post, I mean me and my tireless AI colleague who never once complained about the fifth script rewrite. Good times. Let me share the journey with you good folks reading this blog, because I think it might save someone out there from going mad. ## The problem The environment: Windows 11 devices running the standalone **FortiClient VPN** (no EMS, no FortiGate integration beyond the tunnel itself). The requirement: **if the VPN is down, the internet is off.** Local network traffic? Fine. Public internet? Not without the tunnel. How hard could it be? (*Narrator: it was hard-ish.*) ## The obvious answer (that wasn't) The first instinct is the right one: use the **Windows Firewall**. Set the default outbound action to Block, add allow rules for the VPN client, and call it a day. It's built into the OS, it's free, it doesn't require third-party software, and it survives reboots. What's not to love? Well, as it turns out, quite a lot. ## Attempt 1: Block everything, allow the VPN adapter The initial approach was straightforward: 1. Set `DefaultOutboundAction` to `Block` on all firewall profiles 2. Allow FortiClient executables so the VPN can establish 3. Allow traffic on the Fortinet VPN adapter by its `InterfaceAlias` Step 3 is where the first crack appeared. The `New-NetFirewallRule` cmdlet with `-InterfaceAlias` does not play nicely with virtual VPN adapters. The adapter exists in a sort of Schrödinger's state — it's technically present even when the VPN is disconnected, but the firewall doesn't always agree that it's a real interface worth filtering on. We also briefly explored using `InterfaceTypes = RemoteAccess` to scope rules to the VPN adapter. Sounds right — it's a remote access tunnel, after all. But FortiClient's virtual adapter doesn't necessarily register as `RemoteAccess` in Windows. Depending on the driver version and VPN type (SSL vs IPsec), it can show up as `Lan`. You can check what Windows actually thinks with `Get-NetAdapter | Select-Object Name, InterfaceDescription, NdisPhysicalMedium` — and you should, before trusting any `InterfaceTypes`-based rule. **Q:** What error did you get? **A:** An unhelpful one. As is tradition with Windows Firewall. ## Attempt 2: The profile trick With some digging, we discovered something promising. When FortiClient's SSL VPN connects, its virtual adapter (`Fortinet SSL VPN Virtual Ethernet Adapter`) registers under the **Domain** firewall profile — because the tunnel reaches the corporate network where a Domain Controller lives. Meanwhile, the physical NIC sits on **Public** or **Private**. This led to an elegant idea: block outbound on Public and Private, leave Domain as Allow. The VPN tunnel traffic flows through the Domain-profile adapter, so everything works once connected. Except it didn't. The VPN adapter starts its life as **Public**. Windows NLA (Network Location Awareness) needs to reach a Domain Controller to reclassify the adapter as Domain. But we've blocked outbound on Public. So NLA can't reach the DC. So the adapter stays Public. So traffic stays blocked. So NLA can't reach the DC... This is what we in the industry call a **chicken-and-egg problem**, and what I in the moment called something my mother wouldn't approve of. **Side note for the curious:** This NLA behavior is actually a known issue documented by Fortinet. When FortiClient connects, route installation lags behind adapter creation, so NLA can't reach the DC in time. Even without our firewall blocking, the profile flip is unreliable. Fortinet's workaround is to set `NegativeCachePeriod = 0` in `HKLM\SYSTEM\CurrentControlSet\Services\NetLogon\Parameters`. But even with that fix, the timing remained too unpredictable for our use case. ## Attempt 3: Allow svchost — surely THAT fixes it NLA runs as a service inside `svchost.exe`. If we allow svchost outbound on all profiles, NLA can reach the DC, detect the domain, flip the adapter to Domain profile, and our elegant solution works. It did not work. Even with svchost allowed, the NLA detection through a VPN tunnel proved unreliable. The adapter stubbornly remained on Public. Whether this was a timing issue, a caching issue, or Windows simply having a bad day — the result was the same: no Domain profile, no internet. I did find a few discussions online about scripts and reg settings to solve this, but I did not want to go down that route in this PoC. This is where I went full **Claude Opus 4.6 extended thinking mode**. We threw everything at it — restarting the NLA service, adding delays, praying to the firewall gods. Nothing. The profile would not flip consistently. ## The breakthrough: Stop fighting profiles After several rounds of increasingly creative (and decreasingly dignified) troubleshooting, the solution came from stepping back and asking: *why are we fighting the profile system at all?* The VPN runs in **full-tunnel mode**. That means when it's connected, *all* traffic — including internet-bound traffic — routes through the tunnel. And what does the tunnel look like from a routing perspective? It's a gateway on a **private IP address**. That's the key insight right there. Instead of trying to detect which profile the adapter is on, we can "simply": 1. **Block all outbound** on all profiles (Domain, Private, Public) 2. **Allow outbound to all private IP ranges** (RFC1918 + link-local + multicast + loopback) 3. **Allow FortiClient executables** (so the VPN tunnel can establish to the public gateway) 4. **Allow svchost.exe** (for DNS, DHCP, NCSI, and NLA) 5. **Allow Intune and Defender** (so the device stays managed and protected — more on this later) When the VPN is disconnected, the device can only talk to private IPs — local network, printers, file shares, all fine. But no public internet. When the VPN connects, the full-tunnel routes all traffic through the tunnel's private gateway IP, which is allowed by our RFC1918 rule. Internet works, routed through the corporate network. No profile detection needed. No adapter alias games. No NLA timing issues. Beautiful. The private IP ranges we allow: | Range | Purpose | | --- | --- | | `10.0.0.0/8` | RFC1918 Class A | | `172.16.0.0/12` | RFC1918 Class B | | `192.168.0.0/16` | RFC1918 Class C | | `169.254.0.0/16` | Link-local / APIPA | | `224.0.0.0/4` | Multicast | | `255.255.255.255/32` | Broadcast | | `127.0.0.0/8` | Loopback | ## Keeping the device managed: Intune agents and Defender Now, blocking all outbound is a bold move. You know what also needs outbound access to keep working? The very system that's enforcing your policy. Don't lock yourself out of the house, folks. We need to make sure the **Intune management agents** and **Windows Defender** can phone home regardless of VPN state. **Intune Management Extension:** | Process | Path | | --- | --- | | IME Agent | `C:\Program Files (x86)\Microsoft Intune Management Extension\Microsoft.Management.Services.IntuneWindowsAgent.exe` | | AgentExecutor | `C:\Program Files (x86)\Microsoft Intune Management Extension\AgentExecutor.exe` | | ClientHealthEval | `C:\Program Files (x86)\Microsoft Intune Management Extension\ClientHealthEval.exe` | | SensorService | `C:\Program Files (x86)\Microsoft Intune Management Extension\SensorService.exe` | **Other system processes:** | Process | Path | | --- | --- | | Device Enroller | `C:\Windows\System32\deviceenroller.exe` | **Windows Defender** — and here's a fun one. Defender's executables (`MsMpEng.exe`, `MpCmdRun.exe`, `NisSrv.exe`) live under `C:\ProgramData\Microsoft\Windows Defender\Platform\\`. That version folder changes with every Defender update. **Q:** Can't you just use a wildcard path? **A:** No. And I know this because I tried it years ago, and it didn't work. Microsoft's own documentation confirms: **wildcard patterns like `C:\*\executable.exe` are not supported in Windows Firewall application rules.** Only full paths. Still. In 2026. Cool. The workaround is to use the **service name** filter instead of the file path. Windows Defender runs as the `WinDefend` service, and Intune firewall rules have a dedicated "Service name" field. Problem solved — and version-folder-proof. **Q:** What about the OMA-DM client for Intune sync? **A:** It runs inside `svchost.exe` via the `dmwappushservice`, so that's already covered by our svchost allow rule. Same goes for Windows Update and BITS. ## The rule bypass problem With the default outbound set to Block, the next issue was that **Windows ships with dozens of pre-existing outbound allow rules**. Any one of these could let traffic escape without VPN. Worse, any application installed with admin privileges can create *new* outbound allow rules at will. This is where the deployment method matters - and where we need to talk about doing this properly. ## The Intune solution (the right way) The production-grade approach uses two Intune **Endpoint Security > Firewall** policies. Both are created in the same place: 1. Open the **Intune admin center** ([intune.microsoft.com](https://intune.microsoft.com)) 2. Navigate to **Endpoint security > Firewall** 3. Click **Create policy** 4. Platform: **Windows** From there, the **Profile** dropdown is where the two policies diverge: * For Policy 1, select **Windows Firewall** — this is where profile-level defaults live * For Policy 2, select **Windows Firewall Rules** — this is where individual allow/block rules go ### Policy 1: Windows Firewall Profile This configures the firewall defaults for all three profiles: * **Default Outbound Action**: Block * **Ignore all local firewall rules**: Yes * **Ignore authorized application firewall rules**: Yes * **Ignore global port firewall rules**: Yes * **Ignore connection security rules**: Yes * **Allow Local Policy Merge**: No Those four "Ignore" settings are the critical piece. They tell the firewall to **disregard every rule in the local store** — including Windows defaults and anything installed by software. Only rules delivered via Intune's Endpoint Security Firewall Rules policy are active. This completely eliminates the rule bypass problem. No software can add its own exceptions. No user can create a sneaky allow rule. The MDM policy store is king. The `AllowLocalPolicyMerge = No` setting (via `./Vendor/MSFT/Firewall/MdmStore/{Profile}/AllowLocalPolicyMerge`) is the belt to the "Ignore" suspenders. Without it, locally-added rules can still merge into the active policy store and create bypass paths. Set it on all three profiles. ### Policy 2: Windows Firewall Rules This delivers the specific allow rules. Here's the full set: **Infrastructure rules:** | Rule | Direction | Action | Details | | --- | --- | --- | --- | | Allow Private IPs | Out | Allow | Remote addresses: `10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`, `169.254.0.0/16`, `224.0.0.0/4`, `255.255.255.255/32`, `127.0.0.0/8` | | Allow svchost | Out | Allow | File path: `C:\Windows\System32\svchost.exe` | | Allow Device Enroller | Out | Allow | File path: `C:\Windows\System32\deviceenroller.exe` | | Allow Defender (WinDefend) | Out | Allow | Service name: `WinDefend` (no file path — avoids the version folder problem) | **FortiClient rules** (one per executable, all Outbound / Allow): | Rule | File Path | | --- | --- | | Allow FortiClient | `C:\Program Files\Fortinet\FortiClient\FortiClient.exe` | | Allow FortiClientConsole | `C:\Program Files\Fortinet\FortiClient\FortiClientConsole.exe` | | Allow FortiClientSecurity | `C:\Program Files\Fortinet\FortiClient\FortiClientSecurity.exe` | | Allow FortiSSLVPNdaemon | `C:\Program Files\Fortinet\FortiClient\FortiSSLVPNdaemon.exe` | | Allow FortiSSLVPNsys | `C:\Program Files\Fortinet\FortiClient\FortiSSLVPNsys.exe` | | Allow FortiTray | `C:\Program Files\Fortinet\FortiClient\FortiTray.exe` | | Allow FortiVPN | `C:\Program Files\Fortinet\FortiClient\FortiVPN.exe` | | Allow FortiGui | `C:\Program Files\Fortinet\FortiClient\FortiGui.exe` | | Allow FortiAuth | `C:\Program Files\Fortinet\FortiClient\FortiAuth.exe` | | Allow FCAuth | `C:\Program Files\Fortinet\FortiClient\FCAuth.exe` | | Allow FCCOMInt | `C:\Program Files\Fortinet\FortiClient\FCCOMInt.exe` | | Allow FCConfig | `C:\Program Files\Fortinet\FortiClient\FCConfig.exe` | | Allow ipsec | `C:\Program Files\Fortinet\FortiClient\ipsec.exe` | | Allow FSSOMA | `C:\Program Files\Fortinet\FortiClient\FSSOMA.exe` | **Intune Management Extension rules** (one per executable, all Outbound / Allow): | Rule | File Path | | --- | --- | | Allow IME Agent | `C:\Program Files (x86)\Microsoft Intune Management Extension\Microsoft.Management.Services.IntuneWindowsAgent.exe` | | Allow AgentExecutor | `C:\Program Files (x86)\Microsoft Intune Management Extension\AgentExecutor.exe` | | Allow ClientHealthEval | `C:\Program Files (x86)\Microsoft Intune Management Extension\ClientHealthEval.exe` | | Allow SensorService | `C:\Program Files (x86)\Microsoft Intune Management Extension\SensorService.exe` | That's **23 rules** total — well within Intune's 150-rule-per-policy limit. Plenty of room for your future "oh wait, we also need *this*" moments. ### Why two policies? (Blame Intune) You might be wondering why we don't just put everything in one policy. So did I. The answer is: Intune won't let you. The firewall *profile* settings (`DefaultOutboundAction`, the "Ignore" toggles, `AllowLocalPolicyMerge`) and the firewall *rules* (individual allow entries) are separate policy templates under Endpoint Security > Firewall. You can't mix them. Two policies is not a design choice — it's a constraint. Just make sure you assign both policies to the same group. If a device somehow gets the block profile without the allow rules, nothing goes outbound — including Intune sync — and you'll need physical access to unenroll from MDM. Don't do that to yourself. ### Verification After both policies apply, run these on a target device: ```powershell # Confirm outbound is blocked Get-NetFirewallProfile | Format-Table Name, DefaultOutboundAction # Confirm only Intune rules are active Get-NetFirewallRule -PolicyStore ActiveStore -Direction Outbound -Action Allow -Enabled True | Format-Table DisplayName # Test: VPN off, no internet Test-NetConnection google.com -Port 443 # Test: VPN on, internet works Test-NetConnection google.com -Port 443 ``` ## The PoC scripts (for testing only) During the development of this solution, we wrote PowerShell setup and undo scripts to rapidly iterate without waiting for Intune sync cycles. I've published these to GitHub so you can use them for your own testing: > **GitHub**: [github.com/mardahl/PSBucket/tree/master/FortinetVPNKillSwitch](https://github.com/mardahl/PSBucket/tree/master/FortinetVPNKillSwitch) > > - `Setup-VPNKillSwitch.ps1` — Applies the kill switch configuration > - `Undo-VPNKillSwitch.ps1` — Reverts to the previous firewall state > - `Detect-VPNKillSwitch.ps1` — Detection script for Intune Win32 packaging **Important:** These scripts were built as proof-of-concept tooling to iterate quickly during development. They do **not** include all the Intune Management Extension, Device Enroller, and Windows Defender exclusions that we recommend for production use. If you use the scripts as-is, Intune sync and Defender updates may be blocked when the VPN is disconnected. For a complete production deployment, use the Intune Firewall Policy approach described above. ### The security caveat: scripts vs. Intune policy Here's the important distinction: **the PowerShell scripts and the Intune Firewall Policy are not equivalent from a security perspective.** The scripts manipulate the **local firewall store**. This means: * Any local administrator can undo them * Any software running with admin privileges can add outbound allow rules that bypass the block * The scripts disable pre-existing rules, but new ones can appear at any time * There is no continuous enforcement — if someone reverts the changes, they stay reverted The Intune Firewall Policy leverages the **MDM policy store** and the "Ignore local rules" CSP settings. This means: * Local firewall rules are completely inactive — even if they exist, they have no effect * New rules created locally are also ignored * The policy is continuously enforced and re-applied on every Intune sync * Users cannot override it without unenrolling from Intune **Use the scripts for testing. Use Intune for production.** ## What this doesn't cover (the honest part) Alright, I spent a few hours on this and it works for a PoC. But if you're thinking of deploying this as a *security control* rather than a *convenience feature*, here's the list of things that will keep a security auditor up at night. I'm sharing these not to undermine the solution, but because honesty is more useful than false confidence. ### IPv6: The silent leak Everything above is IPv4 only. Windows has IPv6 enabled by default, and IPv6 traffic — including Teredo tunneling — will happily bypass your carefully crafted IPv4 rules. If you're serious about this, you need parallel IPv6 blocking rules, or you need to disable IPv6 on all physical adapters and kill Teredo with `netsh interface teredo set state disabled`. This is the kind of thing that's easy to forget and embarrassing to discover. ### svchost.exe: The skeleton key Yes, allowing `svchost.exe` outbound on all profiles is necessary. It's also a *massive* hole. Svchost hosts DNS, DHCP, BITS, Windows Update, NLA, the OMA-DM client, and roughly a hundred other services. By allowing it unrestricted outbound access, we've effectively given a large chunk of Windows networking a free pass to talk to the internet without VPN. Any service running under svchost can reach out. For a PoC, this is acceptable. For a security-hardened deployment, you'd want to scope this down — for example, allowing svchost only for specific service SIDs (like `dnscache` and `Dhcp`) or restricting it to specific remote ports (53, 67, 68) and destination IPs. The Firewall CSP supports the `ServiceName` filter on rules, which helps. But doing this correctly is a project in itself, and I didn't want to overengineer a PoC. ### Captive portals: Mostly fine, actually Since we allow all RFC1918 traffic and svchost handles DNS, most captive portals just work. The device gets DHCP, DNS resolves, and the portal login page — typically hosted on the gateway's private IP — is reachable by any process. The user authenticates, the network opens, and public internet remains blocked until the VPN connects. Exactly as intended. The one edge case: some enterprise WiFi systems redirect to a **cloud-hosted** authentication portal on a public IP. That would be blocked. In practice, this is uncommon for typical hotel and airport WiFi, but it's worth knowing it's possible. ### Boot-time gap Between system startup and when the Base Filtering Engine (BFE) service initializes, traffic can flow unfiltered. Standard Windows Firewall rules provide no boot-time protection. Professional VPN clients solve this with persistent WFP boot-time filters — a capability not available through the Firewall CSP. For most use cases this gap is measured in seconds and is largely theoretical, but it exists and a thorough security review would flag it. ### WFP sublayer ordering The Windows Firewall operates in a specific WFP (Windows Filtering Platform) sublayer. Other applications — including some VPN clients, endpoint security products, and even malware — can create their own WFP sublayers with higher weights that *override* the firewall's block with a hard Permit. Your Windows Firewall kill switch is only as strong as the assumption that nothing else is manipulating WFP at a higher priority. In practice this is rarely an issue on managed devices, but it's worth knowing. ### CVE-2024-3661 (TunnelVision) This is a fun one. A rogue DHCP server on the local network can inject static routes via DHCP Option 121, causing traffic to bypass the VPN tunnel entirely while the VPN *appears* to be connected. Our approach — blocking by default and allowing private IP ranges — should mitigate TunnelVision better than a route-based kill switch, because traffic is still constrained by firewall rules rather than routing table entries. But "should mitigate" and "definitely mitigates" are different things, and I haven't tested this specific attack against the PoC. If this threat vector matters to you, test it. ### FortiClient executable allow rules We're allowing 14 FortiClient executables to talk outbound to *any* destination. That's necessary for the VPN to establish its tunnel to the public gateway. But it also means those executables can reach any IP on the internet, VPN or not. If any of those binaries were compromised or had a vulnerability, they'd have unrestricted outbound access. A tighter approach would restrict them to the specific VPN gateway IP(s) — if your environment has a small, stable set of gateways. ## The elephant in the room: FortiClient EMS Network Lockdown I'd be doing you a disservice if I didn't mention this. If you're running FortiClient with **FortiClient EMS** (the paid, managed version), Fortinet already built exactly what we're trying to build here. It's called **Network Lockdown**, introduced in FortiClient 7.2.1 for SSL VPN and extended to IPsec in 7.2.5. Network Lockdown does everything our PoC does, plus: * **Captive portal detection** with a configurable grace period (default 120 seconds) * **Exception lists** for allowed applications, IPs, and domains * **Automatic enforcement** that doesn't depend on Windows Firewall or WFP sublayer ordering * **Centralized management** through the EMS console It handles the edge cases we listed above — IPv6, boot-time protection, WFP sublayer ordering — properly and out of the box. The reason we went down the Windows Firewall path is that this environment uses the **standalone free FortiClient VPN** — no EMS, no FortiGate fabric integration. If that's your situation too, this PoC is a reasonable starting point. But if you have EMS licensing (or can justify the cost), **use Network Lockdown instead**. It's purpose-built for this exact problem and it handles the edge cases properly. The Windows Firewall approach is a *can we do this?* exercise. Network Lockdown is the *should we do this?* answer. ## Final Words What started as "just block outbound and allow the VPN" turned into a tour through Windows Firewall profile classification, NLA detection quirks, virtual adapter behavior, wildcard paths that Microsoft still doesn't support in 2026, and the nuances of local vs. MDM policy stores. The final solution is relatively simple: block all outbound, allow private IPs, allow the VPN client, allow svchost, allow Intune agents, and allow Defender by service name. Five concepts, twenty-three rules, two Intune policies, and the *reasonable expectation* that your users aren't browsing the internet from a hotel Wi-Fi without the corporate tunnel. Is it perfect? No. The honest-to-goodness truth is that a few hours of work with Windows Firewall and Intune gets you maybe 80% of the way to a real kill switch. The remaining 20% — IPv6, boot-time gaps, WFP sublayer shenanigans, svchost being a wide-open door — is where commercial solutions earn their keep. But for a PoC that demonstrates the concept and blocks the casual "I'll just disconnect the VPN and browse directly" scenario? It works. The journey to get there was anything but simple. But that's why we share, right? Please bear in mind that this knowledge is shared for learning purposes only. Do your own tests before deploying this into production environments. --- > **Final disclaimer:** This is a proof-of-concept. It was born from real-world need and tested on a limited set of devices, but it has not been validated across every FortiClient version, Windows 11 build, or network configuration. The Intune policies and PowerShell scripts are provided as-is with no warranty. If you find issues or improvements, contribute back to the [GitHub repo](https://github.com/mardahl/PSBucket/tree/master/FortinetVPNKillSwitch). Sharing is caring! *And if you've found an even more creative way for NLA to refuse to detect a domain network, reach out — misery loves company.* --- ## [Passkeys and the Personal Phone Problem – An MFA Update for 2026](https://iphase.dk/posts/identity/passkeys-personal-phone-mfa-update) Date: 2026-01-10 Category: identity Tags: entra-id, fido2, mfa, microsoft-authenticator, passkey, passwordless, zero-trust > UPDATED March 2026 - This post has been reviewed and updated to reflect current Microsoft product names, portal locations, and technology status. See inline notes for specific changes. This article is an update to my original [2023 post on the importance of MFA](/posts/identity/why-multi-factor-authentication-is-important/). A lot has changed since then - Microsoft is now *mandating* MFA, and passkeys have evolved from the "cool new thing" to "the only right thing." Here's what's new-ish and why your employees' personal phones are not the privacy nightmare they think they are. --- **Quick Facts: Passkeys & Microsoft MFA Mandate** - **Microsoft MFA Mandate Phase 1** - Azure Portal, Entra admin center, Intune admin center - 100% enforced since March 2025 - **Microsoft MFA Mandate Phase 2** - Azure CLI, PowerShell, IaC tools - Enforced since October 2025 - **Microsoft 365 Admin Center** - Full enforcement February 9, 2026 (next month at the time of writing!) - **Passkey Types** - Synced Passkeys (cloud-synced, recoverable) vs. Device-Bound Passkeys (hardware-locked, attestable) - **Microsoft Authenticator Unique Feature** - Only major authenticator app supporting device-bound passkeys afaik - **Self-Enrollment** - Users can set up passkeys 100% on their smartphone - no IT intervention required (nice!) --- ## Microsoft is Done Asking Nicely Remember when MFA was a "best practice" and "highly recommended"? Those days are over. Microsoft has officially moved from gentle suggestions to mandatory enforcement as part of their Secure Future Initiative. And honestly? As an IT admin who's been advocating for stronger authentication for over 20 years, this mandate is overdue. The challenge now isn't deciding whether to implement MFA or not - it's how to deploy phishing-resistant methods efficiently. > **Key stat:** MFA blocks more than 99.2% of account compromise attacks. That's not a typo. Ninety-nine point two percent bro! **Phase 1** enforcement hit the Azure Portal, Microsoft Entra admin center, and Intune admin center with full enforcement back in March 2025. If you're an admin who hasn't set up MFA yet... well, hope you like dealing with the Data Protection Team at MS Support and have all the time in the world. **Phase 2** kicked in October 2025 and now covers Azure CLI, PowerShell, and all those Infrastructure as Code tools you've been automating with. The good news? [Read operations don't require MFA - only Create, Update, and Delete operations. So your monitoring scripts can breathe easy.](https://learn.microsoft.com/en-us/entra/identity/authentication/concept-mandatory-multifactor-authentication?tabs=dotnet#:~:text=Read%20operations%20won%27t%20require%20MFA.) The Microsoft 365 Admin Center hits full enforcement on February 9, 2026 - that's next month. If you're not ready, now's the time to get moving (Or opt-in for an extension until July!). Even if YOU have MFA setup - how about a billing admin or what not? ## Passkeys Have Grown Up ![Open Image: Illustration that Passkeys have grown up by showing a small dog and a big dog](/media/posts/identity/passkeys-personal-phone-mfa-update/passkeys_have_grown_up-d7b2033ac0.png) If you've been following this blog, you know I've been banging the [FIDO2 drum since 2019](https://msendpointmgr.com/tag/fido2/). Back then, it was all about hardware security keys and convincing skeptical IT teams that passwordless wasn't just a fantasy. Well, the fantasy is now reality - and it lives in your pocket and on extensions like 1Password and is rebranded under the term Passkeys. There are two flavours of passkeys you need to understand: ### Synced Passkeys These are the consumer-friendly option. Your passkey gets encrypted and synced across your devices via cloud services like iCloud Keychain, Google Password Manager, 1Password, or Dashlane. Lost your phone? No problem - your passkey is waiting for you on your new device as soon as you restore from backup. The trade-off? Organizations can't cryptographically verify which device created the credential (no attestation support). For most scenarios, this is perfectly fine. For your CFO's account that authorizes wire transfers? Maybe not. ### Device-Bound Passkeys These are the enterprise security team's dream. The private key is generated and stored entirely within the device's secure hardware - Secure Enclave on Apple devices, TPM on Windows, TEE on Android. It never leaves. Ever. Not even encrypted. If someone steals your phone, they still can't extract the passkey. If you lose your phone, that passkey is gone forever (which is why you need backup authentication methods and maybe [SSAR](/posts/identity/self-service-account-recovery-ssar/)). The advantage? Full attestation support. Your organization can verify exactly which authenticator created the credential, its firmware version, and its FIDO certification level. This is how you enforce policies like "only passkeys created on FIPS 140-3 compliant authenticators can access sensitive resources." > **NIST says:** Both passkey types are officially recognized as phishing-resistant authenticators. Synced passkeys meet AAL2 requirements, while device-bound passkeys can meet AAL3 for scenarios requiring non-exportable private keys. [Read the boring details on their website](https://pages.nist.gov/800-63-4/sp800-63b/authenticators/#verifimpers) ## Microsoft Authenticator: The Quiet Differentiator Here's something that doesn't get talked about enough: Microsoft Authenticator is the **only** major authenticator app that supports device-bound passkeys. Let me repeat that, because it's important. Google Authenticator? TOTP only - not even a passkey manager. Google Password Manager? Synced passkeys only. 1Password? Synced. Bitwarden? Synced. Apple Keychain? Hardware-generated but synced. Microsoft Authenticator? **Device-bound only.** ![Open Image: Microsoft Authenticator passkey screenshot](/media/posts/identity/passkeys-personal-phone-mfa-update/image-8-4f6b36028c.png) This is a deliberate design choice for organizations with strict security requirements. Your passkey credentials cannot be synced, shared, exported, or recovered. They live and die with the device. For regulated industries - finance, government, healthcare - this is exactly what compliance teams have been asking for and why I personally swear by the MS Authenticator app! And before you ask: yes, Microsoft Entra ID (the identity platform) supports *both* types. You can use device-bound passkeys through Microsoft Authenticator AND allow synced passkeys through third-party providers. Best of both worlds, depending on your risk appetite. ## The Elephant in the Room: Personal Phones ![Open Image: Passkeys on personal devices is a good thing - trust!](/media/posts/identity/passkeys-personal-phone-mfa-update/myprecious_smartphone_passkeys-7ed89dbf3b.png) As an IT admin, you're about to face the most common deployment roadblock: employee resistance to using personal devices for work authentication. When companies don't provide corporate phones, this conversation becomes inevitable. Here are the objections your users will raise: - "I don't want my employer spying on me!" - "They'll track my location!" - "What if they can see my personal stuff?" - "It's MY phone, not theirs!" - "They can pay me to use it!" - "It takes up space on my phone and uses my data!" These concerns stem from psychology, not facts. Your job is to communicate the technical reality clearly and compassionately. Here's some ammunition you need for those conversations. ### What to Tell Users: Data Privacy Facts Arm yourself with these facts when addressing privacy concerns. Microsoft Authenticator does NOT give IT departments access to: - **Personal accounts are completely invisible** - Your personal Microsoft account, Google account, Amazon TOTP codes, that crypto wallet 2FA? IT admins cannot see any of it. Period. - **No backdoor device access** - Adding a work account inside Authenticator does not magically grant IT access to your photos, messages, contacts, browsing history, or other apps. - **OTP secrets stay local** - The codes generated by Authenticator are never transmitted anywhere. They're computed locally on your device. - **Location is NOT tracked by default** - Unless your organization has specifically configured GPS-based Conditional Access policies (and you'd see a prompt asking permission), the app doesn't track where you are. ### What Your Organization Actually Sees (And How to Explain It) Be transparent with users about what limited data your organization receives for work/school accounts only when they authenticate and tell them these facts: - Device registration status and compliance (is it encrypted? has a passcode?) - Device name and OS version - When authentication events occur (sign-in logs) - IP address of sign-in attempts - Country location ONLY if GPS Conditional Access is enabled - and even then, Microsoft stores only the country name, never coordinates (And it is only at the time of accepting an MFA Prompt) "That's it dear Employee. Your employer cannot remote-wipe your personal photos. They cannot read your WhatsApp messages. They cannot see that you've been doom-scrolling social media during meetings. (They might suspect it, but Authenticator won't tell them.)" ### Your Best Talking Point: Passkeys Increase Privacy Here's your strongest argument when users push back: passkeys on their personal phone actually provide **more privacy** than traditional authentication. Help them understand this counter-intuitive truth: With password-based authentication, your organization's servers log every detail of the sign-in: password hash verification, device fingerprint, network information, behavioral patterns. The authentication happens on *organizational* servers. With passkeys, the cryptographic verification happens locally on *the user's* device. Your servers only receive a signed challenge - they never see the user's biometric, PIN, or private key. The device proves identity without revealing *how* it knows the user is legitimate. > **Strategy note:** Frame this deployment requirement the same way you'd frame any workplace technology requirement. The resistance is psychological, not technical. Your role is to provide facts, address specific concerns, and demonstrate that the organization respects user privacy while maintaining security. Fear comes from lack of understanding - clear communication is what makes or breaks your rollout (start with the C-level folks). ## Self-Enrollment: Why This Changes Everything One of the most underappreciated aspects of passkeys in Microsoft Authenticator is the self-enrollment capability. Your users can set up passkeys **100% on their own smartphone**, without any IT intervention whatsoever - literally, they can do the whole process just on the phone without even having access to a normal desktop. ![Open Image: Self-enrollment passkey setup screenshot](/media/posts/identity/passkeys-personal-phone-mfa-update/Screenshot-2026-01-10-at-16.49.23-1024x270-88e79354e5.png) Requirements are simple: iOS 17+ or Android 14+ (15 recommended), Microsoft Authenticator installed, and you must have enabled "Allow self-service set up" for Passkey (FIDO2) in Entra ID. [The process takes about two minutes:](https://learn.microsoft.com/en-us/entra/identity/authentication/how-to-register-passkey-authenticator?tabs=iOS) 1. Download Microsoft Authenticator 2. Add work/school account 3. Complete existing MFA verification (look up Temporary Access Pass, it is a godsend for this situation) 4. Enable Authenticator as passkey provider in device settings 5. Confirm passkey creation Done. No IT tickets. No "please come to the office so we can set up your security key." No shipping hardware tokens internationally. Just a person, their phone, and two minutes of their time. For organizations struggling with MFA adoption, this removes the last excuse. ### For the IT admin wanting to try Passkey bliss Of course I have simplified this a bit and there are many complex technicalities to unravel due to the combination of policies one can have in a Microsoft Tenant. But if you are an Admin trying to test this, here are some quick steps [(Make sure you have migrated to the new Authentication Methods Policy)](/posts/identity/migrating-to-authentication-methods/): 1. Disable SSPR for the test user. 2. Enable ONLY: Passkey (FIDO2) and Temporary Access Pass (TAP) Authentication methods for the test user. 3. Generate a TAP for the user and then start adding the new work account in the Microsoft Authenticator app. The process is incredibly simple and quick! If any Conditional Access settings block it, you'll need to address those. Also, note that the test user doesn't need to have Authenticator authentication method policy enabled even though we're using the Authenticator app to mint a Passkey. That applies only to Push message MFA and Passwordless (PSI)! ![Open Video: Simple sign-in with a device-bound Passkey on the Authenticator App](/media/posts/identity/passkeys-personal-phone-mfa-update/Screen-Recording-2026-01-10-at-15-online-video-cutter.com_-2470e69f28.mp4) Since I like sharing my learnings: Here is how my tenant authentication methods policies blade looks. So it is possible just to have Passkeys as the only authentication and still be productive. ![Open Image: Authentication methods policies blade showing Passkey configuration](/media/posts/identity/passkeys-personal-phone-mfa-update/Screenshot-2026-01-10-at-17.57.30-1024x667-dd2aacdbd2.png) --- ## IT Admin FAQ: Deployment Questions #### Should I use synced or device-bound passkeys? It depends on your security requirements. For most workforce users in non-regulated environments, synced passkeys offer a good balance of security and usability (no lockout on device loss). For privileged accounts, regulated industries, or scenarios requiring attestation, device-bound passkeys in Microsoft Authenticator are the way to go. #### Can I use both types in my organization? Yes! Microsoft Entra ID supports both. You can configure policies that require device-bound passkeys for admins while allowing synced passkeys for general users (Requires opt-in to the Public Preview at this time). #### What happens if an employee loses their phone with a device-bound passkey? The passkey is gone. This is why you need backup authentication methods or [Self-Service Account Recovery (SSAR)](/posts/identity/self-service-account-recovery-ssar/) configured. Or someone with access has to help you on-board a new key. #### Is SMS-based MFA still okay? It's better than nothing, but Microsoft has deprecated SMS and voice calls as recommended methods due to SIM-swapping vulnerabilities [among other crazy hacks](https://youtu.be/wVyu7NB7W6Y?t=798)... Move to app-based authentication or passkeys when possible. #### What about employees who genuinely don't have smartphones? Hardware security keys (like YubiKeys) or the newer, [less talked about QR Code login](https://learn.microsoft.com/en-us/entra/identity/authentication/concept-authentication-qr-code), are your answer. They provide Passwordless auth without requiring a smartphone. Budget for them (Or use the free QR code thingy if possible). #### How do I handle users who refuse to use personal devices? Document the business requirement, provide alternatives (hardware security keys for those who qualify), and escalate persistent refusals to management. This should be a business policy decision, not an IT decision. Your role is to implement the technical solution and provide education - not to negotiate individual exceptions. I would love to hear their excuses/fears in the comments section, so we can help each other with persuasive arguments. --- ## What About Windows Hello for Business? Yes, **Windows Hello for Business (WHfB)** is absolutely a passkey provider and has been since Windows 11, version 22H2. While Microsoft's authentication portfolio can be complex to navigate, WHfB represents a mature, enterprise-ready implementation. According to [Microsoft's documentation](https://learn.microsoft.com/en-us/windows/security/identity-protection/passkeys/), Windows Hello offers native passkey support that's **device-bound** and protected by TPM (Trusted Platform Module) hardware. When you create a passkey with Windows Hello, it's stored locally on your Windows device and protected by the same biometrics or PIN you use to unlock your PC. These credentials never leave your Windows device - that's about as device-bound as it gets! ![Open Image: Windows Hello for Business passkey illustration](/media/posts/identity/passkeys-personal-phone-mfa-update/windows_hello_for_business_passkey-1-1024x683-511baffe85.png) ### So Why Aren't We Covering It in Depth? **Platform specificity:** Windows Hello for Business is an excellent passkey implementation with enterprise-grade security features, but it's exclusively for Windows devices. For organizations with heterogeneous environments, this limitation matters. Since this article aims to help a wider audience understand passkeys across multiple platforms (iOS, Android, macOS, Linux, and yes, even those weirdos still running ChromeOS), we're focusing on cross-platform solutions like Microsoft Authenticator, 1Password, and other providers that work regardless of your OS. **However**, if your organization is Windows-centric and you want the ultimate in device-bound passkey security, Windows Hello for Business deserves serious consideration. Microsoft reports that "nearly a million passkeys are registered every day" through Windows Hello, indicating significant enterprise adoption among Windows-centric organizations and sign-ins are "eight times faster and nearly three times more successful" compared to passwords. ### Key Differences to Know: - **Platform:** Windows-only (10 & 11) - **Passkey Type:** Device-bound (non-exportable) - **Storage:** Local TPM/secure hardware - **Biometrics:** stored locally, never leaves the device as PII. **Bottom line:** WHfB is solid if you're all-in on Windows. For everyone else juggling multiple platforms, stick with the cross-platform options we've covered in this article. --- ## Final Words When I wrote the original MFA article in 2023, passkeys were promising but not quite ready for enterprise primetime. Now they are - and now, with Microsoft's mandatory MFA enforcement already in effect for most admin portals, you no longer have the luxury of doing Conditional Access excludes. Passkeys offer the smoothest path to compliance that actually improves security rather than just checking a box. I sometimes fear that the users view IT a bit like Dr. Clarise in this video clip... ![Open Video: The IT perspective on MFA resistance](https://www.youtube.com/embed/5ZURNtDG4Mo) The personal phone resistance is real, but it's based on fear rather than facts. Part of your job as an IT architect is to communicate these facts clearly and compassionately to both management and end users. Position Authenticator not as surveillance software, but as a privacy-enhancing security tool that happens to reside on users' personal devices. --- **Useful Links to go deeper:** - [Plan for mandatory Microsoft Entra MFA](https://learn.microsoft.com/en-us/entra/identity/authentication/concept-mandatory-multifactor-authentication) - [Passwordless authentication options for Microsoft Entra](https://learn.microsoft.com/en-us/entra/identity/authentication/concept-authentication-passwordless) - [Enable passkeys in Microsoft Authenticator](https://learn.microsoft.com/en-us/entra/identity/authentication/how-to-enable-authenticator-passkey) - [Microsoft Authenticator FAQ](https://support.microsoft.com/en-us/account-billing/common-questions-about-the-microsoft-authenticator-app-12d283d1-bcef-4875-9ae5-ac360e2945dd) - [FIDO Alliance - Passkeys](https://fidoalliance.org/passkeys/) - [Original MFA Article (2023)](/posts/identity/why-multi-factor-authentication-is-important/) *Originally published on [MSEndpointMgr.com](https://msendpointmgr.com/2026/01/10/passkeys-personal-phone-mfa-update/)* --- ## [ConsentFix - The Quickfix](https://iphase.dk/posts/identity/consentfix-quickfix) Date: 2026-01-08 Category: identity Tags: entra-id, oauth, security, powershell, service-principals, conditional-access > UPDATED March 2026 -- This post has been reviewed and updated to reflect current Microsoft product names, portal locations, and technology status. See inline notes for specific changes. Just when you thought OAuth was safe, along comes ConsentFix to remind us that attackers are *always* two steps ahead. If you've been following security news lately, you've probably heard about this clever attack that abuses legitimate Microsoft authentication flows to steal authorization codes. The good news? There's a dead-simple PowerShell fix that sorts this out for everyone (yes, even the "security defaults" peeps without Conditional Access licensing). > *"The best time to fix a security hole was yesterday. The second-best time is right now, before your users start clicking suspicious links."* > > -- Ancient IT proverb, probably --- ## So what exactly is ConsentFix? ConsentFix (also called AuthCodeFix) is an OAuth attack that tricks users into handing over their authorization code through social engineering. Here's the scary part: the Microsoft login page they see is 100% legitimate. The attacker creates a real OAuth flow, the user authenticates successfully, and then... copy-paste (or drag-and-drop) happens. Suddenly, the attacker has valid tokens to your Azure resources. *Yes. It does require a stupid user action, but we can all get stupid sometimes (I get stupid in da club all the time bruh!)* The attack works because Microsoft first-party apps like Azure CLI, Azure PowerShell, and Visual Studio are **pre-consented in every tenant** -- any user can authenticate to them without needing admin approval. When an attacker tricks a user into starting an OAuth flow with one of these apps, the user sees a legitimate Microsoft login page and successfully authenticates. The browser redirects to localhost (where these apps listen during normal use), but since the attacker initiated the flow, no app is actually listening! The browser shows an error with the auth code sitting right there in the URL bar. One social engineering trick later, and boom -- the attacker redeems that code for tokens. ![Open Image: ConsentFix OAuth attack flow explainer diagram](/media/posts/identity/consentfix-quickfix/michael-mardahl-consentfix-explainer-de739550df.png) ## Why should you care? - Works on **any** user in your tenant, even if they've never used CLI tools before - Bypasses MFA, Conditional Access, and device compliance checks (during initial auth code redemption) - Gives attackers access to Azure Resource Manager, Microsoft Graph, and more - Refresh tokens can be valid for weeks or months -- they really just need one hour to do a ton of damage - Your fancy security tools won't catch this reliably -- it looks like legitimate OAuth activity Imagine this: You have a guest hiding in your house (since forever), that guest just pops up when anyone in your house invites them -- they don't even use the front door! If you're thinking "my users would never fall for that" -- remember that security researchers and CTOs get phished too. Social engineering is called "engineering" for a reason. --- ## The Solution The fix is surprisingly simple: pre-create the service principals for vulnerable apps and require user assignment **before** anyone can use them. This way, random users can't auto-consent when an attacker tricks them into initiating an OAuth flow. Think of it like this: instead of leaving your front door unlocked because "nobody's home anyway," we're installing deadbolts on doors that don't even exist yet. Proactive security FTW! ### Step 1: Connect to Microsoft Graph First, we need the right permissions to create and modify service principals. ```powershell Connect-MgGraph -Scopes "Application.ReadWrite.All", "AppRoleAssignment.ReadWrite.All" ``` **What this does:** Requests admin consent to manage applications and assign users to apps. You'll get a consent prompt on first use -- just click Accept (no need to consent for the entire Tenant). ### Step 2: Check What's Already in Your Tenant Let's see which vulnerable apps already exist in your environment. ```powershell # Define the apps we're concerned about $targetApps = @{ "04b07795-8ddb-461a-bbee-02f9e1bf7b46" = "Azure CLI" "1950a258-227b-4e31-a9cf-717495945fc2" = "Azure PowerShell" "04f0c124-f2bc-4f59-8241-bf6df9866bbd" = "Visual Studio" "aebc6443-996d-45c2-90f0-388ff96faa56" = "VS Code" "12128f48-ec9e-42f0-b203-ea49fb6af367" = "Teams PowerShell" } # Check which ones exist $found = @() foreach ($appId in $targetApps.Keys) { $sp = Get-MgServicePrincipal -Filter "appId eq '$appId'" -ErrorAction SilentlyContinue if ($sp) { $found += [PSCustomObject]@{ Name = $targetApps[$appId] AppId = $appId ObjectId = $sp.Id } } } if ($found.Count -eq 0) { Write-Host "No vulnerable apps found yet - that's good!" -ForegroundColor Green Write-Host "We'll create them proactively and lock them down." -ForegroundColor Yellow } else { Write-Host "Found $($found.Count) app(s) to protect:" -ForegroundColor Yellow $found | Format-Table } ``` **Why this matters:** Service principals only exist after first use. If nobody's used Azure CLI yet, the service principal won't exist. But an attacker can *create* it by tricking any user into clicking their malicious link. We're getting ahead of them. ### Step 3: Lock Down the Apps Now comes the magic -- we'll pre-create these service principals and require user assignment. ```powershell $apps = @( "04b07795-8ddb-461a-bbee-02f9e1bf7b46", # Azure CLI "1950a258-227b-4e31-a9cf-717495945fc2", # Azure PowerShell "04f0c124-f2bc-4f59-8241-bf6df9866bbd", # Visual Studio "aebc6443-996d-45c2-90f0-388ff96faa56", # VS Code "12128f48-ec9e-42f0-b203-ea49fb6af367" # Teams PowerShell ) foreach ($appId in $apps) { $sp = Get-MgServicePrincipal -Filter "appId eq '$appId'" -ErrorAction SilentlyContinue if (!$sp) { Write-Host "Creating service principal for $appId..." -ForegroundColor Cyan New-MgServicePrincipal -AppId $appId | Out-Null $sp = Get-MgServicePrincipal -Filter "appId eq '$appId'" } Write-Host "Locking down $($sp.DisplayName)..." -ForegroundColor Yellow Update-MgServicePrincipal -ServicePrincipalId $sp.Id -AppRoleAssignmentRequired:$true } Write-Host "`nDone! CLI tools are now locked down." -ForegroundColor Green Write-Host "Users need explicit assignment to use these apps." -ForegroundColor Green ``` **What just happened?** - We created service principals for all vulnerable apps (if they didn't exist) - We set `AppRoleAssignmentRequired` to true on each one - Now, **only** assigned users can authenticate to these apps - Random users can't auto-consent anymore -- the attack fails at step 1 ### Step 4: Assign Legitimate Users If you actually *do* have users who need CLI access (like yourself maybe?), assign them: ```powershell # Get your user ID $userId = (Get-MgUser -Filter "userPrincipalName eq 'admin@contoso.com'").Id # Assign yourself to Azure CLI (repeat for other apps as needed) $appId = "04b07795-8ddb-461a-bbee-02f9e1bf7b46" # Azure CLI $sp = Get-MgServicePrincipal -Filter "appId eq '$appId'" New-MgServicePrincipalAppRoleAssignedTo ` -ServicePrincipalId $sp.Id ` -PrincipalId $userId ` -ResourceId $sp.Id ` -AppRoleId "00000000-0000-0000-0000-000000000000" Write-Host "Assigned! You can now use Azure CLI." -ForegroundColor Green ``` **Pro tip:** Create a security group for CLI users instead of individual assignments. That way, you can manage access through group membership or even use PIM for just-in-time access (Slayyy!). --- ## Testing Your Protection Let's make sure this actually works. Try authenticating with Azure CLI as a non-assigned user: ``` az login ``` You should see an error similar to: ``` AADSTS50105: The signed in user is not assigned to a role for the application ``` That's **exactly** what we want! The attack is blocked before it even starts. Now test with an assigned user -- authentication should work normally. --- ## Important Gotchas ### There are more ServicePrincipals that you can choose to block! The ServicePrincipal AppIds that are in the example script are just a few must-haves out of many more. Check out [EntraScopes.com](https://entrascopes.com/?bypass=true&authcodeFix=true) for more AppIds that you can add to the script. *But, fair warning, these might be a bit harder to actually block, since there is a greater chance of them being needed by the users.* ### Duplicate Names Are a Problem If you plan to use the `DisplayName` property for anything, note that Microsoft first-party apps can have identical display names. Always use the AppId (GUID) to identify apps uniquely. ### This Doesn't Fix Everything User assignment blocks unauthorized users, but if an assigned user gets phished, the attack still works. Consider layering this with: - Conditional Access to require trusted locations - Token Protection (if you're on Windows with Entra-joined devices) -- Not a very mature feature IMHO - User education (because social engineering is hard to defend against) ### Service Principal Creation Can Take Time After running the script, wait a few minutes before testing. Azure needs time to replicate the changes across regions. ### Privileged Users Are High-Value Targets If you're only assigning Global Admins to these apps, remember that attackers *specifically* target privileged accounts. Don't assume your admins are immune to phishing -- they're not. --- ## Troubleshooting ### Error: "Insufficient privileges to complete the operation" **Cause:** You don't have the required [Graph permissions](https://msendpointmgr.com/2025/11/08/graph-api-rate-limiting-in-intune/). **Fix:** Make sure you're using `Application.ReadWrite.All` scope when connecting to Graph. You might also need to be a Global Admin or Privileged Role Administrator just while fixing ConsentFix. ### Script runs but users can still authenticate **Cause:** Replication lag or you're testing too quickly. **Fix:** Wait 5-10 minutes and try again. Clear any cached tokens (`az account clear` for Azure CLI). ### Legitimate user can't authenticate anymore **Cause:** They're not assigned to the app. **Fix:** Use the assignment script from Step 4 to grant them access. Check their user ID is correct. Or use the Enterprise Applications blade in the Entra portal if you like a UI (search All Applications, not just Enterprise Applications). ### How do I undo this if something breaks? **Fix:** Set `AppRoleAssignmentRequired` back to false: ```powershell $sp = Get-MgServicePrincipal -Filter "appId eq '04b07795-8ddb-461a-bbee-02f9e1bf7b46'" Update-MgServicePrincipal -ServicePrincipalId $sp.Id -AppRoleAssignmentRequired:$false ``` --- ## Defense in Depth: Layer Your Security against ConsentFix User assignment is great, but don't stop there. Consider these additional layers that I am just grazing over quickly -- So, you will make sure to test and lookup the known issues with these methods and test -- right? ### 1. Conditional Access for Location Blocking Block refresh token usage from untrusted locations: - **Users:** All users - **Cloud apps:** Microsoft Graph Command Line Tools + Windows Azure Service Management API - **Conditions:** Location NOT in "Trusted Locations" - **Grant:** Block access This prevents attackers from using stolen refresh tokens from their infrastructure. ### 2. Token Protection (Windows Only) If you're running Windows 10+ with Entra-joined devices, enable Token Protection: - **Cloud apps:** Exchange Online, SharePoint Online, Teams - **Session:** Require token protection for sign-in This cryptographically binds tokens to the device, making browser-based auth code attacks fail completely. ### 3. Monitor Sign-In Logs Watch for: - Non-interactive sign-ins to CLI tools from unexpected locations - Large geographic distance between interactive and non-interactive sign-ins with the same SessionId - Auth code redemptions followed immediately by unusual API calls I am sure Security Copilot can whip up some cool playbooks to alert on these things. --- ## Final Words ConsentFix is a reminder that even legitimate OAuth flows can be weaponized with the right social engineering. The good news is that this particular attack has a simple, effective mitigation: lock down those service principals before attackers can abuse them. Five minutes of PowerShell today could save you from a very awkward conversation with your security team tomorrow. Or worse -- explaining to your CEO why an attacker had Azure admin access for the past three weeks. Stay safe out there, and remember: proactive security beats reactive incident response every single time. --- ## Useful Links Respect to the Team at Glueckkanja for getting all the nerdy details sorted! - [ConsentFix: How a New OAuth Attack Bypasses Microsoft Entra Conditional Access](https://www.glueckkanja.com/en/posts/2025-12-31-vulnerability-consentfix) - [EntraScopes: Browse Vulnerable Apps](https://entrascopes.com/?authcodeFix=true) - [Microsoft Graph API: Create Service Principal](https://learn.microsoft.com/en-us/graph/api/serviceprincipal-post-serviceprincipals) - [Microsoft Learn: Token Protection](https://learn.microsoft.com/en-us/entra/identity/conditional-access/concept-token-protection) --- ## [Unlocking Self-Service Account Recovery (SSAR) in Microsoft Entra](https://iphase.dk/posts/identity/self-service-account-recovery-ssar) Date: 2025-12-30 Category: identity Tags: entra-id, passkey, passwordless, ssar, sspr, verified-id, face-check > UPDATED March 2026 -- This post has been reviewed and updated to reflect current Microsoft product names, portal locations, and technology status. See inline notes for specific changes. Self-Service Account Recovery (SSAR) is finally here for Microsoft Entra ID! Are you planning or running a passwordless tenant and wondering what to do when your users lose access to *all* their authentication methods? Well, wonder no more -- Microsoft has delivered what many of us have been waiting for! (Especially those of us that have had to knick the ol' SSPR service to go 100% Passkey) --- **Quick Facts: Self-Service Account Recovery** - **Feature Name** -- Self-Service Account Recovery (SSAR) - **Status** -- Public Preview (as of December 2025) - **License Required** -- Microsoft Entra ID P1 or higher - **Supported IDV Providers** -- AU10TIX, IDEMIA, TrueCredential (LexisNexis) - **Dependencies** -- Verified ID, Face Check, TAP policy - **Recovery URL for users** -- https://aka.ms/mfasetup --- ## So what exactly is SSAR? > **Definition:** Self-Service Account Recovery (SSAR) is a Microsoft Entra ID feature that enables users to regain access to their accounts through government ID verification and biometric liveness checks when they've lost all authentication methods. Self-Service Account Recovery (SSAR) is Microsoft's answer to a long-standing problem in identity management: what to do when someone loses *everything*. Phone stolen? Authenticator wiped? Hardware token gone missing? Your pet ostrich swallowed the FIDO key... In the passwordless world, this used to mean a trip to the helpdesk, where someone would have to somehow verify you are who you say you are -- often using nothing more than "security questions" or a gut feeling (and they really had better things to do that day). SSAR changes the game entirely. Instead of relying on human judgment alone (which attackers love to exploit through social engineering), users can now verify their identity using government-issued ID and biometric liveness checks that is AI assisted. It's like SSPR, but for the modern passwordless era -- and it *actually* seems pretty secure (Always remember: Hackers are two steps ahead!). ![Open Image: Self-Service Account Recovery (SSAR) explainer cartoon](/media/posts/identity/self-service-account-recovery-ssar/image-19-123df9ca11.png) ## Why should you care? - Self-Service Account Recovery brings SSPR-like functionality to the passwordless world. - Your helpdesk will thank you (fewer "My ostrich ate my laptop, phone and fido key" tickets). - Social engineering attacks on account recovery are eliminated-ish. - Users can recover access on their own if they have proper government ID available. - It's the missing piece for true passwordless adoption IMHO. If you're already running Verified ID and Face Check in your tenant (perhaps for some cool on-boarding solution), you're halfway there. If not... well, keep reading! and I'll walk you through the entire setup. ## Prerequisites Before we dive into configuring Self-Service Account Recovery, make sure you have the following in place: - Microsoft Entra ID P1 license (or higher). - An Azure subscription (for the IDV provider billing). - Verified ID enabled and configured in your tenant. - Face Check add-on enabled with a validated Azure subscription. - Authentication Administrator role in Microsoft Entra. - Contributor or Billing Administrator role for your Azure subscription. - And I think you should also have migrated to the new [authentication methods policy controls](/posts/identity/migrating-to-authentication-methods/). ## The Solution I'll walk you through setting up SSAR with AU10TIX as the identity verification provider. We'll scope it to a specific group of users first (always a good idea with preview features), and then test the recovery flow. ### Step 1: Verify that Verified ID and Face Check are Enabled Before configuring SSAR, we need to make sure the underlying services are ready. 1. Sign in to the [Microsoft Entra admin center](https://entra.microsoft.com) as a Global Administrator. 2. Navigate to **Verified ID** in the menu. 3. Under **Overview**, verify that you have configured the defaults. Else you will see the option for Quick Setup, where you click the get started button and follow the wizard till done. ![Open Image: Verified ID showing the default employee credential](/media/posts/identity/self-service-account-recovery-ssar/Screenshot-2025-12-30-at-14.52.22-c4acd41d12.png) 4. Now just scroll down a bit and activate the **Face Check** add-on if not already done. 5. Verify that Face Check shows a validated Azure subscription. ![Open Image: Face Check add-on showing validated Azure subscription](/media/posts/identity/self-service-account-recovery-ssar/Screenshot-2025-12-30-at-14.57.46-557a06b4c3.png) If either of these are not configured, you'll need to set them up first. Face Check requires linking an Azure subscription for billing purposes (You get like a bunch of free credits, so worry not about your finances at this point). *I am purposefully not going into minute details on how to setup these things, as it is very straightforward to just follow the wizards that are built-in. And go with all the defaults.* ### Step 2: Create a Security Group for SSAR I prefer to scope new preview features to a controlled group of users before rolling out to the masses. And for SSAR you are forced to assign to a group anyways... 1. In the Microsoft Entra admin center, navigate to **Identity** > **Groups** > **All groups**. 2. Click **New group**. 3. Configure the group as follows: - **Group type:** Security - **Group name:** `acl_ssar_enabled` - **Group description:** Users enabled for Self-Service Account Recovery - **Membership type:** Assigned (or Dynamic if you prefer) 4. Add your test users to the group - **These should be real users who have completed actual sign-ins**, else you will have to do some fake sign-ins before testing. Also important to note, you should have a government ID for these users, so don't be faking it so much in your tests. Since the service will match on First name and Last name. Meaning that you now have to fire all people that have the same first and last name. I would personally go with the Last-In First-Out rule. (For those without sarcasm, I must explain that I am kidding. But the duplicate name thing is a real issue. **You can't have people with the same first and last name in your assignment group. Period.**) 5. Click **Create**. ### Step 3: Configure Account Recovery Now for the main event -- let's set up SSAR. 1. In the Microsoft Entra admin center, navigate to **Entra ID** > **Account recovery (Preview)**. ![Open Image: SSAR Account Recovery button in Entra portal](/media/posts/identity/self-service-account-recovery-ssar/image-20-3167dfcf7e.png) 2. Under **Set up account recovery**, click **Get started**. ![Open Image: Account recovery Get started page](/media/posts/identity/self-service-account-recovery-ssar/Screenshot-2025-12-30-at-13.32.52-ac9a5daa0c.png) 3. Under **Choose a recovery mode**, select **Production** then click **Next**. ![Open Image: Choose a recovery mode for SSAR - Production selected](/media/posts/identity/self-service-account-recovery-ssar/Screenshot-2025-12-30-at-13.35.16-feaad6001a.png) - **Note:** Evaluation mode lets users test the identity verification flow but won't actually recover accounts. Since we want the full experience, we're going straight to Production -- but with a scoped group, so don't worry bruh! 4. Under **User group selection**, click **Select groups**. - Search for and select your `acl_ssar_enabled` group. ![Open Image: User group selection for SSAR included users scope](/media/posts/identity/self-service-account-recovery-ssar/Screenshot-2025-12-30-at-13.36.53-00a020bc80.png) 5. Click **Next** when you see the group added to the include list. ### Step 4: Subscribe to an Identity Verification Provider This is where we set our IDV provider through the Microsoft Security Store. 1. Under **Identity verification providers**, you'll see the available options: AU10TIX, IDEMIA, and TrueCredential (LexisNexis). 2. Select **AU10TIX** by clicking **Get solution** in the AU10TIX box. ![Open Image: Selecting an identity verification provider for SSAR](/media/posts/identity/self-service-account-recovery-ssar/Screenshot-2025-12-30-at-13.43.13-055097adcd.png) - *I am simply using AU10TIX as an example here, I am not directly recommending them. It was just the easiest for me to use them in the demo, as I already use IDEMIA due to them being EU based, like me.* 3. Click **Marketplace** to open the Microsoft Security Store. 4. Make sure you are signed-in with an account that has Owner or Contributor rights on your Azure subscription (required for billing). 5. On the AU10TIX overview page, click **Get solution**. ![Open Image: Microsoft Security Store view of the AU10TIX IDV solution](/media/posts/identity/self-service-account-recovery-ssar/Screenshot-2025-12-30-at-14.47.48-25593088c9.png) 6. Configure the SaaS subscription: - **Billing subscription:** Select your Azure subscription - **Resource group:** I simply use the same one as I did for the Face Check billing - **Resource name:** Give it a descriptive name like "au10tix-ssar" - **Plan:** Select your preferred pricing plan (I choose the Free Trial, and **disabled auto-renewal**) ![Open Image: AU10TIX SaaS subscription configuration with free trial selected](/media/posts/identity/self-service-account-recovery-ssar/Screenshot-2025-12-30-at-15.10.13-baeb47384f.png) 7. Click **Next**, review your order, and click **Place order**. 8. When the subscription is ready, click **Configure account now**. 9. Complete the activation in the AU10TIX portal by providing the required details. 10. After seeing **Success**, return to the Microsoft Entra admin center (It takes some time to provision, and you get a bunch of e-mails you can archive). 11. PRO TIP: Afterwards you can always return to the security store to view the solutions (and cancel them) via the **Management -> My solutions** view. ![Open Image: Solutions view in the Microsoft Security Store](/media/posts/identity/self-service-account-recovery-ssar/Screenshot-2025-12-30-at-15.13.03-scaled-c7d2e079cc.png) ### Step 5: Finalize Account Recovery Setup 1. Back in the Account Recovery setup wizard, the Identity verification provider should now show AU10TIX as **Subscribed**. 2. Click **Select** next to AU10TIX. 3. Click **Next** to proceed to the review page. 4. Review your configuration: - Recovery mode: Production - User groups: acl_ssar_enabled - Identity verification provider: AU10TIX 5. Click **Done** to complete the setup. You should now see the Account Recovery home page showing your configuration in Production mode with AU10TIX (or your choice) as the subscribed provider. Here is a screenshot from my production tenant where I use IDEMIA: ![Open Image: SSAR fully configured showing Production mode with IDEMIA](/media/posts/identity/self-service-account-recovery-ssar/Screenshot-2025-12-30-at-15.17.21-f49e77609e.png) ## Testing Account Recovery Now for the moment of truth -- let's test the recovery flow! ### IMPORTANT: The Undocumented Gotcha Here's something I discovered the hard way, and it's **not documented anywhere** by Microsoft: > **You MUST initiate the account recovery process via [https://aka.ms/mfasetup](https://aka.ms/mfasetup) -- NOT through normal portal logins!** If you try to test recovery through the standard login portals (like portal.azure.com or portal.office.com), you'll get an unhelpful `AADSTS55200: The continuation_token is invalid` error immediately after clicking "Recover your account." ![Open Image: SSAR error message - AADSTS55200 The continuation_token is invalid](/media/posts/identity/self-service-account-recovery-ssar/image-18-600x324-74e26de58f.png) I spent hours troubleshooting this, checking Verified ID credentials, Face Check configuration, and IDEMIA/AU10TIX setup -- only to discover the issue was simply *where* I was starting the recovery flow. It also seems to work when doing it from inside a Microsoft App like Teams on the smartphone, but I was just testing, so did not bother with signing-out of my apps or setting up a separate user and smartphone just for this. I only tested from within the Microsoft Authenticator app by trying to add a new user account via the sign-in feature. But that was also completely broken! which is a shame, because it would be the best place to start IMHO. ### The Correct Way to Test 1. Open an **InPrivate/Incognito browser session**. 2. Navigate to **[https://aka.ms/mfasetup](https://aka.ms/mfasetup)**. 3. Enter the UPN of your test user (must be a member of `acl_ssar_enabled`). 4. When prompted for authentication, click **Other ways to sign in**. ![Open Image: SSAR account recovery - sign-in another way option](/media/posts/identity/self-service-account-recovery-ssar/Screenshot-2025-12-30-at-16.00.50-c3e7b2938f.png) 5. Click **Recover your account**. ![Open Image: SSAR - Recover your account link](/media/posts/identity/self-service-account-recovery-ssar/Screenshot-2025-12-30-at-16.01.15-9dd347b510.png) 6. You'll be presented with information about the recovery process. Click **Next** to proceed. 7. You'll be redirected to the IDV provider for identity verification: - Choose your country and identification method - Upload/scan your government-issued ID - Complete the liveness check (selfie time!) 8. After successful verification, a Verified ID credential is issued to your Microsoft Authenticator app. 9. Complete the Face Check in Microsoft Authenticator. 10. Upon successful verification, you'll receive a **Temporary Access Pass (TAP)**. 11. Use the TAP to sign in and register new authentication methods. Preferably directly in the authenticator app -- You can go straight to Passkey setup if you have completely disabled the old SSPR for the user account and enabled Passkeys as the only method allowed! ![Open Video: Self-Service Account Recovery flow demonstration](/media/posts/identity/self-service-account-recovery-ssar/Screen-Recording-2025-12-30-at-15-online-video-cutter.com_-f309cc66bc.mp4) > *"He who remembers a thousand passwords carries a thousand burdens. He who uses a passkey carries only his finger."* > > -- Confucius, probably --- ### User Profile Requirements For the identity verification to succeed, the user's **First name** and **Last name** in Entra ID must match the details on their government-issued ID. The Display Name is *not* used in this process. Make sure your test users have these properties correctly filled in: - Navigate to **Users** > select the user > **Properties** > **Edit properties** - Verify that **First name** and **Last name** match their government ID exactly Mismatches like "John" vs. "Jonathan" or complex surnames will cause the verification to fail! (At least during preview). --- ### Troubleshooting - **AADSTS55200: The continuation_token is invalid** -- Are you using [https://aka.ms/mfasetup](https://aka.ms/mfasetup) to initiate recovery? If not, that's your problem! (Microsoft knows this and will be rolling out a fix in Feb. 2026) - **User doesn't see "Recover your account" option** -- Verify the user is a member of your SSAR-enabled group. The user needs at least one prior successful authentication before recovery becomes available. - **Identity verification fails at name matching** -- Check that First name and Last name in Entra ID match the government ID exactly. Display name is not used -- only First name and Last name properties. - **Face Check fails** -- Ensure good lighting conditions. Try a different background. Make sure the user's face is clearly visible. - **No TAP issued after verification** -- Verify that TAP is enabled in your Authentication methods policy. Ensure the user is in scope for TAP (this is separate from the SSAR group!). - **Unable to use the TAP after issuance (User blocked by CA)** -- Make sure your Conditional Access does not contain a policy that blocks the user action "Register security information". In general I recommend allowing this user action in combination with a custom Authentication Strength that specifically requires the use of a Temporary Access Pass (TAP). - **I don't see the "Recover account" link when choosing other ways to sign-in** -- The system will only show this link in certain scenarios, and only when it knows the user you are trying to access is a member of a group assigned to the SSAR service. So, either you are too fast (It can take a few minutes to register), you are trying with a user that is not correctly assigned to the service, or you did not heed my warning about simply going to aka.ms/mfasetup. --- ### Frequently Asked Questions **What is the difference between SSPR and SSAR?** Self-Service Password Reset (SSPR) allows users to reset passwords when they still have access to at least one authentication method. Self-Service Account Recovery (SSAR) is designed for total lockout scenarios where users have lost access to ALL authentication methods and must verify their identity through government ID and biometrics -- this is especially important when using only Passkeys. **Which identity verification providers does SSAR support?** Microsoft Entra SSAR supports three IDV providers through the Microsoft Security Store: AU10TIX, IDEMIA, and TrueCredential (powered by LexisNexis). All three offer government ID verification and biometric liveness checks. **Why do I get AADSTS55200 error when testing SSAR?** The AADSTS55200 "continuation_token is invalid" error occurs when initiating account recovery from standard login portals. You must use https://aka.ms/mfasetup to start the recovery process -- this is an undocumented requirement as of December 2025. UPDATE: Microsoft is now aware of this, and will be rolling out the fix in Feb. 2026. **Does the user need the Microsoft Authenticator app for SSAR?** Yes, the Verified ID credential issued after identity verification is stored in Microsoft Authenticator. The Face Check verification also occurs within the Authenticator app. **What user attributes must match for SSAR to work?** The user's **First name** and **Last name** properties in Microsoft Entra ID must exactly match the name on their government-issued ID. The Display Name field is not used in the matching process. --- ## Final Words Just remember: This is a preview feature (as of writing), and I see a bright future for it -- So, lets hope Microsoft keeps investing in this service. I ran into some snags which made me write this blog post, and I hope sharing it here saves you some time and frustration! (Or at the very least makes Microsoft fix the issues that I uncovered) **Useful Links to go deeper:** - [Overview of Microsoft Entra ID Account Recovery](https://learn.microsoft.com/en-us/entra/identity/authentication/concept-account-recovery-overview) - [How to Enable and Test Account Recovery (Preview)](https://learn.microsoft.com/en-us/entra/identity/authentication/how-to-account-recovery-enable) - [How End Users Can Set Up Account Recovery](https://learn.microsoft.com/en-us/entra/identity/authentication/how-to-account-recovery-for-users) - [Microsoft Entra Verified ID](https://learn.microsoft.com/en-us/entra/verified-id/) --- ## [Exporting Teams Chats: Why You Might Need It, and How I Built a Tool for It](https://iphase.dk/posts/misc/exporting-teams-chats-with-graph-api) Date: 2025-09-01 Category: misc Tags: teams, microsoft-graph, powershell, export, automation, archiving > UPDATED January 2026 -- Added a note about ConsentFix hardening and how it affects the Microsoft Graph Command Line Tools default app. If your tenant has locked down consent attacks, you'll need to register your own app instead. # Exporting Teams Chats: Why You Might Need It, and How I Built a Tool for It If you've spent more than five minutes in Microsoft Teams, you've probably hit a wall trying to do something that should be incredibly simple: getting a copy of your own damn chat out of the system. Maybe HR asked for a copy of a conversation. Maybe you're trying to feed a massive technical thread into an LLM so it can write the documentation you've been avoiding. Or maybe you're just paranoid that the "temporary" project team is going to be deleted tomorrow and take all your architectural decisions with it. Whatever the reason, Microsoft in their infinite wisdom decided that "Export Chat" shouldn't be a button you can just click. Your options are essentially: screenshot everything like it's 2012 (terrible), blindly trust that Teams will keep it forever (risky), or try to convince your compliance team to run an eDiscovery search for you (expensive and usually requires filling out three forms). So, naturally, I got annoyed and built a PowerShell script to do it properly: **[Export-TeamsChat](https://github.com/mardahl/Export-TeamsChat)**. > **Disclaimer:** This is a proof of concept. I've tested it on a few different tenants and it works great, but it's not an officially supported enterprise tool. Use it for what it is—a handy utility—and always test in a non-production environment first before you point it at the CEO's chat history. --- ## Why Export Teams Chats? Before we look at the code, let's talk about *why* you'd bother doing this. **Feeding the AI overlords.** I've been experimenting with taking messy, rambling technical chats and throwing them into LLMs to extract action items or summarize decisions. For that to actually work, you need structured data—JSON or CSV—not a bunch of PNGs you took with Snipping Tool. **Archiving that doesn't suck.** Some of us still maintain knowledge bases in flat files or markdown. If critical decisions live in Teams, exporting them to TXT or HTML lets you archive them in a format *you* control, safely away from any Microsoft 365 licensing disputes. **The "Just in Case" folder.** Not an eDiscovery replacement, but useful for internal reviews or just making sure you have a paper trail of that one vendor who keeps changing their story. Which brings me to the obvious warning: **this is not a forensic or legal eDiscovery solution**. There are no cryptographic checksums here. No chain-of-custody mechanism. I can export a chat to JSON and change what my boss said. If you need tamper-evident records that hold up in court, use Microsoft 365 Purview eDiscovery. If you just want to read your chat history without opening the bloated Teams client? Keep reading. --- ## Two Ways to Authenticate (Pick Your Poison) The script supports two very different authentication modes because "personal use" and "enterprise automation" are two very different beasts. ### Delegated Mode: The "I Just Want My Own Stuff" Option You sign in with your own account. The script only touches chats you're already a participant in. No client secrets to manage, no begging the global admins for consent. ```powershell pwsh ./Export-TeamsChat.ps1 -Interactive ``` When you run this, it kicks off a device code flow by default: 1. Choose your sign-in method (device code or browser — see below). 2. Tenant ID is optional. Leave it blank and the script uses the common endpoint, then auto-detects your tenant ID from the token it gets back. 3. Press Enter to use the default Microsoft Graph Command Line Tools app. 4. Open `https://microsoft.com/devicelogin`, punch in the code, and sign in. 5. Paste your Teams chat URL when prompted. 6. Pick your format and let it run. That's it. It's the safest option by far because it literally cannot access anything your account can't already see. **Bonus: if you just double-click the script or run it with no arguments and no config file present, it drops straight into interactive mode automatically.** No flags needed. **Browser sign-in (`-BrowserAuth`):** Device code flow blocked by a Conditional Access policy? Add `-BrowserAuth` and the script uses the OAuth Authorization Code + PKCE flow instead. It starts a local listener on a loopback port (8400–8420), opens your default browser, and handles the redirect automatically. No client secret required. Works cross-platform — Windows, macOS, Linux. ```powershell pwsh ./Export-TeamsChat.ps1 -Interactive -BrowserAuth ``` You can also use `-BrowserAuth` outside of interactive mode when passing parameters directly: ```powershell pwsh ./Export-TeamsChat.ps1 -TenantId "..." -ClientId "..." -Delegated -BrowserAuth -TeamsUrl "..." ``` (The `-Delegated` switch forces delegated auth when you're providing `TenantId` and `ClientId` as parameters but no `ClientSecret`.) **A note on the Microsoft Graph Command Line Tools app:** This default app (`14d82eec-204b-4c2f-b7e8-296a70dab67e`) is fantastic because it requires zero registration. You just pull the chat. The catch? If your security team is actually paying attention—perhaps they've read my [ConsentFix article](/consentfix-quickfix/)—they might have locked down token refresh or disabled this app entirely to prevent consent attacks. If your tenant is locked down, you'll need to register your own app with the `Chat.Read` delegated permission instead. It's the same process, just one extra hoop to jump through. ### App-Only Mode: The "I Am The Admin" Option You register an app in Entra ID with `Chat.Read.All` application permission and admin consent. The script can now read *any* chat in the entire tenant. Use this when you need to: - Automate bulk exports across the tenant. - Export chats for users who have already left the company. - Run unattended scripts on a server somewhere. The trade-off? You're managing a client secret. Protect it like the keys to the kingdom, because it essentially is. --- ## Setting Up App-Only Mode If you actually need tenant-wide access, here's the setup: 1. Head to **Microsoft Entra admin center** → App registrations. 2. Create a new app registration. 3. Go to **API permissions** -> **Add a permission** -> **Microsoft Graph**. 4. Select **Application permissions** (NOT delegated) and check off: - `Chat.Read.All` (required) - `ChatMessage.Read.All` (optional, but a good idea) 5. Smash that **Grant admin consent** button. 6. Generate a client secret under **Certificates & secrets**. 7. Write down the Tenant ID, Client ID, and the Secret. Then you either pass them all as parameters: ```powershell pwsh ./Export-TeamsChat.ps1 -TenantId "..." -ClientId "..." -ClientSecret "..." -TeamsUrl "..." ``` Or you save them in a `TeamsExportConfig.json` file next to the script. Not sure what that file should look like? Run `pwsh ./Export-TeamsChat.ps1 -ConfigFile` and it creates a self-documented template for you. If you choose the JSON route, for the love of all that is holy, **do not commit that file to git.** Add it to `.gitignore` before you even create it. --- ## The Output Formats The script spits out data in four formats because everyone's downstream process is different. **TXT** — Plain text. Good for reading, printing, or pasting into an email when you need to prove a point quickly. Includes timestamps and who sent what. **JSON** — Structured data. Full message metadata, exact timestamps, and raw reaction data. Perfect if you're feeding this into a Python script or an LLM. **HTML** — A self-contained web page. It actually looks pretty decent. Open it in Edge, print to PDF, file it away. **CSV** — For the spreadsheet warriors. Every message gets a row. Pull it into Excel, filter by sender, and pivot-table your heart out. --- ## How It Works (The Short Version) It's just PowerShell and the Microsoft Graph API doing a little dance. 1. **Auth:** Gets a token using either device code or client credentials. 2. **Parse:** Rips the actual chat ID out of the Teams URL (whether it's `@thread.v2`, `@unq.gbl.spaces`, or `@unq`). You can even give it a link to a specific message and it figures it out. 3. **Loop:** The Graph API only gives you 50 messages at a time. The script patiently paginates through until it hits the end. 4. **Format:** Transforms the raw Graph JSON into whatever format you asked for. 5. **Save:** Drops the file on your disk and spits out the path. --- ## Things to Keep in Mind **Delegated mode means *your* chats only.** You cannot use the `-Interactive` flag to read the C-suite's private channel. The Graph API blocks it, not me. **App-only mode is dangerous.** Don't hand out `Chat.Read.All` to a service account unless you absolutely trust the person holding the secret. **Emojis are weird.** The HTML output usually renders emojis fine. TXT might spit out Unicode blocks depending on your console font. JSON will give you the raw data. **No attached files.** It exports the text of the chat. If someone dropped a 40MB PowerPoint in the thread, the script will tell you a file was attached, but it won't download the actual file. Inline images embedded directly in a message *are* downloaded — they get saved to a sibling assets folder next to your export file and the references are rewritten to point there. But SharePoint-linked files and other attachments? Those stay put. **It can't read deleted messages.** If your company has a 30-day retention policy that actively purges Teams messages, the script can't magically recover them. It only sees what you can see. --- ## Go Get It I built this because I was tired of doing things the hard way. It's open-source (Prosperity Public License 3.0.0, non-commercial + 30-day commercial trial), and it works. Grab the script over at **[github.com/mardahl/Export-TeamsChat](https://github.com/mardahl/Export-TeamsChat)**. You need PowerShell 5.1 or later (Windows PowerShell works fine; PowerShell 7+ is also fully supported) and an Entra ID tenant. Download it, run it, and finally get your data out of the walled garden. --- ## [2 for 1 - Mail Enable Unlicensed Admin Accounts - 2024 Edition](https://iphase.dk/posts/identity/2-for-1-admin-mail-enable-unlicensed-admin-accounts) Date: 2024-02-02 Category: identity Tags: exchange-online, admin-accounts, licensing, powershell, plus-addressing > UPDATED March 2026 -- This post has been reviewed and updated to reflect current Microsoft product names, portal locations, and technology status. See inline notes for specific changes. Are you looking to cut mailbox licensing costs for your Microsoft 365 tenants admin mail accounts? Well, look no further, and I will share a few ways for you to save money on Exchange Online licensing fees for your admin accounts that need to exchange e-mails. *So what do I mean by "admin accounts"?* In this case, the admin account (sometimes referred to as an ADM account) is a separate privileged account used by IT staff to perform their privileged duties. These account types are a standard security measure implemented in many companies, and in some cases, they need to be mail-enabled. **Some valid reasons for needing to mail enable an admins account is:** - To receive Microsoft Notifications. - Third-party admin tools that don't support alternative e-mail addresses. - OTP messages sent to the account. - Using the account UPN in places that require you to fill in an e-mail. But mail enabling does not necessarily mean having to purchase a license for Exchange Online! One way for you to avoid excessive licensing for Exchange Online is to redirect emails using Distribution Lists. By redirection, I mean mail destined for your admin account goes to your regular non-privileged account instead. ## IMPORTANT UPDATE These solutions below worked for many years but are maybe no longer needed. A much simpler solution is now available to tenants that have "plus addressing" enabled. I have left the original part of this article below the line, just for historical reasons. The following is the "new" simple way of doing this. But notice that e-mail sent directly to the UPN will not be delivered, in this case you need to use one of the other options. A "plus" address is simply a "tag" that is added to the incoming e-mail, but when added to the admin account, Entra ID will pass the check for duplicate mail address values, and allow you to add the "same" mail account to two different objects in Entra ID. ### Enable Plus Addressing Requirements: Exchange Administrator Role To begin with, we need to verify if the tenant allows "Plus Addressing". It is enabled by default in most tenants, and you can read more about it here: [Plus Addressing in Exchange Online | Microsoft Learn](https://learn.microsoft.com/en-us/exchange/recipients-in-exchange-online/plus-addressing-in-exchange-online?wt.mc_id=EM-MVP-5004117) 1. Access the Exchange Online Admin Center via https://admin.exchange.microsoft.com 2. In the menu on the left, find the "Settings" button, indicated by a "gear" icon, and click it. ![Open Image: Settings button in Exchange Admin Center](/media/posts/identity/2-for-1-admin-mail-enable-unlicensed-admin-accounts/image-1-f2b6ece812.png) 3. Inside "settings", find the "Mail flow" option indicated by an envelope icon, and click it. ![Open Image: Mail flow options link in Exchange Admin Center](/media/posts/identity/2-for-1-admin-mail-enable-unlicensed-admin-accounts/image-2-d960aa1186.png) 4. You should see a fan-out menu with the "plus addressing" option shown at the top. Make sure that the box next to it is clear. Clear it if needed. ![Open Image: Plus addressing options in Exchange Admin Center mail flow settings](/media/posts/identity/2-for-1-admin-mail-enable-unlicensed-admin-accounts/image-3-bda6be087c.png) ### Add a "plus" Address to the Admin Account Adding a "plus" address to the admin account, so you receive e-mails in your "regular" mailbox, is as simple as these steps: 1. Go to the Microsoft Entra Portal: https://entra.microsoft.com 2. Find the user account in your list of users and open up the account page 3. Click on the "properties" tab found on the overview page. 4. Find the "Contact information" edit "pen" and click it. ![Open Image: Contact information menu button in Entra ID user properties](/media/posts/identity/2-for-1-admin-mail-enable-unlicensed-admin-accounts/image-5-2986749bba.png) 5. Now simply type in your regular account e-mail but add the "plus" tag as well. For example, if your regular e-mail account is "user@contoso.com", add a "+admin" tag, right before the @-sign: `user+admin@contoso.com` ![Open Image: Email address field in the contact information blade showing plus addressing](/media/posts/identity/2-for-1-admin-mail-enable-unlicensed-admin-accounts/image-6-fffdd1e783.png) 6. Afterwards, click "save" and you are done! Now you will receive e-mails on this address inside the normal user account mailbox. The added benefit of "plus" addressing is that you now have a tag that you can use to sort your e-mail on. --- ## Using Distribution Lists to redirect e-mail (Original Solution) **Using Distribution Lists to redirect e-mail has several advantages:** - Easy to set up with PowerShell or EAC. - Redirect without storing a copy. - Supports "send as" or "on behalf." - Supports "Hide from Global Address List." - Generates the least amount of system clutter. - No license consumption required! You might be wondering why this single problem had me choose Distribution Lists over other tried-and-true solutions? I explain that and other solutions, at the end of this article. It's up to you to decide if you think another solution is a better fit for your organization. Now that most of the admin portals in Microsoft 365 and Azure no longer require admins to have an active license assigned, you could be looking into removing Exchange Online Licensing from your admin accounts and switching to Distribution List redirection or similar solutions to save money. --- ## The solution I have opted into using PowerShell for this solution, but you could use the Exchange Admin Center instead. This is, however, not explained in this blog post. The following PowerShell code should get you off to a good start. Use it to build a neat solution in Azure Automation, and have it execute every time you add a new admin account. That is sure to impress the boss! Automation is king -- only your imagination will limit you... ### The requirements - Azure Subscription (free is sufficient). Alternatively, connect using the Exchange Online PowerShell Module V2. - Exchange Online Administrator Privileges. - A basic understanding of PowerShell script variables. ### The steps 1. Log on to Azure Cloud Shell via **[https://shell.azure.com](https://shell.azure.com)** 2. Run the command: **Connect-ExoPSSession** (UPDATE: removed in latest version of cloud shell, where you will have to install exchangeonlinemanagement PS module manually!) ![Open Image: Azure Cloud Shell using Exchange Online Module](/media/posts/identity/2-for-1-admin-mail-enable-unlicensed-admin-accounts/image-17-1024x495-9f8fb479be.png) After completing the above steps, you can interact with Exchange Online PowerShell. **Before you go off and execute the script below, you first need to understand the variables that it uses.** ```powershell $adminMail = "adm.yourname@contoso.com" $userMail = "yourname@contoso.com" $name = ($adminMail -replace "@","_").Replace(".","-") New-DistributionGroup -Name "Redirect for $name" -Alias "$name`_admin" -PrimarySMTPAddress "$($adminMail)" -ManagedBy "$userMail" -CopyOwnerToMember -MemberDepartRestriction "Closed" -MemberJoinRestriction "Closed" Set-DistributionGroup "Redirect for $name" -HiddenFromAddressListsEnabled $true -GrantSendOnBehalfTo "$userMail" -RequireSenderAuthenticationEnabled $false ``` **You will need to modify the variables in the script above, according to your requirements.** - **$adminMail** -- This variable is the e-mail address you wish to assign to the Distribution Group. This should be the same as the UPN address of the admin account. - **$userMail** -- This variable is the non-privileged account e-mail. This account must have an Exchange mailbox and should only belong to the same person owning the admin account if you like staying compliant. - **$name** -- This variable is my way of auto-generating a name for the Distribution List; you can modify it if you like, but you must understand the impact yourself. --- ### Troubleshooting - **No e-mail coming through from the Internet** -- Unfortunately, it can take a while for your newly created Distribution Lists cleared for unauthenticated external e-mail. So, give it some time. - **Admin e-mail address already in use in the organization?** -- If you previously had this e-mail address receiving e-mail, you will need to track down the location of the e-mail attribute and remove it from whatever crevice it resides in -- e-mail addresses are unique throughout Exchange Online. Remember to back up any existing mail data *if you already had a license assigned to the admin account*. You might have leftover attributes from past licensing on your admin account. Clean them out by temporarily adding a license and running the `Set-User admin@contoso.com -PermanentlyClearPreviousMailboxInfo` command from Exchange Online PowerShell. You are out of luck? -- delete the user and create from scratch. - **Unable to remove the Exchange Online license from the admin account** -- You might have [group-based licensing](https://msendpointmgr.com/2020/03/17/microsoft-365-group-based-licensing-automated/) enabled in your tenant. ## Other solutions -- pros/cons As with all things Microsoft, there are several ways to achieve a solution to a problem, so in the spirit of sharing my thoughts, here are some other possible solutions. *Please keep in mind that you might be required to adhere to specific compliance requirements, such as accountability, traceability, retention, backup licensing, exit strategies, and separation of privileges.* Security compliance is why I ended up choosing Distribution Lists. Also because they have the smallest footprint vs. usability. ### Transport Rule **Pros:** - Requires no license. - Easy to implement. **Cons:** - Can't use "Send As" and "On behalf of". - Clutter in the rules list. Can you imagine having 99 admin accounts and this problem? - You are limited to 300 rules in Exchange Online. ### Shared mailbox A classic solution to saving on Exchange Online licensing, but it did not support my requirements of not being able to store email -- it came close though! **Pros:** - Requires no license. - Can store a hierarchy of mail items in folders. - Easy to configure and maintain with PowerShell. - Can have a very small visual footprint in the admin interface. **Cons:** - Requires a user account to be present and disabled for mailbox login. - The admin UPN can only be added as a secondary Alias. - Runs as a separate mailbox in Outlook, unless automapping is disabled and email is forwarded. - Your mobile access to these emails will be limited to Outlook for iOS/Android. ### Alias Address Not much to say here. Except that it's not possible to assign an Alias to a regular user if the alias exists as a "UserPrincipalName" (UPN) on an existing account. Also if you have a Hybrid Exchange environment, you might be tempted to manipulate the user's proxyAddress attribute directly. This will not work! ### Microsoft 365 Groups Not much to say here either. Same limitations as Alias Address apply. ## Final words In a perfect world of P2 licensing, you could use Azure PIM to consolidate users. Unless security has required that you have separate accounts (tiering). --- ## [Simplify Windows Hello for Business SSO with Cloud Kerberos Trust - Part 1](https://iphase.dk/posts/identity/cloud-kerberos-trust-part-1) Date: 2023-03-04 Category: identity Tags: cloud-kerberos-trust, sso, windows-hello-for-business, passwordless, kerberos > UPDATED March 2026 -- This post has been reviewed and updated to reflect current Microsoft product names, portal locations, and technology status. See inline notes for specific changes. Cloud Kerberos Trust for Windows Hello for Business is the apex of single sign-on solutions for your Windows devices. In this Trilogy you can expect to learn the what, the how and the **wow**! *Co-authored by Ben Whitmore and Michael Mardahl* Looking for other parts? [Part 2](/posts/identity/cloud-kerberos-trust-part-2) -- [Part 3](/posts/identity/cloud-kerberos-trust-part-3) --- ## The story so far Windows Hello for Business Cloud Kerberos Trust -- Every silver lining begins with a journey through pain, non optimal circumstance and wisdom gained through grit and determination. The trust model story has never been simple.. ![Open Image: Star Wars Darth Sion pain meme - Cloud Kerberos Trust](/media/posts/identity/cloud-kerberos-trust-part-1/Pain-f433655aed.png) [This Photo](http://scifi.stackexchange.com/questions/84450/is-it-possible-that-darth-sion-was-actually-lucien-draay) is licensed under [CC BY-SA](https://creativecommons.org/licenses/by-sa/3.0/) In this 3-part mini series, we will talk about concepts, strategies, configurations and pain points that we commonly come across when configuring Windows Hello for Business and why Cloud Kerberos Trust is the future. ### What is Windows Hello for Business? We won't spend too much time peeling apart what Windows Hello for Business (WHfB) is but let's remind ourselves of some key points. - WHfB is a password-less authentication mechanism. Think of it as a type of user credential which is uniquely tied to a device -- secured with a PIN or biometric - WHfB is **not** the same same as Windows Hello. Windows Hello "convenience PIN" is targeted for the home market and is, essentially, like a password vault. A PIN or biometric is used to reveal the password(s) in that vault. - WHfB key trust uses an asymmetric key pair, a password is never hashed and sent across "the wire" which is what makes it particularly secure. The private key is secured, normally, using the Trusted Platform Module (TPM). The private key **never** leaves the device and is **unique** for every device. An alternative to WHfB key trust is WHfB certificate-based authentication. ### Why Windows Hello for Business? ![Open Image: Star Wars Sith meme - why Windows Hello for Business](/media/posts/identity/cloud-kerberos-trust-part-1/image-31-8da1279e81.png) [This Photo](http://scifi.stackexchange.com/questions/84450/is-it-possible-that-darth-sion-was-actually-lucien-draay) is licensed under [CC BY-SA](https://creativecommons.org/licenses/by-sa/3.0/) Passwords are weak. Full stop. In a world where Identity theft is on the rise and password lists can be purchased from the dark web for the price of a McDonalds coffee we need to do more to secure the identity of our workforce. Passwords are transmitted over the wire and are susceptible to many man in the middle and eaves dropping practices. This leads to the question... > Why does WHfB address the weak password conundrum? WHfB is considered a "Strong" authentication type. The Biometric and PIN are unique to a user on a specific device where as passwords can normally be used to validate a user from **any** device. WHfB differs because the "Password" or "Private Key" never leaves the device. For WHfB key trust, a cryptographic key pair is bound to the TPM or in Software (less secure). WHfB policy dictates where the key is generated. The Identity Provider (IDP) has the public portion of the key that is mapped to the user account during the registration process. Even when a token is generated by the Identity Provider (IDP) it is bound to that specific device. Unlike some Multi-Factor (MFA) methods, WHfB is considered "Phish Resistant". This means that strong authentication cannot be phished, unlike "One Time Passwords" and "Push Notifications". When we talk about WHfB, many orgs think about key trust but certificate trust is also another valid way to ensure a strong logon to a device. Certificate trust is used by orgs leveraging ADFS. WHfB is great, and a much stronger alternative to passwords, but there are still scenarios where some might consider the PIN is weak compared with a password. If you deploy a WHfB policy and require a 4 digit PIN, will most users use the day and month of their birthday for the PIN -- or perhaps a phone number? This information can be easily phished through social engineering. Also consider if a laptop is stolen on a train and the PIN is shoulder surfed -- an attacker has access to the device* We are not saying don't use WHfB because of these scenarios but you should be aware of them when deciding on your WHfB PIN policy and Conditional Access design. \* [TPM anti-hammering](https://learn.microsoft.com/en-us/windows/device-security/tpm/tpm-fundamentals#anti-hammering) can prevent an attacker guessing the PIN incorrectly too many times. ### Key Trust Many organizations have already deployed WHfB key trust. If you are still requiring your devices to access on-premise resources, the single biggest pitfall is during initial deployment. A synced user identity is required in a hybrid environment. Imagine you have a shiny, internet born device, enrolled in Entra ID and managed by Intune but you want the user to still access resources within your domain. We spoke about this scenario and the requirements in our SSO mega series. [SSO to domain resources from Microsoft Entra joined Devices -- The MEGA Series -- Part 1 -- Overview](/posts/identity/sso-to-domain-resources-from-azure-ad-joined-devices-the-mega-series/) During the provisioning of WHfB, there is a delay while the Next Generation Credential (NGC) is written back to the Active Directory User object -- specifically the msDS-KeyCredentialLink attribute. Below is a high level flow for a typical first logon in a hybrid scenario when the user is prompted to setup WHfB. ![Open Image: WHfB key trust first logon flow diagram showing NGC sync delay](/media/posts/identity/cloud-kerberos-trust-part-1/image-35-1024x686-dddc5e2482.png) 1. User signs in and is prompted to setup WHfB 2. PIN is set and Biometric (if applicable) is chosen 3. NGC written to Entra ID user object 4. Microsoft Entra Connect Sync, by default every 30m, synchronizes the NGC to the Active Directory User object. Until that AD Sync happens, the user cannot authenticate to on-premise resources with WHfB. This results in a poor first-run experience where users would setup WHfB and then be told by IT they need to sign back in with their password or *"go and have some pie and wait an hour before trying again"*. ![Open Image: Frustrated man waiting for AD sync - Photo by Andrea Piacquadio from Pexels](/media/posts/identity/cloud-kerberos-trust-part-1/image-34-dee363fd69.png) **Key Trust Pain Points** - Requires a Certificate Authority and a valid trust chain from the device to a 2016 DC. - In order for SSO to function on a Microsoft Entra joined device you need to publish a CRL. This can be challenging to configure and debug if you are not comfortable with Enterprise PKI. - SSO will not work until the NGC is synced back to Active Directory ### Certificate Trust The certificate trust type issues authentication certificates to end users. Users authenticate using a certificate requested using a hardware-bound key created during the built-in provisioning experience of WHfB. Companies using ADFS only had the option to use certificate trust. We still found, in our experience, that most companies used the key trust type for WHfB. Did anybody who configured certificate trust live to tell the tale even? Who knows! Our thoughts on certificate trust are few, so we won't dwell on it in this post. **Certificate Trust Pain Points** - Requires a Federated domain. AD federation with Entra ID. (Who else vomited a little in their mouth when they read ADFS?) - Requires a PKI for SSO to on-premises resources. Users are issued certificates during enrollment to WHfB. - Certificate requirements are complex -- no one got no time for legacy PKI design. --- ## What is Cloud Kerberos Trust? WHfB hybrid key and certificate trust always had a lot of [moving parts](https://learn.microsoft.com/en-us/windows/security/identity-protection/hello-for-business/hello-hybrid-key-trust). Microsoft Entra Connect Sync, Device Registration, PKI, sync wait times and more. There was often misunderstanding on configurations, timings and almost every blog post or Microsoft doc you looked at never quite explained the setup for your *specific* scenario. Microsoft knew this complexity was a roadblock to many and they really wanted to help organisations improve their authentication posture -- moving away from insecure passwords was an itch everyone was eager to satisfy. The big challenge they had to solve was the reliance on the credential sync and complex configuration of many moving parts. Along came Entra Kerberos. Entra Kerberos was first brought in to enable FIDO2 authentication on Microsoft Entra hybrid join devices. Entra Kerberos facilitates kerberos ticket issuance by Entra ID instead of on-premises Domain Controllers. Because a DC was not critical to the ticket issuance, neither was the wait for Microsoft Entra Connect Sync to sync when a user first setup their WHfB credential. Entra Kerberos allows Entra ID to issue TGTs that came down with the PRT -- amazing stuff. Onto a winner: - No need to deploy a public key infrastructure (PKI) or to change an existing PKI - No need to synchronize public keys between Entra ID and Active Directory for users to access on-premises resources. This means that there isn't delay between the user's WHfB provisioning and being able to authenticate to Active Directory - Passwordless security key sign-in can be deployed with minimal extra setup At a high-level, "Cloud Trust" means, that we establish a chain of trust directly with Microsoft Entra ID. Instead of a triangle of trusts that involve our local AD, PKI, the device TPM storage things become incredibly simple, incredibly quickly. > The big game changer with Cloud Key Trust is WHfB works immediately after enrolment for SSO to domain resources There is no need to wait for Microsoft Entra Connect Sync to sync some public key material to establish the trust, or anything like that. It. Just works. So, that's the first problem Cloud Kerberos Trust solves -- the users waiting for sync and the issues that arise from trouble with the msDS-KeyCredentialLink in AD. So, the big game changer with Cloud Key Trust is that WHfB works immediately after enrolment for SSO to domain resources. The Second problem Cloud Kerberos Trust solves -- no more PKI requirements or CRL over http required for hybrid devices. A third problem Cloud Kerberos Trust solves, limited normally to large organisations, is the added CPU overhead for KDC Authentication when using key trust. In some instances those organisations had to spin up extra domain controllers to handle the extra processing load. --- ## Can I get rid of the PIN requirement now? "Silly rabbit! Trix are for kids" And tricks like removing the PIN code is not a thing. You need the PIN as a fallback for your biometrics. Just like with any passwordless solution out there, we need a way for the user to recover in case their biometrics fail, or if there simply are no biometrics available (I hear that people can lose face!). Remember fundamental principles of multi-factor authentication. - *Something the user has*: Any physical object in the possession of the user, such as a security token (USB stick), authenticator app, their device, etc. - *Something the user knows*: Certain knowledge only known to the user, such as a password, PIN, etc. - *Something the user is*: Some physical characteristic of the user (biometrics), such as a fingerprint, etc. So if your argument is that the PIN seems insecure compared to a password, think again -- it ONLY relates to the unlocking of your access token in the TPM for use in Windows Hello for Business. The password on the other hand will let you in from a remote location, which is ideal for a hacker or any bad actor (the password is what you should focus on getting rid of!). But of course, protecting the PIN is still important, so here are a few strategies to consider if you feel that the PIN is a security risk (These are notes from the field and not necessarily to be considered recommendations). 1. Teach users to only use Biometrics, and have a policy of only using the PIN in a secure way (e.g. never in the open Office, and always looking over their shoulder while wearing a tin foil hat!) 2. IT can be a part of the WHfB provision process, and choose the unique PIN for the users. This PIN could be kept with IT, and never disclosed to the user unless required. If you choose this option, remember to disable PIN recovery for the users, and have a policy of never using the same PIN on multiple devices. Using this strategy is not recommended, as you are essentially creating a treasure chest for any bad actor to abuse (i.e. insider risk). 3. Make the PIN more complex but avoid making it possible for the user to replicate their actual password (if you are still providing them with such a relic). This could be achieved by adding a requirement for the use of lower case letters (not upper case) besides just the digits. As a final word of advice on the whole PIN code debacle -- consider your very own smartphone. How do you login to that? Face? Fingerprint? PIN? -- Regardless of your answer, consider that you are holding on to that device 24/7 like a crack addict. And just put things into perspective, when you say that PIN seems less secure than a password. --- ## How does authentication work to on-premise resources? After Cloud Kerberos Trust is enabled for the user (see the next post in our mini series), we can observe the following authentication flow when we attempt to **access** domain resources -- after all, the main purpose of enabling Cloud Trust with WHfB is for SSO authentication to domain resources. ![Open Image: Cloud Kerberos Trust authentication flow diagram for on-premise resource access](/media/posts/identity/cloud-kerberos-trust-part-1/image-44-27f6597540.png) - There is still a requirement for the user to be synchronized from Active Directory. This is how we discover the domain name associated with the user in order to request tickets from the KDC. - Authentication to Active Directory from a Microsoft Entra joined device begins when the user first attempts to use a resource that needs Kerberos authentication. - The Kerberos security support provider, hosted in lsass, uses metadata from the Windows Hello for Business key to get a hint of the user's domain. - Using the hint, the provider uses the **DClocator** service to locate a 2016 domain controller. - DCLocator needs a domain hint, which it gets from the onpremisedomainname that came down with the PRT. - A Domain Controller (KDC) is then returned to the client to continue normal service ticket issuance. **Note** If DNS is broken this lookup will fail -- it's always DNS when things fail (except when it's routing) ![Open Image: DCLocator lookup process for finding a Domain Controller](/media/posts/identity/cloud-kerberos-trust-part-1/image-36-1024x256-3876dc3255.png) - After locating an active 2016 domain controller, the Kerberos provider sends a partial TGT that it received from Entra ID from a previous Entra ID authentication with the domain controller. - The partial TGT contains only the user SID and is signed by Entra Kerberos. - The domain controller will verify that the partial TGT is valid. - On success, the KDC returns a full TGT to the client so the client can begin requesting service tickets. In summary, Entra Kerberos issues a partial TGT to the user. The partial TGT is then exchanged for a full TGT from the KDC and normal service ticket issuance continues when the user tries to access domain resources. **PRO-TIP** DNS hit and miss in your place? You can test if DCLocator is able to return a list of valid DCs by running the **nltest** command ```powershell nltest /dsgetdc:contoso.local ``` ![Open Image: nltest command output showing Domain Controller locator results](/media/posts/identity/cloud-kerberos-trust-part-1/image-38-1024x704-7545b24217.png) An unsuspecting command prompt getting hit by the nltest command and forced to put out! --- ## Summary In part 1 of this mini series we introduced the concept of Cloud Kerberos Trust. Being able to receive partial TGTs from Entra ID is a game changer in terms of speed to SSO logon for on-premises resources AND for simplicity of configuration for admins. In [Part 2](/posts/identity/cloud-kerberos-trust-part-2) we will look at how to configure Cloud Kerberos Trust. We are waiting over on the next page! --- ## [Simplify Windows Hello for Business SSO with Cloud Kerberos Trust - Part 2](https://iphase.dk/posts/identity/cloud-kerberos-trust-part-2) Date: 2023-03-04 Category: identity Tags: cloud-kerberos-trust, sso, windows-hello-for-business, intune, powershell > UPDATED March 2026 -- This post has been reviewed and updated to reflect current Microsoft product names, portal locations, and technology status. See inline notes for specific changes. Cloud Kerberos Trust for Windows Hello for Business is the apex of single sign-on solutions for your Windows devices. In this Trilogy you can expect to learn the what, the how and the **wow**! *Co-authored by Ben Whitmore and Michael Mardahl* Looking for other parts? [Part 1](/posts/identity/cloud-kerberos-trust-part-1) -- [Part 3](/posts/identity/cloud-kerberos-trust-part-3) --- ## The story so far We continue our mini series on Windows Hello for Business Cloud Kerberos Trust. In [Part 1](/posts/identity/cloud-kerberos-trust-part-1) we introduced the concept of Cloud Kerberos Trust and spoke to some of the challenges it can help organisations overcome. One of the things that we love is the **simplicity** of configuration -- both for green field tenants and for organisations already using a different trust method with Windows Hello for Business (WHfB). > Simplicity is elegance ![Open Image: Nanna Mardahl drawing illustrating the simplicity of Cloud Kerberos Trust configuration](/media/posts/identity/cloud-kerberos-trust-part-2/image-61-1024x711-d92b1355b0.png) Drawing by Nanna Mardahl In this post, we will show you how to configure Cloud Kerberos Trust for your on-premises infrastructure and how to create a configuration policy for your client devices. --- ## Enabling Entra Kerberos for Cloud Kerberos Trust This is so easy. Honestly, put one hand behind you back, juggle some wet frogs and sing "I will always love you", all at the same time, and you will still be able to configure Entra Kerberos too. Enabling Entra Kerberos creates an "Entra Kerberos" server object in the domain. **This server object:** - Appears as a Read Only Domain Controller (RODC) object, but isn't associated with any physical servers. - Is only used by Entra ID to generate partial TGTs for the Active Directory domain. The same rules and restrictions used for RODCs apply to the Entra Kerberos Server object. We will configure **Entra Kerberos** in our lab. Full prerequisites can be found [here](https://learn.microsoft.com/en-us/windows/security/identity-protection/hello-for-business/hello-hybrid-cloud-kerberos-trust?tabs=intune#prerequisites) and the code samples are taken from the Microsoft docs [here](https://learn.microsoft.com/en-us/azure/active-directory/authentication/howto-authentication-passwordless-security-key-on-premises#install-the-azure-ad-kerberos-powershell-module). ### 1. Download and install the Entra Kerberos PowerShell module From the [PowerShell Gallery](https://www.powershellgallery.com/packages/AzureADHybridAuthenticationManagement). This can be done directly on the Domain Controller or from a computer that can access the Domain Controller. ![Open Image: PowerShell Gallery install command for AzureADHybridAuthenticationManagement module](/media/posts/identity/cloud-kerberos-trust-part-2/image-39-1024x426-057ea72503.png) ```powershell Install-Module -Name AzureADHybridAuthenticationManagement -AllowClobber ``` > NOTE (Updated 2026): The `AzureADHybridAuthenticationManagement` module retains its original name for backward compatibility despite the Entra ID rebrand. The cmdlets `Set-AzureADKerberosServer` and `Get-AzureADKerberosServer` in this module are NOT deprecated -- they are the current supported method for managing the Entra Kerberos server object. TLS 1.2 is required to access the PowerShell Gallery. Run the following command if it is not enabled: ```powershell [Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12 ``` ### 2. Run the following ```powershell # Specify the on-premises Active Directory domain. A new Entra # Kerberos Server object will be created in this Active Directory domain. $domain = $env:USERDNSDOMAIN # Enter a UPN of a Microsoft Entra ID global administrator $userPrincipalName = "admin@contoso.onmicrosoft.com" # Enter a domain administrator username and password. $domainCred = Get-Credential # Create the new Entra Kerberos Server object in Active Directory # and then publish it to Microsoft Entra ID. # Open an interactive sign-in prompt with given username to access Entra ID. Set-AzureADKerberosServer -Domain $domain -UserPrincipalName $userPrincipalName -DomainCredential $domainCred ``` ![Open Image: Set-AzureADKerberosServer command execution and output](/media/posts/identity/cloud-kerberos-trust-part-2/image-41-1024x662-f56c0117a2.png) ### 3. Verify that the Kerberos server RODC object was created successfully ```powershell Get-AzureADKerberosServer -Domain $domain -UserPrincipalName $userPrincipalName ``` ![Open Image: Get-AzureADKerberosServer output showing RODC object properties](/media/posts/identity/cloud-kerberos-trust-part-2/image-42-1024x261-a1e92b2f4e.png) ![Open Image: Entra Kerberos server object verification in Active Directory](/media/posts/identity/cloud-kerberos-trust-part-2/image-43-1024x287-5754e46387.png) ### 4. Also verify that the krbtgt user account was created (it is intentionally disabled) ![Open Image: Disabled krbtgt user account created for Entra Kerberos in Active Directory Users and Computers](/media/posts/identity/cloud-kerberos-trust-part-2/image-54-1024x560-d84c1a2d57.png) --- ## Configure Cloud Key Trust using Intune We can either use a GPO or push a configuration from Intune. If you are interested in using a GPO, read more [here](https://learn.microsoft.com/en-us/windows/security/identity-protection/hello-for-business/hello-hybrid-cloud-kerberos-trust?tabs=gpo#tabpanel_1_gpo). In this post we will push the configuration from Intune (this is the way). Ensure the client devices are a minimum of Windows 10 21H2 / Windows 11 Pro or Enterprise SKU. Perhaps consider using an [Intune Filter](https://learn.microsoft.com/en-us/mem/intune/fundamentals/filters) for targeting. ### 1. Create a configuration profile Assuming you don't already have an existing policy for Windows Hello for Business, we will add it in its simplest form using the Settings Catalog. ### 2. Settings catalog profile Go to the Windows configuration profiles area and click "Create profile". Select the "Windows 10 and later" platform along with the profile type "Settings catalog" and click **Create**. ![Open Image: Intune create profile dialog selecting Windows 10 and later with Settings catalog profile type](/media/posts/identity/cloud-kerberos-trust-part-2/image-1024x390-d053f35f8c.png) Give it an appropriate name and description and click **next**. Now, start adding settings by clicking on the "Add settings" button. ![Open Image: Intune Settings Catalog add settings button in configuration profile](/media/posts/identity/cloud-kerberos-trust-part-2/image-1-1024x438-5b7c925cab.png) The list of settings is LOOOONG, so, you want to do a search for "Windows Hello for Business" and click on the appearing category name "Windows Hello for Business" when it returns the result. Now we start by selecting the following settings (this is a minimum): ![Open Image: Settings Catalog showing Use Cloud Trust For On Prem Auth and Use Passport for Work settings](/media/posts/identity/cloud-kerberos-trust-part-2/image-2-1024x683-46552298e0.png) - Use Cloud Trust For On Prem Auth - Use Passport for Work (User) A few things to note here... One is, that Passport for Work is the name in the CSP for "Windows Hello for Business", it is a leftover from Microsoft rebranding. So, don't get stuck on that. Speaking of rebranding, "Cloud Trust" and "Cloud Kerberos Trust" are the exact same thing, just another rebranding. Second thing is that we selected a policy setting with the text "(User)" in it. This indicates that the user is the target. Even if you assign to a device, this policy will be a user scoped policy on that device. This takes precedence over any other policies that might be targeted to the device. For Windows Hello for Business in Intune, the rules of precedence is "Tenant wide settings" over "User" and lastly "Device". ![Open Image: Intune Settings Catalog with Use Cloud Trust and Use Passport for Work enabled](/media/posts/identity/cloud-kerberos-trust-part-2/image-3-1024x347-d86b88f963.png) Lastly we enable the settings and move on to the next part. ### 3. Assignments Assign the profile to your desired group. You can target either users or devices according to your own preference or policy in-house. ![Open Image: Intune profile assignments showing group targeting options](/media/posts/identity/cloud-kerberos-trust-part-2/image-49-1024x330-2933599cac.png) ### 4. Test the policy worked Now we are assuming that the policy has applied from Intune... At this stage, after a synced user logs in using WHfB, verify that a partial TGT has been issued using the command: ```powershell klist cloud_debug ``` ![Open Image: klist cloud_debug output showing Cloud Primary TGT with partial TGT details](/media/posts/identity/cloud-kerberos-trust-part-2/image-55-1024x664-b36b4e073a.png) You can also verify in the event log if the policy has been set successfully on the client. ![Open Image: Windows Event Viewer showing WHfB Cloud Trust policy applied successfully with Event ID 358](/media/posts/identity/cloud-kerberos-trust-part-2/image-58-1024x808-61943bcb49.png) If you don't see the Cloud Primary TGT, then you might not have gotten a new token from Entra ID, and you can force that process by running the command line (as the user): ```powershell DSREGCMD /REFRESHPRT ``` Then wait a bit and issue the command: ```powershell DSREGCMD /STATUS ``` You should be able to see the "SSO" part has the following values set: ``` OnPremTgt : YES CloudTgt : YES ``` --- ## Summary In part 2 of this mini series we looked at how to configure Cloud Kerberos Trust. In [Part 3](/posts/identity/cloud-kerberos-trust-part-3) we will dive a little deeper into some of the moving parts and help with some troubleshooting tips. Stay tuned for more fun! --- ## [Simplify Windows Hello for Business SSO with Cloud Kerberos Trust - Part 3](https://iphase.dk/posts/identity/cloud-kerberos-trust-part-3) Date: 2023-03-04 Category: identity Tags: cloud-kerberos-trust, sso, windows-hello-for-business, kerberos, active-directory > UPDATED March 2026 -- This post has been reviewed and updated to reflect current Microsoft product names, portal locations, and technology status. See inline notes for specific changes. Cloud Kerberos Trust for Windows Hello for Business is the apex of single sign-on solutions for your Windows devices. In this Trilogy you can expect to learn the what, the how and the **wow**! *Co-authored by Ben Whitmore and Michael Mardahl* Looking for other parts? [Part 1](/posts/identity/cloud-kerberos-trust-part-1) -- [Part 2](/posts/identity/cloud-kerberos-trust-part-2) --- ## The story so far We continue our mini series on Windows Hello for Business Cloud Kerberos Trust. In [Part 2](/posts/identity/cloud-kerberos-trust-part-2) we walked through the configuration of Cloud Kerberos Trust for both on-premise infrastructure and clients. If you missed part 1 of our series, your journey into "Cloud Kerberos Trust" should start here: [Part 1](/posts/identity/cloud-kerberos-trust-part-1) We love the elegance and simplicity of Cloud Kerberos Trust but in this final post of the mini series we will dive a little deeper and look at some of the mechanics and moving parts to help you understand and troubleshoot your way out of a hole -- if you need to. Hold tight and get your engineer brain engaged as we equip you with the tools you need to succeed! > Pick-up your engineering toolkit and come down the rabbit hole --- ## Migrating from other Trust Models This question often comes up, naturally. What if you are using hybrid key trust and you want to begin kicking the tires on cloud kerberos trust? The answer is simpler than you might think. Migrating from a hybrid key trust model is very simple. For Microsoft Entra joined and Microsoft Entra hybrid join devices, simply deploy the Intune configuration to enable cloud kerberos trust and the user will switch to cloud kerberos trust. The extra requirement for Microsoft Entra hybrid join devices is the device requires line-of-sight to a DC at first logon or it will fall back to using key trust. Migrating from certificate trust has more moving parts. You must disable the existing certificate trust policy, deploy the Intune configuration to enable cloud kerberos trust, delete the existing hello credential and sign back in to the device. Use the following command to delete the existing hello credential: ```powershell certutil.exe -DeleteHelloContainer ``` The "Key" thing to understand, (see what I did there?) is that a policy that defines neither: "Use certificate for on-premises authentication" or "Use cloud trust for on-premises authentication" is considered as using the "Key Trust" model for authentication. ![Open Image: Windows Hello for Business settings GPO showing certificate and cloud trust options](/media/posts/identity/cloud-kerberos-trust-part-3/image-63-1024x405-ebae7e4663.png) --- ## Privileged Accounts Highly privileged accounts are not granted, by default, to use FIDO2 security keys and/or cloud kerberos trust to login to a device. The local security policy forbids it. The **msDS-NeverRevealGroup** property is used to define which AD objects are forbidden to have their passwords cached on the Kerberos RODC. To unblock the accounts, use Active Directory Users and Computers to modify the **msDS-NeverRevealGroup** property of the Entra Kerberos Computer object (CN=AzureADKerberos,OU=Domain Controllers,\). ![Open Image: Active Directory Users and Computers showing msDS-NeverRevealGroup property for AzureADKerberos object](/media/posts/identity/cloud-kerberos-trust-part-3/image-60-1024x674-a4b69ec78d.png) Caution should be used when relaxing any local security policy. Understand the impact, if any, of what you are about to do. --- ## Next Generation Credential (NGC) The Next Generation Credential (NGC) is important. Verify the NGC has been set on client devices correctly by using **dsregcmd** (in the user context) command. **NgcSet: YES** means that a hello key has been set for the current user. ```powershell dsregcmd /status ``` ![Open Image: DSREGCMD /status output showing NgcSet YES for a user session](/media/posts/identity/cloud-kerberos-trust-part-3/image-59-1024x471-ea58485c77.png) Verify the NGC has been saved to the user object in Entra ID using [Graph Explorer](https://aka.ms/ge). Examine the deviceKeys attribute for the NGC assigned to the device the user logged on to using WHfB. ![Open Image: Graph Explorer showing WHfB deviceKeys attribute with NGC data](/media/posts/identity/cloud-kerberos-trust-part-3/image-51-1024x624-b6777edf06.png) The NGC is present as a result of the normal WHfB authentication process -- it is not specific to us enabling Entra Kerberos but it will be important when we look at other moving parts later in this blog. The NGC contains the base64-encoded public portion of the asymmetric key pair used for WHfB authentication. You can also see in the Windows event log that the NGC was created and written to the user object in Entra ID. ![Open Image: Windows Hello for Business event log showing NGC creation event](/media/posts/identity/cloud-kerberos-trust-part-3/image-57-1024x542-a6126e3cff.png) In Graph Explorer, we can also see some other cool metadata that will be useful when we deep dive later! ![Open Image: Graph Explorer showing additional WHfB key metadata including key material and usage](/media/posts/identity/cloud-kerberos-trust-part-3/image-53-1024x932-3913ef6b1c.png) --- ## Cloud Kerberos Trust under the Microscope Before we dial in our microscopes it is best we define what the high level components are in a Windows Hello for Business Cloud Kerberos Trust relationship as this will help us sort through the finer details. - AzureADKerberos - Windows 10/11 - Windows Server 2016 or newer DC - User account synced from On-Premise Yes, it is basically just those few things, no PKI is explicitly required! And now we have that sorted, on to the nitty gritty. ### AzureADKerberos In Part 2, we provisioned the Entra Kerberos Read-Only Domain Controller (RODC) object into the "Domain Controllers" OU of our local Active Directory domain. So what happens when the object is created? It creates a server object that can issue Ticket Granting Tickets (TGTs) for Kerberos in your domain. The encryption key is then securely published to Entra ID, which allows it to issue a partial TGT as part of the magic behind Cloud Kerberos Trust. This partial TGT is received by the user via the Primary Refresh Token when they authenticate with Entra ID. The TGT includes only the user's SID, and no authorization data. ![Open Image: Illustration of a user starving for SSO to on-prem resources](/media/posts/identity/cloud-kerberos-trust-part-3/image-68-57e23bf36e.png) A poor user starving for SSO to on-prem resources! This is a one-time operation, and for each on-premises domain, an object will represent it in Entra ID. No background processes are enabled to keep things in sync. It's all very secure! If you have more than one on-premises domain, each one will have a key in Entra ID that corresponds to the on-premises domain. Thus, if you have multiple domains, this is not an issue. However, if you have a single domain and multiple tenants, the issue becomes more complicated, as there is no option to just publish the encryption key of the current Entra Kerberos RODC object into another tenant. It's important to know that, since the encryption key (krbtgt) is not synced after the initial publishing into Entra ID, it's imperative to only use the AzureADHybridAuthenticationManagement PowerShell module to rotate the krbtgt of the Entra Kerberos RODC object. ```powershell Set-AzureADKerberosServer -Domain $domain -UserPrincipalName $userprincipalname -RotateServerKey ``` There is more on the official Microsoft Learn site: [Passwordless security key sign-in to on-premises resources](https://learn.microsoft.com/en-us/azure/active-directory/authentication/howto-authentication-passwordless-security-key-on-premises#rotate-the-azure-ad-kerberos-server-key) ### Windows 10/11 ICYMI: Windows is required for Windows Hello for Business to function. But not just any version of Windows. Windows 10 21H2 and later are recommended because the Cloud Kerberos Trust feature was introduced with this build. So what happens during sign-in, since it is important to have an updated version of Windows? Well it depends on what join-type your device is using -- Microsoft Entra hybrid join or Microsoft Entra joined. Let's start with the most common "Microsoft Entra hybrid join". #### Microsoft Entra hybrid join There are many roads to Rome, and this one takes the longest of them all! ![Open Image: WHfB sign-in process flow diagram for authentication on a hybrid joined device](/media/posts/identity/cloud-kerberos-trust-part-3/image-65-03d267aac0.png) #### Microsoft Entra joined Be prepared to be amazed at the simplicity of being in a Microsoft Entra joined state and doing SSO to your on-prem resources: ![Open Image: WHfB sign-in process flow diagram for authentication on a Microsoft Entra joined device](/media/posts/identity/cloud-kerberos-trust-part-3/image-66-221edef270.png) If you wanna get deeper into it and follow these awesome diagram flows from Microsoft, there is the official documentation at Microsoft Learn: [How Windows Hello for Business works -- Authentication](https://learn.microsoft.com/en-us/windows/security/identity-protection/hello-for-business/hello-how-it-works-authentication) ### Windows Server 2016 or newer DC Now what's wrong with the classic Server OS of yesteryear? It's kerberos trust! Surely it matters not what version ones domain controller is at? Well that part right and some parts wrong. See, there must be one or more Windows Server 2016 DCs to support both the Key Trust and the Cloud Kerberos Trust models, as they need to be able to interpret the Cloud TGT. The amount of DCs is determined by the amount of overhead the additional Kerberos requests cause in your domain. So even if you choose to upgrade all your current DCs that might not be enough if you decide everyone has to use WHfB. As Windows Hello for Business generates a sign-in process overhead, and you might need to plop in a few more "Mega Godzilla Beast servers" (as Mark Russinovich likes to call his pet servers) to take the load. So, we are talking about Windows Server 2016+ Domain Controllers, which just upgrades the Schema when introduced. But what about the forest and domain functional level you ask? Well... Windows Server 2008 R2 Domain/Forest functional level is the accepted minimum. If you like leftovers and dumpster diving, you can go right ahead and keep it like that. ![Open Image: Comparison illustration of upgraded vs legacy Domain Controller environments](/media/posts/identity/cloud-kerberos-trust-part-3/image-11-13cdb92e0a.png) The difference between people who have an upgraded Domain Controller environment and those who don't. ### User account synced from On-Premise We have already eluded to the fact that an on-premise user account is indeed needed -- so there is no crying to mommy when your pure cloud user won't magically SSO into the ocean of legacy file shares you might have on-premise. The simple fact is that the TGT that you get from Cloud Kerberos, is in fact just an identifier, proving that you are in fact a synced user from the on-prem domain. And the full TGT which you get from the DC, contains information that comes from the on-prem. Entra ID has no clue about what resources are in your on-prem, and even if it did, the on-prem is likely not trusting Entra's own Kerberos tokens (yes, there is another thing called Entra Kerberos, which can issue full TGTs for resources like file shares in an Azure Storage account, but I digress). To get deeper into how all this works, we need to spin up a new headline called (drum-roll please)... --- ## Kerberos is King! ![Open Image: Illustration of Michael, Ben and Fluffy the dog as the three heads of Kerberos](/media/posts/identity/cloud-kerberos-trust-part-3/image-1024x546-1744f9fe88.png) Meet Michael, Ben and Fluffy the dog. Cerberos is the mythical creature that guards hades, the gates of hell. Fluffy is the watchdog of the underworld etc. In previous roles he was guarding Windows Vista and was born in the 80's when no one cared what shampoo you used. Kerberos has 3 parts/heads (Michael = User, Fluffy = KDC, Ben = Service) So what is Kerberos and how does it help us when we are looking to SSO to our domain resources? Here are some Kerberos basics: - "Kerberos" is just a cryptographic ticketing system - In order to request tickets to domain resources, the Kerberos protocol needs to know where the "Ticket Master" is - The "Ticket Master" is called the Key Distribution Centre (KDC) - The KDC in a Windows Domain is a Domain Controller Basically I need to get a ticket from the domain controller, or KDC, to prove who I am to the service e.g. file server. ### Finding a KDC Microsoft Entra joined devices are not aware of your domain, so how do they find the KDC to get tickets? That's easy and takes us back to the 80's again. **DCLOCATOR** is a process used by Windows systems to locate the closest available Domain Controller. First my client needs to find the KDC, how does it do this when the client knows nothing about the domain? Ah-ha, remember we have some synced attributes that come down with our Primary Refresh Token at logon. DCLocator needs a domain hint, which it gets from the onpremisedomainname attribute that came down with this PRT. A Domain Controller (KDC) is returned to the client as a result of, effectively, a DNS query. ![Open Image: DCLocator DNS query process for finding a Key Distribution Centre](/media/posts/identity/cloud-kerberos-trust-part-3/image-1-eadcab0d99.png) We can simulate what DCLocator does by running the **nltest** command on a device and passing the domain name: ```powershell nltest /dsgetdc:byteben.com ``` ![Open Image: nltest dsgetdc command output returning Domain Controller information](/media/posts/identity/cloud-kerberos-trust-part-3/image-2-1024x566-64120ad822.png) If on-premises DNS is broken or the client is not configured correctly for DNS. This query might/will fail. It's always DNS right? ### Tickets Please Now we know where the KDC is, let's go into a bit more detail on how Kerberos ticket issuance works and helps us to access domain resources. ![Open Image: Kerberos ticket issuance flow diagram showing partial TGT exchange for full TGT and service ticket](/media/posts/identity/cloud-kerberos-trust-part-3/image-4-cb85d81c29.png) 1. The partial TGT we obtained from Entra ID is sent to the KDC. 2. The KDC validates the partial TGT. 3. The KDC then issues a "Golden" ticket to the user. The golden ticket, or Full TGT, is proof the user authenticated. Authentication has a lot of overhead so we don't want to keep doing it. 4. The user then sends that TGT (proof that they can come into the nightclub) along with another request to access a service, like CIFS (fileshare). 5. The KDC sees the user has a valid TGT (BTW, only the KDC can decrypt the TGT) and issues a "Service Ticket". The service ticket contains things like group membership and service requested. We can see the AS-REQ for a ticket come into the KDC (You can filter Wireshark using the KRB5 protocol to see this cool stuff): ![Open Image: Wireshark capture showing KRB5 AS-REQ Kerberos authentication request to KDC](/media/posts/identity/cloud-kerberos-trust-part-3/image-5-1024x283-87e60124b9.png) When we try to access a file share, we see the client send a request to the KDC. The request contains our TGT which validates who we are: ![Open Image: Wireshark capture showing TGS-REQ with TGT for file share access](/media/posts/identity/cloud-kerberos-trust-part-3/image-7-1024x431-9bf62d84d1.png) The KDC then issues us a service ticket for the resource we just tried to access. In this example we accessed a file share on bb-app1.byteben.com: ![Open Image: Wireshark capture showing TGS-REP with service ticket issued for bb-app1.byteben.com](/media/posts/identity/cloud-kerberos-trust-part-3/image-8-1024x407-4ce10f4bc0.png) ### Klist **klist** displays all the service tickets we have been granted. Here is the service ticket we requested to access the file share on bb-app1.byteben.com: ![Open Image: klist output showing CIFS service ticket for bb-app1.byteben.com](/media/posts/identity/cloud-kerberos-trust-part-3/image-9-cc74693ed5.png) Klist also has another cool command when working with Cloud Kerberos Trust: ```powershell klist /cloud_debug ``` ![Open Image: klist cloud_debug output showing Cloud TGT details and partial TGT information](/media/posts/identity/cloud-kerberos-trust-part-3/image-10-c696c48d54.png) --- ## MFA YES! In case it was not obvious, the requirement to enroll into Windows Hello for Business is that the user can complete an MFA request from Entra ID. And there is absolutely no way around that. But there are tricks like using Temporary Access Pass in Entra ID, in case you want to pre-provision WHfB for end users, or you don't want or need them to have MFA capabilities outside of their device. --- ## Summary ![Open Image: Cloud Kerberos Trust trilogy summary illustration](/media/posts/identity/cloud-kerberos-trust-part-3/image-69-e341e63f6e.png) Hopefully this 3 part mini series has been useful. It's always difficult to know how deep to go and keep the content engaging. If you would like any more info, please reach out! Bookmark this page, because there is no way you will remember all of this stuff, and don't forget that Ben and Michael work for likes and follows on Twitter and LinkedIn. Fluffy takes bones, peanut butter and cinema ticket stubs as donations. --- ## [2FA/MFA - Why Multi-Factor Authentication is Important](https://iphase.dk/posts/identity/why-multi-factor-authentication-is-important) Date: 2023-01-17 Category: identity Tags: mfa, multi-factor-authentication, phishing, security, passwordless > UPDATED March 2026 -- This post has been reviewed and updated to reflect current Microsoft product names, portal locations, and technology status. See inline notes for specific changes. In this article we take a high level view of multi-factor authentication, the concepts and its importance in todays corporate IT landscape. As the world becomes increasingly digital, the need for secure access to online accounts and systems becomes more critical than ever. One of the most effective ways to protect against unauthorised access is through the use of multi-factor authentication (MFA). In this article, we will explore the importance of MFA in the Microsoft Cloud and how it can help protect your organisations sensitive data and systems. ## Introduction **Outline:** For those who are unfamiliar with what a phishing attack is, it is where an attacker attempts to fraudulently obtain sensitive information from a user by posing as someone or something that the person/organisation trusts. Phishing attacks target passwords and usernames via various methods including email, pop-up windows, instant message, text messages, and social network sites. It ruins lives and cost companies millions of dollars each month. One of the best ways to protect against phishing attacks is through the use of MFA. **Takeaway:** Use MFA or Passwordless. And do not click on links in unexpected emails from people you do or do not know. Always be suspicious of any link that requests you to enter your login credentials for an unknown site and be sure that a familiar sign-in page is using the right domain name in the address bar. *Disclaimer: There are a plethora of ways to put together MFA now a days, and not all scenarios or methods are covered in this article for the sake of readability.* ## What is multi-factor authentication? ![Open Image: A person wondering about all the multi-factor authentication choices](/media/posts/identity/why-multi-factor-authentication-is-important/DALL·E-2023-01-17-10.01.18-a-confused-person-with-pictograms-of-a-smartphone-padlock-text-message-and-key-fob-floating-around-their-head.-In-an-isometric-style-clean-fonts-us-1-71a555ce93.png) Multi-factor authentication (MFA) is a process of verifying your identity by using more than one form of identification. It can be as simple or as complicated as you want it to be, but the goal is always the same: to make sure that only you can access your account. There are three main types of MFA: SMS-based, app-based and hardware-based. Each type has its own advantages and disadvantages when compared with other methods, so let's take a look at each one individually: ### SMS-based MFA This is the most basic form of two-factor authentication. When you enable it, you'll receive a text message with a PIN code every time you log in to your account. You must enter this PIN into the site or app before gaining access to your account. The benefit of SMS-based MFA is that it's very easy to set up. You don't need any special hardware or software, just a phone number and access to your email account. The downside is that there are often security issues with SMS messages -- they can be intercepted by hackers or spoofed by scam artists who want to take over your account. If this happens, you'll have no way to prove who you are without resetting all of your passwords. ### App-based MFA App-based MFA is similar to SMS-based MFA, but instead of receiving a code via text message, you receive it through an app on your phone. For Microsoft 365 users the best app is the Microsoft Authenticator, which can be downloaded for free from the Apple App Store or Google Play Store. Once you install it, all you need to do is scan a QR code using the app and then enter the six-digit code into the set up wizard. The benefit of app-based MFA is that it's more secure than SMS-based MFA because the authentication process is tied to your physical device and not sent unencrypted over the airwaves. The downside is that it's more difficult to set up. You need to install an app on your phone and then scan a QR code using that app, which can be tricky if you're not tech savvy. ### Hardware-based MFA The most secure way to set up Multi-factor authentication is with a hardware token. This device can look like a USB flash drive, but instead of containing files, it contains a secure chip that generates one-time passwords (OTPs). When you install the software on your computer and plug in the hardware token, you'll be prompted to enter your username and password before it will generate any codes for you. This is a solution often used in companies where employees don't have access to a phone, and hence they are unable to use SMS or App. The benefit of hardware-based MFA is that it's more secure than any other method of two-factor MFA authentication. The downside is that it's more expensive and difficult to set up. You need to purchase the device and then install software on your computer that works with the token -- something most people don't have the time or inclination to do. ## Again, why is multi-factor authentication so important? Multi-factor authentication is a way to protect your accounts from being hacked by using more than one method of verification. It's important to have this on all of your accounts because it works as an extra layer of security that prevents unauthorised access to your account and prevents identity theft. Being passive about this type of security can actually leave you open to lawsuits. If your identity and the trust that others have in it, is used to commit fraud against others, then you are most likely going to be liable for the damages. These lawsuits have already happened and they are not in your favour if you as a person or as a company have been passive. ## What has MFA done for the world? MFA has reduced the amount of fraudulent sign-ins on accounts since its inception. In fact, MFA provides an added layer of security that gives users (and admins) peace of mind when it comes to their corporate/personal information and financial data. MFA has: - Reduced risk of account takeover - Reduced risk of phishing attacks and identity theft - Reduced risks associated with password reuse by requiring two-factor authentication every time you log in (even if you're using a password manager) Remember to thank your MFA device when you use it. ![Open Image: A person loving their authenticator app](/media/posts/identity/why-multi-factor-authentication-is-important/DALL·E-2023-01-17-09.54.45-A-person-kissing-their-smartphone.-In-a-illustrative-style-clean-font-1024x1024-9b34a12fdf.png) ## What is better than MFA? A concept that is quickly gaining in popularity is the Passwordless sign-in. Which is the next step in authentication evolution. It is basically a method to login without a password, and thus prevents anyone from stealing it in the first place! Microsoft offers easy on-boarding to Passwordless with their Authenticator Phone sign-in feature and for the Windows desktop they have [Windows Hello for Business](https://msendpointmgr.com/2022/09/04/manage-windows-hello-for-business-whfb-with-intune/) as an excellent offering. Passwordless technologies aim to address some of the weaknesses of MFA. But, remember that any MFA solution is better than no MFA solution! But, I digress, this article was only meant to be about Multi-factor authentication (MFA). So, follow along here on the blog for an article on passwordless in the near future! In the mean time you can enjoy learning how to enable Passwordless using the Microsoft Authenticator, in this [article on Microsoft Learn](https://learn.microsoft.com/azure/active-directory/authentication/howto-authentication-passwordless-phone?WT.mc_id=ES-MVP-5004117). ## Conclusion Multi-factor authentication is an essential tool for protecting against unauthorised access to online accounts and systems. By using a combination of something you know, something you have, and something you are, MFA provides an extra layer of security that makes it much more difficult for cybercriminals to gain access to your sensitive data and systems. If you want to learn more about how MFA can protect your business, check out the [article on Microsoft Learn](https://learn.microsoft.com/microsoft-365/admin/security-and-compliance/set-up-multi-factor-authentication?WT.mc_id=ES-MVP-5004117) that shows how you can get started on this important first step on your journey towards Zero-Trust and a Passwordless future! ## 2026 Update -- MFA Is Now Mandatory Since this article was written in 2023, Microsoft has moved from recommendation to enforcement. MFA is now mandatory for all Microsoft cloud admin portals as part of Microsoft's Secure Future Initiative. - **Phase 1 (March 2025):** Azure Portal, Microsoft Entra admin center, Microsoft Intune admin center -- fully enforced - **Phase 2 (October 2025):** Azure CLI, Azure PowerShell, Infrastructure as Code tools -- fully enforced - **Microsoft 365 Admin Center:** Full enforcement February 9, 2026 The best path forward is not just MFA but phishing-resistant authentication. Passkeys -- either device-bound via Microsoft Authenticator or hardware FIDO2 keys -- are now the recommended approach. See the [2026 passkeys and MFA update post](/posts/identity/passkeys-personal-phone-mfa-update/) for current deployment guidance. --- ## [Fix onmicrosoft.com Missing Default Domain](https://iphase.dk/posts/identity/onmicrosoft-com-missing-default-domain) Date: 2022-03-07 Category: identity Tags: exchange-online, hybrid-identity, onmicrosoft-com, upn, entra-connect, troubleshooting > UPDATED March 2026 -- This post has been reviewed and updated to reflect current Microsoft product names, portal locations, and technology status. See inline notes for specific changes. Ever found yourself in a messed up Hybrid Exchange environment, and some or all of your synced identities are missing something. Maybe the onmicrosoft.com missing domain bug has infected your tenant? (No its not really a bug, and it does not infect you, but shit happens as they say...) It should be easy to fix, no? Well it is... but if you google it, you will find suggestions like deleting the users or removing them from sync, then making them cloud only. And then hard or soft matching them again after they have received the *domain*.**onmicrosoft.com** alias back. That seems like a terrible waste of time if you ask me. No, you can't just add that domain on-premise to the proxyAddress field and be over with it -- *domain*.**onmicrosoft.com** is not synced as an alias. ## The quick(ish) fix You don't need to delete the user or anything fancy like that to fix that onmicrosoft.com missing default domain -- here are the steps to fix it in production. ![Open Image: Diagram showing the onmicrosoft.com fix workflow](/media/posts/identity/onmicrosoft-com-missing-default-domain/onmicrosoft.com_-79b75a44a3.png) ### Add the UPN Suffix to your domain In order for this fix to work, we need to add the tenant default domain as a UPN Suffix to our on-prem active directory. This is a simple one-time thing. Open up "Active Directory Domains and Trusts" and follow the steps in the screenshot: ![Open Image: Active Directory Domains and Trusts dialog showing how to add the onmicrosoft.com UPN suffix](/media/posts/identity/onmicrosoft-com-missing-default-domain/active-directory-domains-and-trusts-875x1024-604cc7a7f3.jpg) 1. Right-click and select the properties of "Active directory domains and trusts" in the MMC 2. Type in your default tenant domain (e.g. mytenant.onmicrosoft.com) 3. Click "Add" 4. Click "OK" Now we can do some magic on the user-account... ### Change the users UPN Now the trick is to change the users logon name to match that of the default tenant domain, because unlike the e-mail alias (proxyAddress), the logon name will actually sync a change if using the default tenant domain. So crack open your "Active Directory Users and Computers" MMC, and lets follow along with the screenshot: ![Open Image: Active Directory Users and Computers showing the Account tab with UPN suffix selection](/media/posts/identity/onmicrosoft-com-missing-default-domain/image-1-1024x760-78e9d6d2d9.png) 1. Find the user with issues and go to the "Account" tab. 2. From the User logon name domain name dropdown, **note the current selection** and then select the newly added UPN suffix (i.e. mytenant.onmicrosoft.com) 3. Click "OK" Now, all you have to do is either wait or force a sync with Entra Connect sync. Forcing it will obviously be faster. After sync has completed, you should verify that the user login has actually changed in Entra ID or the M365 Admin portal. And at the same time, you can verify that the default domain e-mail alias is now in place as it should be. ### Put it all back as it was After you have confirmed that the cloud user has received the changes from on-prem, you simply need to put back the original domain from step 2 in the screenshot above. Then again wait for sync or force it. If you wish to get rid of the UPN Suffix in your local AD, you can do that at this point, it is no longer needed. Just do sort of the reverse of what we did in the first step. ## Final words One could wish for a "fix it" button in Exchange Online or the M365 portal to take care of this little bug of the onmicrosoft.com missing in action. But, I hope I have at least saved you some time by sharing this wacky workaround. Of course all of this can be scripted if you have hundreds or thousands of users in this state. And before you ask why you even need this domain? Then think about the fact that it is default. And you never really know what 3rd party program or script is expecting to find that specific e-mail Alias on an account. --- ## [How to remove credentials from a FIDO2 key like a boss](https://iphase.dk/posts/identity/how-to-remove-credentials-from-a-fido2-key) Date: 2022-01-25 Category: identity Tags: fido2, security-keys, passwordless, feitian > UPDATED March 2026 -- This post has been reviewed and updated to reflect current Microsoft product names, portal locations, and technology status. See inline notes for specific changes. In this blog post I will show you how to remove credentials from a FIDO2 key (Feitian keys specifically in this case) and some reasons why you might need to do some housekeeping on the FIDO2 devices you own. - **Intended audience** - End-users and admins that have experience using the FIDO2 key in general. - **Required hardware** - Feitian FIDO2 key. - **Operating system** - Windows 10 or 11, MacOS ## Why bother spending time to remove credentials from a FIDO2 key? So, why even bother with the cleanup? Some of these devices can hold unlimited credentials? ### Long lists of credentials to select from During your journey with your FIDO2 devices, you might have tested access with multiple credentials on the same web service. And afterward, have to select which of the numerous credentials you wish to access a service with. That might be annoying once you get to a point where those other accounts are no longer needed. And according to the KonMari principle, you should hold your credentials in your hand once in a while and ask yourself if they "spark joy" -- if not, then remove those credentials. ### Windows login confusion Some services like passwordless login to Windows might not even let you select which account to use if multiple accounts exist for the same tenant/service. These usually prefer the last credential added to the key. So, in that case, you might still want multiple credentials, but you need to change the order in which they are listed. Well, as far as I know, the only way of changing that order is to delete the credential you want the service to auto-select and then add it again, making it the last added credential to the key, thus being the one that is auto-selected for use. ## How to actually remove credentials from a FIDO2 key The methods differ from vendor to vendor, and some browsers also have key management support, which is semi-universal. Still, it seems to have been removed in some updates, so I will focus on the vendor-specific methods of doing this task. ## Windows 11 Native Option (Added 2026) Windows 11 (22H2 and later) includes a built-in FIDO2 credential manager accessible directly from Settings, without requiring any vendor-specific application. To remove credentials natively on Windows 11: 1. Open **Settings** > **Accounts** > **Sign-in options** 2. Under **Security key**, click **Manage** 3. Insert your FIDO2 key when prompted and enter the key PIN 4. Select the credential to remove and click **Remove** This method works for any FIDO2 security key and is the recommended approach on Windows 11. The vendor-specific method below remains useful for macOS, older Windows versions, or when more detailed credential inspection is needed. ### The Feitian way Since Feitian was nice enough to send me a key for testing, this guide will focus on using their tool, but the process is more or less the same for all vendors, and they just have different applications to do it. Note that to remove credentials from a FIDO2 key, you will most likely need to use the vendor's own application. Feitian has a simple GUI tool that you can use to enumerate and remove credentials from a FIDO2 key. It is called the FEITIAN SK Manager Tool. Download FEITIAN SK Manager Tool from their website: FEITIAN SK Manager Tool User Manual -- FIDO Security Keys (ftsafe.com) *NB: There does not seem to be any command-line tools for this.* To remove a specific credential, start the FEITIAN SK Manager Tool and insert the FIDO2 key once prompted to do so (you could also have it pre-inserted). Now, click on the "**Applications**" menu item, then "**FIDO2**" and finally "**Enum Credential**" in the main window. After being prompted for the key **PIN**, The tool will show you the FIDO2 credentials found on the key. Now, **tick the box** to the left of the credential you wish to remove and make it so by clicking on the "**Delete**" button. ![Open Image: Remove credentials from a FIDO2 key using Feitian SK Manager Tool](/media/posts/identity/how-to-remove-credentials-from-a-fido2-key/feitian-fido2-delete-credential-2-cf0a60f9eb.gif) That's it! And really, it should not be more complicated than this. ## Final Words Now that your key is nice and tidy, and you feel a sense of joy when holding your credentials in the palm of your hand, I hope you will show some love on social media and subscribe to our newsletter. If you are curious as an IT Pro about FIDO2 keys, then please read my series on FIDO2 keys. --- ## [FSLogix slow sign-in (fix) redux - Black Screen bug](https://iphase.dk/posts/modernwork/fslogix-slow-sign-in-fix-redux) Date: 2021-08-30 Category: modernwork Tags: fslogix, app-readiness, black-screen, slow-login, remote-desktop > UPDATED March 2026 -- This post has been reviewed and updated to reflect current Microsoft product names, portal locations, and technology status. See inline notes for specific changes. FSLogix slow sign-in caused by the App Readiness service can be fixed without workarounds. In this post you will learn what goes on with this service during any Windows login. Debugging FSLogix slow sign-in issues can be a stern reminder of just how many things interact with each other during the Windows login sequence. Most of the time, it might not even be FSLogix that's at fault -- or at least not entirely, which you can read about in this post where we must once again fix the OS and not FSLogix (*Psst* it's all about **App Readiness** this time). If you missed the previous post that this one extends, then do yourself a solid, and check it out in case you are going mad googling through all sorts of solutions: FSLogix slow sign-in (fix) ## The problem Imagine running a large RDSH farm, either on-prem or using Azure Virtual Desktop (formerly Windows Virtual Desktop). Now, imagine that all your users have to wait several minutes the first time and perhaps each subsequent login. And all they have to look at is a black screen with a cursor, no progress indicators; add to that, once the desktop finally renders, the CPU is tied up for several minutes! ![Open Image: Black screen during sign-in](/media/posts/modernwork/fslogix-slow-sign-in-fix-redux/fslogix_slow_sing-in-181f9ae622.png) This black screen during sign-in is NOT the best way to start your users day. This is what I had to deal with recently. And since solutions were nowhere to be found, I decided that sharing the cause and resolution with you good folks reading this blog was my duty to the community. ## The cause The internet is overflowing with issues surrounding this phenomenon in both persistent and non-persistent VDI/RDS environments. It is not even isolated to Windows servers because the culprit is actually the App Readiness Service, which is responsible for initializing the user profile with, among other things, **AppX** packages. **Q:** How do you know it is the App Readiness service? **A:** I used the awesome ProcMon: Process Monitor -- Windows Sysinternals Anyway, the App Readiness service is required for any modern desktop or multi-session host, so please don't just take for granted that you can disable this service, and all your problems disappear (even though it might seem so). ### The App Readiness service As I said, this service is important, and without it, Windows Update will not work properly, your AppX packages will start to vanish, and rot will set into the deepest corners of Windows. ![Open Image: App Readiness Service](/media/posts/modernwork/fslogix-slow-sign-in-fix-redux/image-124-1316349981.png) But this post is not about why you should have the service enabled. It is more of why it might be slowing you down, especially with FSLogix in the mix. You see, the FSLogix container, and others like it, seem to insist on re-enumerating the AppX installations. So, basically, reinstalling them each time a user signs in to their desktop. Normally the process is cached by the AppX Deployment Service. And should only happen once in a while for a regular user profile. So you might dismiss even doing anything about such an intermittent slow sign-in issue. ![Open Image: AppX Deployment Service](/media/posts/modernwork/fslogix-slow-sign-in-fix-redux/image-125-508172eb8a.png) From the learnings in the previous blog post, we know that FSLogix does not do too well if too many things need to be enumerated/evaluated etc., during the sign-in. ### The reason App Readiness is especially hard on FSLogix sign-ins As it turns out, the App Readiness service will actually start the **AppXsvc**, which will then do the work with the AppX packages needed in the user's profile. And this, in turn, kicks the **StateRepository** service into gears, which is where things might start to go really bad. What is this StateRepository service, you say? Well, there is not a whole lot of information about it online. For this blog post, all you need to know is that it's a service that on the backend operates an SQLite database that stores information about all the AppX packages. And it is the same file/database for all users! ![Open Image: State Repository Service](/media/posts/modernwork/fslogix-slow-sign-in-fix-redux/image-126-07369fc586.png) The database file is located in **"%SystemDrive%\ProgramData\Microsoft\Windows\AppRepository"**. If you want to take a look, you can open up an elevated prompt and run the following commands. ```cmd cd %SystemDrive%\ProgramData\Microsoft\Windows\AppRepository dir state* ``` Now imagine that this database grew too large, and the system had to work with that database for each user sign-in. That could, at some point, cause fatigue of system resources. #### The StateRepository database size Now, if you have a single environment, you might not notice that this database had become too large because "what is the normal size anyway?". Let's see about the output from the command I showed you in the previous section... ![Open Image: StateRepository files on Windows 11](/media/posts/modernwork/fslogix-slow-sign-in-fix-redux/image-122-1024x485-cbbe887935.png) The screenshot above is from my Windows 11 computer with a bunch more AppX packages than your average RDS Farms. As you can see, the files are only a few MB in size. I have not been able to find a document that states what the normal size is. So let's see what the size is on a server that is suffering from FSLogix slow logon with a black screen: ![Open Image: StateRepository files on a Remote Desktop Session Host server - bloated](/media/posts/modernwork/fslogix-slow-sign-in-fix-redux/image-123-1024x636-a84e74b177.png) Quite a difference, right? Poor server! Having to process this database file simultaneously for several user logins. Mornings must be hell... **Q:** Why did this happen? **A:** I don't know. **Q:** So, do we dare delete this? **A:** Sure we do! Since the StateRepository service will automatically recreate a new database at startup. We have backups of our servers/workstations (*right?*). ## The script to fix the StateRepository database bloat So, since there is good reason to believe this action has to be done on several servers. I wrote a quick script to delete the StateRepository database (which could be locked by services). You can fetch a copy from my GitHub repository here: invoke-StateRepositoryReset.ps1 (github.com) In short, this script will attempt to stop the associated services and delete all the StateRepository database files. This bit of PowerShell is a straightforward version of the script. You should use the full version from the GitHub repo. ```powershell Get-Service -Name StateRepository | Stop-Service -Force Get-Service -Name AppReadiness | Stop-Service -Force del C:\ProgramData\Microsoft\Windows\AppRepository\StateRepository* Get-Service -Name StateRepository | Start-Service ``` After having completed the database reset, FSLogix slow sign-in should be a thing of the past. That is, unless you are running your farm on a dumpster with spinning disks, then nobody can save you. ## Conclusion StateRepository bloat/corruption is bad for FSLogix, Mmmkay? Please bear in mind that this knowledge is shared for learning purposes only. So, do your own tests etc., before deploying this fix into production environments. Respect each other out there -- we can get through this -- we are meaningless without each other. --- ## [Managed Identities in Azure Automation (PowerShell)](https://iphase.dk/posts/azure/managed-identities-in-azure-automation-powershell) Date: 2021-07-02 Category: azure Tags: azure-automation, managed-identity, powershell, microsoft-graph, security > UPDATED March 2026 -- This post has been reviewed and updated to reflect current Microsoft product names, portal locations, and technology status. See inline notes for specific changes. If you love Azure Automation and Security, you probably know that since around April 2021, Managed Identities in Azure Automation is the best way to access resources securely. This article will show why and how you should use Managed Identities to simplify your resource access management. And end it with showing how I have made my Graph API-related Runbooks much leaner. The expected audience for this article is IT Pros with general experience managing access to Microsoft Entra ID roles and Azure Resources. UPDATE: Here is an example of how to connect to an Exchange Online PSSession: ExchangeOnlineScripts/ConnectEXOwithMSIRunbookExample.ps1 at main (github.com) > NOTE (Updated 2026): The Azure Automation RunAs account was retired on September 30, 2023. If you are still using RunAs accounts, migration to Managed Identities is required. This post covers Managed Identities, which is the correct modern approach. ## What are managed identities? Managed Identities are accounts in your Microsoft Entra ID that are only available for use by the resources that you have assigned them to. This could be an Azure automation account or some other service like Azure Functions or Azure VM. But it is not a given that they are supported in every type of Azure Resource. ### Managed Identities come in two flavors - **System assigned** - tied to the lifecycle of a single resource (i.e., an Azure Automation account) much like a classic Active Directory managed service account (MSA) - **User assigned** - can be thought of as a classic group managed service account (gMSA), that is available to multiple resources NB: In this article we only deal with System assigned as I feel that is easiest to manage when thinking about the lifecycle management of our solutions in Azure. ### How are they more secure? Managed Identities are more secure because their "credentials" are only available to the resource they are assigned to, and they are never exposed in code. Unlike other account types that rely on an administrator to handle the credentials at some point, Managed Identities credentials are at no point handled by the systems administrator or anyone else. It is all handled by Azure, like a boss! > They are never exposed in code Not having to deal with any form of credential (i.e., certificates or secrets) greatly enhances the security posture of the solutions you develop. And having to monitor for expired client secrets or certificates for app registrations is a thing of the past. ## How do I get started with using Managed Identities in Azure Automation? To get started with Managed Identities you first need an Azure Automation account. And I suggest you start with a fresh Azure Automation account in a new Resource Group that will hold your automation solution. NB: When you create your new Azure Automation Account, a default option is to create a RunAs account. I would like you to consider not using that option during creation. It is not wise to enable RunAs accounts unless you will be using them. ## Actually using the managed identity for something cool! First off, it is extremely easy to use a managed identity within your Runbook, once it is supported by the PowerShell modules that you use. Currently Az.Accounts is the only one that I have been using. Using managed identities with the connect-azaccount cmdlet is very easy. Simply add this line to your runbook: ```powershell Connect-AzAccount -Identity ``` Yes. It is that easy! You just connected to Azure using a managed identity. ### Accessing Microsoft Graph API with a managed identity There are many ways to work with Microsoft Graph API. I prefer the PowerShell SDK when working with the Microsoft Graph API in a Runbook since it will make it much leaner and less prone to errors than invoking web requests. Still, support for managed identity is missing at the time of writing this. The PowerShell module does, however, support the use of an access token. So we can simply call on the system assigned managed identity, to generate an access token that is valid for the Microsoft Graph API endpoint. Take a look at this code: ```powershell #Obtain AccessToken for Microsoft Graph via the managed identity $resourceURL = "https://graph.microsoft.com/" $response = [System.Text.Encoding]::Default.GetString((Invoke-WebRequest -UseBasicParsing -Uri "$($env:IDENTITY_ENDPOINT)?resource=$resourceURL" -Method 'GET' -Headers @{'X-IDENTITY-HEADER' = "$env:IDENTITY_HEADER"; 'Metadata' = 'True'}).RawContentStream.ToArray()) | ConvertFrom-Json $accessToken = $response.access_token #Define the desired graph endpoint $graphApiVersion = 'beta' Select-MgProfile -Name $graphApiVersion #Connect to the Microsoft Graph using the acquired AccessToken Connect-Graph -AccessToken $accessToken ``` #### Micro deep dive First, we define the API URL that we know the Microsoft Graph API PowerShell SDK uses in the background. Second, we build the Uri for our invoke-webrequest. Nothing special here, except the fact that we are using two very magic environment variables: - `$env:IDENTITY_ENDPOINT` - `$env:IDENTITY_HEADER` These two variables are only accessible by the automation account and only valid when processing the runbook. It's sort of like a little private webserver within your runbook that you can send a request to. In this case, we are sending a web request that is asking the managed identity service to go to the requested resource URL and get us an access token. Lastly, we use the Microsoft.Graph PowerShell modules cmdlets to define the Profile we want to connect to, and then initiate the connection with our newly acquired access token. The end result is a successful connection to the Microsoft Graph! ## Assigning permissions to the Managed Identity Assigning permissions to a managed identity is much like with any other service principal (but..). You can add the managed identity to a role in Entra ID and Azure that gives it the required access to the resources you need to access from Azure Automation. You are however going to have to use PowerShell in order to assign app permissions to things like Exchange Online or Microsoft Graph. And I have created a script to be executed in the comfort of your own Azure Cloud Shell: PSBucket/Add-MGraphMSIPermissions.ps1 at master (github.com) ![Open Image: Service principal permissions in Entra ID](/media/posts/azure/managed-identities-in-azure-automation-powershell/service-principal-1024x473-60bd472f36.jpg) Needless to say, you should assign the least required privilege. ![Open Image: Azure managed identity configuration](/media/posts/azure/managed-identities-in-azure-automation-powershell/azure-managed-identity-1024x306-975f58d32a.jpg) ## Conclusion Using managed identities to access Azure resources is easy and reliable. You should prioritize assessing if they can be used in your solutions from now and going forward. Since client secrets for app registrations are now limited to a maximum of 24 months expiration count, the risk of a service outage due to bad monitoring grows even bigger. I hope this article helped you to understand that there is more to managed identities than meets the eye. --- ## [FSLogix slow sign-in (fix)](https://iphase.dk/posts/modernwork/fslogix-slow-sign-in-fix) Date: 2021-06-17 Category: modernwork Tags: fslogix, vdi, remote-desktop, slow-login, registry > UPDATED March 2026 -- This post has been reviewed and updated to reflect current Microsoft product names, portal locations, and technology status. See inline notes for specific changes. In this short blog post I will explain a solution for fixing an FSLogix slow sign-in process. A while back, I was having serious issues implementing a conversion from User Profile Disk (UPD) to FSLogix Profile Containers on a Windows Server 2016 Remote Desktop Session host Collection. The FSLogix user sign-in process was not just a few seconds but several minutes prolonged! > NOTE (Updated 2026): Windows Server 2016 reached end of mainstream support in January 2022 and end of extended support on January 12, 2027. If you are still running FSLogix on Windows Server 2016, plan your migration to Windows Server 2022 or 2025. FSLogix is fully supported on current Windows Server versions. ![Open Image: Waiting forever for something to load](/media/posts/modernwork/fslogix-slow-sign-in-fix/slow-sign-in-4cafd2e87a.gif) ## TL;DR; Long story short. I spent more time on this than I care to admit. In the end, all I had to do, was delete the notifications registry key. You can find the script I made, at the end of the article. ## Debugging FSLogix slow sign-in I was obviously double-checking the configuration and returning to a fundamental configuration with only the essential defaults set. But the issue remained. The FSLogix log files indicated that it was doing absolutely nothing after the "Prep1" step. And then, after a long wait, it completes "Prep2" in a second!? What the heck is going on, I thought? I whipped out my good old friend the Process Monitor from Sysinternals but could not really see anything stealing resources or delaying the login process (I had obviously excluded the FSLogix process and containers from the Antivirus software). I decided it was time for some sparring and called up my colleague Morten Pedholt who has extensive knowledge of FSLogix from countless Azure Virtual Desktop implementations. Together we confirmed that every bit of the configuration was correct. So now we were stuck and started to try everything we could think of. - Checking the VM performance. - Trying every crazy combination of settings. - Unlinking all GPOs. - Testing on every single different session host in the collection. - **Using the FSLogix Support tool** - Trying out even the most obscure suggestions from Reddit and the tech community. ### The reason why sharing your experiences online is important! Lo and behold! We found the culprit after reading a few places about some minor login delays caused by the notifications area part of the registry. I initially dismissed this information because the delays I was experiencing were not minor but rather extreme. Nevertheless, we tested the solution on a Session Host and found that just opening the registry area of the notifications in Windows took us 6 minutes! About the same amount of time it took to sign in! This was no coincidence! And there is even an old support article from Microsoft about it which applies to an older Operating System, but it is the same problem. The registry key for the notifications is: **HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Notifications** To give you an idea of just how horrific an experience this was, I recorded this video in real-time (It's the same experience for the FSLogix slow sign-in): ![Open Video: Notification areas registry key was bloated on this system!](/media/posts/modernwork/fslogix-slow-sign-in-fix/FSLogix_notifications_slow_login-b8e27ac5be.mp4) ### Shutdown script to the rescue Naturally, I deleted the useless notifications key and recreated an empty one. And Once I had done that, I rebooted the Session Host. To ensure this never happens again, I created a Group Policy containing a shutdown script so that the notifications registry key would get cleared on every reboot of the Session Hosts. #### The script that fixes FSLogix slow sign-in ```powershell Remove-Item "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Notifications" -Recurse New-Item "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Notifications" ``` ## Conclusion Upgrading to FSLogix profile containers on a set of well used Session Hosts can be more trouble than it is worth. But in this case it was unavoidable. Planning for road bumps like this is key to making your deadlines. --- ## [Securing SCEP/NDES for Intune with gMSA](https://iphase.dk/posts/intune/securing-scep-ndes-for-intune-with-gmsa) Date: 2021-05-12 Category: intune Tags: scep, ndes, gmsa, certificates, intune, security > UPDATED March 2026 -- This post has been reviewed and updated to reflect current Microsoft product names, portal locations, and technology status. See inline notes for specific changes. Swap out your regular service account with an awesome secure group managed service account! In this blog post on "Securing SCEP/NDES for Intune with gMSA," you can learn how to tighten security if you have NDES and SCEP configured for your Intune clients using a regular AD User Account as your NDES Service account. The NDES service account has the permissions to act as a registration authority. The NDES service can enroll client identity certificates for any user in the organization. And you should regard this account as a high-value target for any attackers that might gain a foothold inside your perimeter. This is why I highly recommend that you make it very tough to compromise and abuse this account due to any human error like storing the password in an unsecure location. ## gMSA basics If you are unfamiliar with the term gMSA; It stands for Group Managed Service Accounts and is a feature that allows you to avoid having to manage the password and lifecycle of your service accounts. A gMSA acts much like a computer account. And is tied to specified servers and is not useable by just any server on your network. The rest of this blog post will be expecting you to have *already set up a gMSA account on the NDES server* and tested that it works using PowerShell. Please notice; that this guide has been tested to work on Windows Server 2019 with a GUI installed. ## Replacing the regular NDES service account with a gMSA Log into the remote desktop of your NDES server to begin securing SCEP/NDES for Intune with gMSA. To replace the original NDES service account, we first need to take care that the new gMSA account can read the certificates Private keys and has the correct account permissions. NB: **Do NOT** remove the existing service account from the ACLs. When everything works as expected, you can go ahead and delete the old service account instead of removing it from all the ACLs. ### NDES Private keys permissions - Start the program **"certlm.msc"** from "run." - Navigate to "Personal" -> "Certificates" and find the NDES Client certificate. - Right-click on the certificate and chose "All tasks" -> "Manage Private Keys..." - Add the gMSA account to the Access Control List (ACL). - Pay attention to the fact that you should add a $ sign at the end of the account name. - Make sure to adjust the search scope to include Managed Service Accounts. ![Open Image: Manage certificate private keys](/media/posts/intune/securing-scep-ndes-for-intune-with-gmsa/image-18-df5851c2e4.png) Click the "Add..." button to find and add the gMSA account. ![Open Image: Set private key permissions for gMSA](/media/posts/intune/securing-scep-ndes-for-intune-with-gmsa/NDES_client_certificate_gmsa-1adc8920a3.png) Now, continue adding the gMSA account and permissions to the rest of the certificates private keys that relate to NDES: ![Open Image: Exchange Enrolment Agent certificate Private Keys](/media/posts/intune/securing-scep-ndes-for-intune-with-gmsa/image-19-1024x709-4f7c0876ed.png) ![Open Image: CEP Encryption certificate Private Keys](/media/posts/intune/securing-scep-ndes-for-intune-with-gmsa/image-20-1024x746-9189cc9d8d.png) ### gMSA account permission on the NDES server The new gMSA account will need permissions to logon locally, as a batch job, and as a service. - Start the program **"gpedit.msc"** from "run" on the NDES server. - Navigate to "Computer Configuration" -> "Windows Settings" -> "Security Settings" -> "Local Policies" -> "User Rights Assignment." ![Open Image: Allow log on locally for gMSA](/media/posts/intune/securing-scep-ndes-for-intune-with-gmsa/image-21-19d4780dc3.png) ![Open Image: Log on as a batch job for gMSA](/media/posts/intune/securing-scep-ndes-for-intune-with-gmsa/image-22-99dbf6ac56.png) ![Open Image: Log on as a service for gMSA](/media/posts/intune/securing-scep-ndes-for-intune-with-gmsa/image-23-eb6d2b1023.png) ### SCEP Application pool identity As you might remember from having configured NDES, the SCEP service runs on IIS, so we need to replace the service account for the application pool identity. **Notice:** *Do not attempt to recycle the pool or restart it before you have done the last steps.* You MUST enter the gMSA account with the domain's NetBIOS name prefixed. **Example: DOMAIN\gmsa_ndes$** Please pay attention to the fact that the password box gets greyed out as soon as you enter the $ after the account name, this is how gMSA works, and you know that it is supported. ![Open Image: Adding gMSA to IIS Application Pool identity](/media/posts/intune/securing-scep-ndes-for-intune-with-gmsa/image-24-1024x618-842aa20491.png) ### Configuring certificate template permissions for gMSA The last step is to ensure that your gMSA account can actually request certificates from the Certificate Authority. - Right-click on "Certificate Templates" and click on "Manage" ![Open Image: Manage Certificate Templates on the CA](/media/posts/intune/securing-scep-ndes-for-intune-with-gmsa/image-25-9d013ab491.png) Add the gMSA to the ACL and make sure that it gets the "Enroll" permission. ![Open Image: Certificate Template ACL with gMSA Enroll permission](/media/posts/intune/securing-scep-ndes-for-intune-with-gmsa/image-26-1024x907-b333fd8df8.png) Now, go back to the **NDES server, and reboot it,** to make sure everything gets started properly. ## Troubleshooting and notes ### Intune Connector account There is an advanced option to add a specific service account during the installation of the Intune connector. The UI for configuring this account unfortunately does not support gMSA. You can find the UI for changing this setting in the folder "C:\Program Files\Microsoft Intune\NDESConnectorUI\NDESConnectorUI.exe" on the NDES server. ![Open Image: Intune NDES Connector UI configuration](/media/posts/intune/securing-scep-ndes-for-intune-with-gmsa/image-27-1024x752-31c021e3e1.png) ### Windows Server 2012 specific There is a known issue with doing this on Windows Server 2012. On another note: *do not use Windows Server 2012 for anything that is public-facing!* ### HTTP Error 403.0 - Forbidden (0x8000ffff) Hey! This error is OK. And indicates that things are actually working with the Intune Connector. ![Open Image: HTTP Error 403.0 - Expected behavior with Intune Connector](/media/posts/intune/securing-scep-ndes-for-intune-with-gmsa/image-28-1024x508-38cad31cbd.png) ## Conclusion You have now completed securing SCEP/NDES for Intune with gMSA and can be proud you did something good for the security of your systems! --- ## [Migrate BitLocker to Microsoft Entra ID](https://iphase.dk/posts/intune/migrate-bitlocker-to-azure-ad) Date: 2021-01-12 Category: intune Tags: bitlocker, azure-ad, mbam, escrow, powershell, migration How can you migrate BitLocker to Microsoft Entra ID without needing to re-encrypt or add new recovery keys to your managed devices? This article will illustrate one way to escrow (backup) the existing recovery key, using nothing but a **Microsoft Intune PowerShell script**. > UPDATED March 2026 -- This post has been reviewed and updated to reflect current Microsoft product names, portal locations, and technology status. See inline notes for specific changes. ## The death of MBAM and AD Escrowed credentials The Microsoft BitLocker Administration and Monitoring tools have gone out of mainstream support. And any cloud-first forward-thinking company will likely be looking to escrow the existing and future recovery keys for BitLocker to Microsoft Entra ID / Microsoft Intune. If you have a solid hybrid cloud strategy, Microsoft Configuration Manager is a great choice for BitLocker management. And if that is your scenario, I suggest you read this series: Goodbye MBAM -- BitLocker Management in Configuration Manager. NB: MBAM features have all been ported to Microsoft Configuration Manager. And are fully supported going forward. ## Configuring Intune to enforce and escrow BitLocker to Microsoft Entra ID This part is well documented by Microsoft on the docs page: Encrypt Windows 10 devices with BitLocker in Intune. However, you should be aware that you can actually deploy your Intune managed BitLocker policy on top of your existing GPO policy, as long as you have not configured the MDMWinsOverGP CSP. This way, you will ensure that you have all keys escrowed into Microsoft Entra ID before dismantling your MBAM solution. ### The script that will help you migrate BitLocker to Microsoft Entra ID Now, a policy alone will not migrate existing device recovery keys escrowed in MBAM or AD to Microsoft Entra ID. You will need to take care of those devices with a PowerShell script. Needless to say, the devices must be enrolled into Microsoft Intune for this to work. Please download Invoke-EscrowBitlockerToAAD.ps1 from my PowerShell bucket on GitHub before continuing. > NOTE (Updated 2026): The script filename `Invoke-EscrowBitlockerToAAD.ps1` retains "AAD" in its name for backward compatibility and GitHub URL continuity. The functionality targets Microsoft Entra ID (formerly Azure AD) for BitLocker key escrow. The exact scenario that I had to cover when building the script was: - MBAM with GPO deployed to all devices on-prem. - Devices Microsoft Entra hybrid joined and enrolled. - BitLocker policy deployed from Intune that matches the on-prem GPO Policy. ### Script deployment via Intune From the Microsoft Intune admin center, complete the following steps: ![Open Image: Deploy the script to migrate Bitlocker to Azure AD via MEM](/media/posts/intune/migrate-bitlocker-to-azure-ad/image-1-1024x528-762f2f0faa.png) 1. Click the "**Devices**" button. 2. Then the "**Windows**" platform button. 3. Click the "**PowerShell scripts**" button. 4. And finally, click the "**Add**" button. #### Script Basics ![Open Image: Describing the PowerShell script in Intune](/media/posts/intune/migrate-bitlocker-to-azure-ad/image-2-1024x503-ec96f73a58.png) 1. Type a fitting "**Name**" to be shown in the script overview. 2. Type a fitting "**Description**" that clearly indicates the script's purpose. #### Script settings ![Open Image: PowerShell script settings in Intune](/media/posts/intune/migrate-bitlocker-to-azure-ad/image-3-1024x484-03e42f76d8.png) 1. Click the "**Blue folder icon**" to select the escrow Bitlocker script file to be deployed. Please pay attention to leave the **script settings at their defaults**. #### Script Assignments ![Open Image: Selecting PowerShell script assignments in Intune](/media/posts/intune/migrate-bitlocker-to-azure-ad/image-4-1024x400-0f64ead7e1.png) 1. Click the "**Select groups to include**" link. 2. "**Search**" for the **Security Group** that includes the **devices** you wish to target. 3. Select your security group in the results. 4. Then click the "**Select**" button. 5. Click the "**Next**" button to continue. #### Script deployment Review + add ![Open Image: Review and add the PowerShell script deployment](/media/posts/intune/migrate-bitlocker-to-azure-ad/image-5-1024x873-a6794b64bc.png) Make sure that all the Basics, Script settings, and Assignments are correct. Then click the "**Add**" button to complete the deployment. You have now completed all the steps! ## Conclusion Migrating BitLocker to Microsoft Entra ID, using Intune to escrow the existing Keyprotectors with a PowerShell script is possible. And I am very keen on hearing what other ways the community has come up with! --- ## [The Windows Hello Zone! - Part 2](https://iphase.dk/posts/identity/the-windows-hello-zone-part-2) Date: 2020-12-16 Category: identity Tags: windows-hello-for-business, passwordless, pin-login, endpoint-security, zero-trust > UPDATED March 2026 -- This post has been reviewed and updated to reflect current Microsoft product names, portal locations, and technology status. See inline notes for specific changes. > NOTE (Updated 2026): Windows 10 reaches end of support on October 14, 2025. Organizations should plan migration to Windows 11. The Windows Hello for Business PIN and biometric capabilities described in this post are fully supported and enhanced in Windows 11. Windows Hello for Business? You need to understand why this should be a part of your IT Security arsenal. Read Part 2 for more terrifying stories from the Windows Hello Zone! Enabling Windows Hello for Business... Why? Why Not? Excuses are a dime a dozen, but after reading this second story, you can decide for or against it -- but mind you; these stories might never have seen the day of light had the companies only been using Windows Hello for Business to deter the Antagonist... Welcome to "The Windows Hello Zone!" -- Part 2. If you missed out on Part 1, click here to read it! ![Open Image: Hello at the Hardware Store](/media/posts/identity/the-windows-hello-zone-part-2/hello_jimmy-dbe4f7af8e.png) ## Ask Jimmy! We all go to the hardware store once in a while. So did Isabella one day, when the water heater in her house broke... At the local Mega Hardware store, Isabella started chatting with a sales rep about getting a good deal on a new water heater. But it was a little too rich for her blood. So she asked the sales rep to print out a quote for her to think over at home. Isabella had been talking for so long with the sales rep that the computer he was standing at was locked due to inactivity. It turns out the sales rep was new and struggling to remember the credentials to unlock the station. So, he starts yelling over to a colleague about the credentials, and the colleague yells back, "Ask Jimmy!". It turns out that Jimmy is the manager of the store, and the sales rep calls Jimmy up on the store intercom. Jimmy is on the other end of the intercom now. Isabella can hear everything he is saying to the rep; "...yeah, so we had to change the password to a longer one due to company policy! IT nerds are getting on my nerves about this security bulls**t..." Jimmy goes on to spell out the new password, which is quite complex! ### Hard times tempt even the kindest soul Back home, Isabella is sitting with the quote in hand and notices the account name used to print it out happens to be on it. Poor Isabella is tempted to try the password that she clearly remembers since she is sort of a genius. She easily guesses the webmail address of the hardware store and tries the credentials... She is in! Isabella spends some time with the mailbox and learns that all the sales reps use the same account for all their communication. And how sales are processed and marked as paid and ready for pickup! The next day Isabella makes sure to avoid the sales rep she previously spoke to and picks up her brand new and free water heater! Isabella now visits the store regularly... ### Morals smorals... - If the Hardware store that insists on sharing credentials between employees had only used Windows Hello for Business with a PIN for shared access, then "poor" Isabella would not have had so much success with her grift. ## PINs and needles We previously touched base with the PIN code, a minimum requirement for enabling Windows Hello for Business. And there are a lot of questions that immediately come to mind when you first hear the sentence "Now you can simply sign-in to your device with a PIN code -- it's so much better!": - "How can a 6 digit PIN code possibly be safer!?" - "This person must be out of their mind to suggest such nonsense!" - "I am going to poke needles through my ear-drums and pretend I did not just hear this insanity." YES! That does sound insane, but there is more to the story! ![Open Image: Windows Hello for Business PIN is the way](/media/posts/identity/the-windows-hello-zone-part-2/Windows_hello_for_business_pin_is_the_way-5a6dcc745c.png) ### Windows Hello for Business PIN security A Windows Hello for Business PIN has some hard to ignore advantages over just being a PIN code of 6 or more digits. 1. The PIN will ONLY work on the device it was enrolled onto by using Multi-Factor verification of the enrolled user account. - Meaning that even if you gave it to someone online by mistake, it would be useless. 2. The PIN is shareable without giving away your actual password. - Not something I would condone doing, but it would have worked well at the Mega Hardware store. 3. The PIN can be enrolled by IT, thus keeping the actual account password completely out of the user's reach. - Effectively locking them into the specified device, making them practically Phishing proof. - A great strategy for dealing with those users who are not IT literate and need to do simple tasks on their devices. 4. The PIN can even include letters! - But be careful to enable this -- you don't want to risk users just typing in their password as a "PIN." For more details on why a PIN is better than a password, check out [this article from Microsoft](https://learn.microsoft.com/en-us/windows/security/identity-protection/hello-for-business/hello-why-pin-is-better-than-password) and this great explainer video: ![Open Video: Why is the PIN for Windows Hello more secure than a password? | One Dev Question](https://www.youtube.com/embed/cC24rPBvdhA) ## Conclusion By now, you should be aware of the game changing advantage that Windows Hello for Business gives you over a regular set of credentials. The only thing you should fear is missing out on the awesomeness of going passwordless with Windows Hello for Business. Windows Hello for Business is here to stay, and anyone serious about their Windows 10 endpoints' security needs to get practical experience with this technology NOW -- not later -- NOW. --- ## [The Windows Hello Zone! - Part 1](https://iphase.dk/posts/identity/the-windows-hello-zone-part-1) Date: 2020-11-18 Category: identity Tags: windows-hello-for-business, biometric-login, passwordless, hybrid-key-trust, endpoint-security > UPDATED March 2026 -- This post has been reviewed and updated to reflect current Microsoft product names, portal locations, and technology status. See inline notes for specific changes. Enabling Windows Hello for Business... Why? Why Not? - If it ain't broken, don't fix it? - If the glove doesn't fit, why debate it any further? - We couldn't possibly attract any malicious interest? - We know all our employees! Excuses are a dime a dozen, but after reading the two stories contained in this multi-part "semi-tech" article, you can decide for or against -- but mind you; these stories might never have seen the day of light had the companies only been using Windows Hello for Business to deter the Antagonist... Welcome to "The Windows Hello Zone!" The second part of this article can be found here: The Windows Hello Zone! -- Part 2 ![Open Image: Coworker being inappropriate with shoulder touch - Hello at work](/media/posts/identity/the-windows-hello-zone-part-1/hello_boss-f59cfbba90.png) ## The story of Kim and the new Boss Kim has a good job... But Kim hates the new Boss... Kim makes an effort to learn the Boss' password. Kim uses a shoulder surfing technique, as the glass partitions in the office make it easy to gander over the new Boss' shoulder during sign-in in the mornings. The Boss is oblivious to this... Once the password had been gathered, Kim starts plotting... Kim can now login as the Boss from any company laptop! The possibilities for mayhem are many... Kim comes in late one night as anonymously as possible and starts logging into several co-workers' computers -- with the new Boss' credentials! And starts downloading sensitive materials and designs for the companies new products... Later that week, leaked information from the company finds its way to the news, and the company is in a panic, starting a full investigation into who could have leaked the data!? Audit log trails quickly lead to the new Boss and the seemingly feeble attempt to hide their tracks by downloading the data from the co-workers' computers... Kim still has a good job... Kim is getting a new Boss soon -- let's hope it's a nice Boss... ### Morals smorals... - If only Kim's new Boss had been using Windows Hello for Business with a Biometric login, Kim would have gotten nowhere with the shoulder surfing. At least IT was auditing file access, so they did not have to waste time placing blame! Let's quickly go over some of the tech in Windows Hello for Business: ## Biometrics and Windows Hello for Business Using Biometrics to access Windows is natively built into Windows 10, thanks to Windows Hello for Business. Biometrics are also known as "passwordless" credentials. Passwordless credentials are far superior to typing a password as you sign-in. The most common methods are using either of these mechanisms: - Fingerprint reader - Facial recognition ![Open Image: Fingerprint sign-in setup with Windows Hello](/media/posts/identity/the-windows-hello-zone-part-1/setup-hello-50eb07cb48.png) Most laptops for Enterprises come with either a fingerprint or an IR Camera for facial recognition nowadays, so getting started with Biometrics might be something you can do today! If not, check out Part 2 that covers the use of a PIN code and scenarios for that. But just know that the PIN is always a minimum requirement, even if you are using Biometrics! ### No more roaming around the office with your credentials Windows Hello for Business uses the physical TPM security chip on your device -- which means that it has a hard dependency on that chip, allowing you access to the certificate that Windows Hello for Business has issued to the device and synced with Entra ID. This is by design, and why Kim would have failed if somehow the new Boss' PIN was exposed to Kim during a failed Biometric sign-in. Pay special notice to the fact that the credential certificate is synced to Azure AD. This effectively means there's a delay in a hybrid environment before you can actually use Windows Hello for Business to authenticate. The delay happens because Azure AD Connect takes care of that process by syncing the user's certificate attribute to Azure AD for the trust to be established -- This is called a Key Trust model. The sync happens after the user has enrolled into Windows Hello for Business on a device. There is a really great planning guide from Microsoft that I suggest you fill out, so you know what needs to be done in your organization. **Some quick takeaways for Windows Hello for Business in common Hybrid environments:** - Domain and forest level should be 2012 R2 as a minimum. - Install a single Windows Server 2016 Domain Controller, and assign the PDC FSMO role so the schema can support the required attributes for the certificate. - Remember to re-run Azure AD Connect and refresh the schema after the 2016 DC Role has been installed. ### But I want to roam freely! Then you could opt-in for Biometrics via FIDO2 keys, which have previously been known as "Windows Hello Keys". Notice that these keys are not dependent on whether Windows Hello for Business is enabled or not. They do however let you roam your secured identity between devices. As the key will take the place of the physical TPM chip in your laptop. We have a whole article series on getting started with FIDO2 keys and going Passwordless. Going passwordless is the future. And it can be yours now! > Read another terrifying story of abused credentials in Part two! #### And now for a limerick... > There once was a man from Nantucket > Who left his password in a bitbucket. > But a hacker named Nan, > was tracking the man > And as for the password, Nantucket > NOTE (Updated 2026): Windows 10 reaches end of support on October 14, 2025. Organizations should plan migration to Windows 11 for continued support and access to the latest Windows Hello for Business features, including improved Cloud Kerberos Trust support and expanded passkey capabilities. --- ## [Enable Microsoft Enterprise SSO plug-in for Apple Devices through Intune](https://iphase.dk/posts/identity/enable-microsoft-enterprise-sso-plug-in-for-apple-devices-through-intune) Date: 2020-10-14 Category: identity Tags: authenticator, sso, intune, apple, ios, macos > UPDATED March 2026 -- This post has been reviewed and updated to reflect current Microsoft product names, portal locations, and technology status. See inline notes for specific changes. ## Overview ![Open Image: Apple Microsoft Single Sign-On](/media/posts/identity/enable-microsoft-enterprise-sso-plug-in-for-apple-devices-through-intune/apple_microsoft_single_sign-on-1200x500-0f944d1f45.png) Microsoft Enterprise Single Sign-On has been limited on Apple iOS/macOS devices until now. The new SSO plug-in for the Microsoft Authenticator App changes everything. The Microsoft Enterprise SSO plug-in for Apple devices provides single sign-on (SSO) for Microsoft Entra ID accounts across all applications that support Apple's Enterprise Single Sign-On feature. > NOTE (Updated 2026): macOS support for the Microsoft Enterprise SSO plug-in is now generally available (no longer in preview). Use the same extension configuration for both iOS/iPadOS and macOS devices. For macOS, use Extension ID `com.microsoft.CompanyPortalMac.ssoextension` with Team ID `UBF8T346G9`. **UPDATE:** If your Teams client starts acting strange, try removing your device from being targeted by this policy and reboot the phone. ## Requirements - iOS 16 minimum OS version - Latest version of Microsoft Authenticator with your identity configured - Device enrolled with Intune or another MDM - SSO feature enabled through a device feature policy ## How to enable the SSO extension ### Step 1: Creating a device feature profile Navigate to the Microsoft Intune admin center at https://intune.microsoft.com. ![Open Image: iOS device list in Microsoft Intune](/media/posts/identity/enable-microsoft-enterprise-sso-plug-in-for-apple-devices-through-intune/image-36-21507666a6.png) 1. Click **Devices** > **iOS/iPadOS** 2. Click **Configuration profiles** > **+ Create profile** 3. Select Platform **iOS/iPadOS** and Profile **Device features** ![Open Image: Creating a device features profile](/media/posts/identity/enable-microsoft-enterprise-sso-plug-in-for-apple-devices-through-intune/image-35-1024x451-07757d0eef.png) ![Open Image: Device features profile configuration](/media/posts/identity/enable-microsoft-enterprise-sso-plug-in-for-apple-devices-through-intune/image-31-1024x719-e267b8119d.png) ### Step 2: Configuring the SSO App extension feature Configure the **Single sign-on app extension** (not "Single Sign On"): 1. Select SSO app extension type: **Redirect** 2. Extension ID: **com.microsoft.azureauthenticator.ssoextension** 3. Add the following URLs: - https://login.microsoftonline.com - https://login.microsoft.com - https://sts.windows.net - https://login.partner.microsoftonline.cn - https://login.chinacloudapi.cn - https://login.microsoftonline.de - https://login.microsoftonline.us - https://login.usgovcloudapi.net - https://login-us.microsoftonline.com 4. Additional configuration keys: - **browser_sso_interaction_enabled** - Type: Integer, Value: **1** - **disable_explicit_app_prompt** - Type: Integer, Value: **1** ![Open Image: SSO app extension configuration in Intune](/media/posts/identity/enable-microsoft-enterprise-sso-plug-in-for-apple-devices-through-intune/image-32-749x1024-4b8d4bd406.png) ### Step 3: Assign the policy ![Open Image: Assigning profile to groups](/media/posts/identity/enable-microsoft-enterprise-sso-plug-in-for-apple-devices-through-intune/image-33-1024x549-6cbab3442b.png) ![Open Image: Review profile settings](/media/posts/identity/enable-microsoft-enterprise-sso-plug-in-for-apple-devices-through-intune/image-34-1024x655-db09d08ef5.png) ## Testing the Single Sign-On experience Test using the [Microsoft 365 portal](https://portal.office.com) in Safari for iOS. Clear cached credentials first using Apple's guide. ![Open Image: SSO login experience on Apple iOS](/media/posts/identity/enable-microsoft-enterprise-sso-plug-in-for-apple-devices-through-intune/apple_microsoft_single_sign-on-2-480x1024-7fe19b9da2.png) ## Read more - [Microsoft Docs: Apple SSO Plugin](https://docs.microsoft.com/en-us/azure/active-directory/develop/apple-sso-plugin) - [iOS device feature settings](https://docs.microsoft.com/en-us/mem/intune/configuration/ios-device-features-settings#single-sign-on-app-extension) - [macOS device feature settings](https://docs.microsoft.com/en-us/mem/intune/configuration/macos-device-features-settings#single-sign-on-app-extension) For macOS, use Extension ID **com.microsoft.CompanyPortalMac.ssoextension** with Team ID **UBF8T346G9**. --- ## [Keeping Always On VPN - always on?](https://iphase.dk/posts/intune/keeping-always-on-vpn-always-on) Date: 2020-04-29 Category: intune Tags: always-on-vpn, connectivity, vpn, intune > UPDATED March 2026 -- This post has been reviewed and updated to reflect current Microsoft product names, portal locations, and technology status. See inline notes for specific changes. ## The Problem ![Open Image: Always On VPN](/media/posts/intune/keeping-always-on-vpn-always-on/AlwaysOn-VPN-700x500-8ad32ff84d.jpg) The Microsoft Always On VPN Solution pushed by Microsoft as the successor to DirectAccess is a great tool for remote workers. Despite the name, user tunnel connections don't always auto-connect, even with "AlwaysOn" configured in the ProfileXML or Intune configuration policy. Some hacks include scheduling the "rasdial" command, but wouldn't you rather know why it stopped auto-connecting? ## Why is it not auto connecting? This might happen because the user manually disconnected the user tunnel, or for unexplained reasons. What happens is the VPN connection gets added to a registry list called **AutoTriggerDisabledProfileList**. ![Open Image: Registry location of AutoTriggerDisabledProfileList](/media/posts/intune/keeping-always-on-vpn-always-on/rasman-Registry-Editor-1024x434-bfce8fa252.png) The **AutoTriggerDisabledProfileList** property is located at: ``` HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\RasMan\Config ``` This is a **REG_MULTI_SZ** property that maintains profiles in a disconnected state, surviving reboots. ## Can Intune help me fix this? You could use PowerShell to remove unwanted entries, or create a .intunewin package with a detection rule. For the detection method: ```powershell $connectionName = "Always On VPN Connection Name" if((Get-ItemProperty -Path HKLM:\SYSTEM\CurrentControlSet\Services\RasMan\Config | select AutoTriggerDisabledProfilesList -ExpandProperty AutoTriggerDisabledProfilesList) -icontains $connectionName){ Write-Host "Found connection: $connectionName in disabled profile list!" exit 1 } ``` ### Can I disable the user's ability to disconnect? Microsoft has a device CSP you can deploy with a custom OMA-URI: ``` ./Device/Vendor/MSFT/VPNv2/{ProfileName}/DisableDisconnectButton ``` > NOTE (Updated 2026): OMA-URI custom profiles remain supported but Microsoft recommends using the Settings Catalog for VPN configuration where possible, as it provides a GUI-based interface and better change tracking. The OMA-URI values below remain valid for settings not yet available in the Settings Catalog. Remember to include %20 for spaces in your VPN profile name. Read more about this CSP at: [VPNv2 CSP Documentation](https://learn.microsoft.com/en-us/windows/client-management/mdm/vpnv2-csp#deviceprofilenamedisabledisconnectbutton) ## Final thoughts Adding a fix via Intune complements the fact that Intune is the preferred distribution mechanism for Always On VPN profiles. Even though this seems like a bug, it's a feature, and as such it might never end up on the troubleshooting page. --- ## [Managing Microsoft Teams Firewall requirements with Intune](https://iphase.dk/posts/intune/managing-microsoft-teams-firewall-requirements-with-intune) Date: 2020-03-29 Category: intune Tags: intune, teams, powershell, firewall > UPDATED March 2026 -- This post has been reviewed and updated to reflect current Microsoft product names, portal locations, and technology status. See inline notes for specific changes. > NOTE (Updated 2026): Microsoft has completed the transition from Classic Teams to New Teams (Teams 2.0) across all platforms. New Teams uses different executable paths and may have different firewall requirements than Classic Teams. The firewall rules and script in this post were written for Classic Teams. Verify the executable paths apply to your Teams version before deploying. The New Teams desktop client executable is typically located at `%LocalAppData%\Microsoft\Teams\current\Teams.exe` for user installs or via the system-wide MSIX package path for machine-wide installs. ## The Problem ![Open Image: Teams, PowerShell, Windows Defender and Intune logos](/media/posts/intune/managing-microsoft-teams-firewall-requirements-with-intune/teams_firewall_script-1366x500-c3e8f7c2cb.png) With over 44 million active users, Microsoft Teams creates a familiar headache: the annoying "Windows Security Alert" from Windows Firewall every time users try to share their screen. ![Open Image: Microsoft Teams Firewall prompt](/media/posts/intune/managing-microsoft-teams-firewall-requirements-with-intune/img_5e80fec18129b-5bfac18cb9.png) The Teams executable requires an inbound Firewall rule when it detects users on the same domain network. Teams tries to create the rules automatically but they require admin permissions. Dismissing the prompt actually creates two **blocking** Firewall rules for Teams.exe. The complication: Teams.exe is usually installed **per-user** in the user's APPDATA folder (`%localappdata%\Microsoft\Teams\current\Teams.exe`), making it impossible to create a single rule via the built-in Firewall CSP. ## The Script Solution The official Microsoft script is simple but not intelligent. The improved script is specifically designed for Intune: **Fetch it from GitHub:** [Update-TeamsFWRules.ps1](https://github.com/mardahl/MyScripts-iphase.dk/blob/master/Update-TeamsFWRules.ps1) Improvements over the Microsoft script: - Designed for Intune PowerShell script deployment assigned to user groups - Runs once per user and detects who is signed in - Cleans up existing blocking rules created by dismissed firewall prompts ## Configuring the PowerShell script in Intune Navigate to the Microsoft Intune admin center at https://intune.microsoft.com: 1. Go to **Devices** > **Windows** > **PowerShell scripts** 2. Click **Add** ![Open Image: PowerShell scripts blade in Intune](/media/posts/intune/managing-microsoft-teams-firewall-requirements-with-intune/img_5e810fca7b8cb-7543902fe1.png) 3. Name it "Teams firewall prompt fix" ![Open Image: Basic information for script](/media/posts/intune/managing-microsoft-teams-firewall-requirements-with-intune/img_5e8110d4e4b73-f51f3fb691.png) 4. Upload the script. **Leave script settings as-is** (runs in system context, NOT user context) ![Open Image: Script settings configuration](/media/posts/intune/managing-microsoft-teams-firewall-requirements-with-intune/img_5e811369ae807-6f9ec58f9e.png) 5. Assign to a **group of users** (not devices) ![Open Image: Assigning script to user groups](/media/posts/intune/managing-microsoft-teams-firewall-requirements-with-intune/img_5e81163d2aecd-30ff485314.png) 6. Review and click **Add** ![Open Image: Review and add script](/media/posts/intune/managing-microsoft-teams-firewall-requirements-with-intune/img_5e81178d98ee3-4bcee5d865.png) ## Troubleshooting The script generates log files: - System log: `%windir%\Temp\log_Update-TeamsFWRules.txt` - User log: `%localappdata%\Temp\log_Update-TeamsFWRules.txt` ![Open Image: Intune script execution status](/media/posts/intune/managing-microsoft-teams-firewall-requirements-with-intune/img_5e811a893c811-d0954b1a85.png) Key reminders: - Assign to a group of **USERS** not devices - **DON'T** run in the user's own context - Intune Management Extension is required for PowerShell script execution ## Conclusion We now have a simple way of deploying Firewall rules that target programs installed in user profiles. This approach can be adapted for other per-user applications in the future. --- ## [Passwordless journey with FIDO2 - Part 3 - Engine troubles](https://iphase.dk/posts/identity/passwordless-journey-with-fido2-part-3-engine-troubles) Date: 2020-02-07 Category: identity Tags: fido2, passwordless, mfa, security-keys, azure-ad > ARCHIVED -- This post has been archived. This post contains 2019-era hardware reviews for FIDO2 security keys. The products and firmware versions discussed are outdated and some devices reviewed are discontinued. The original content is preserved below for historical reference. --- Original content preserved below: --- ## Series Navigation - [Part 1 - Getting started with Security keys](/posts/identity/passwordless-journey-with-fido2-part-1-getting-started-with-security-keys/) - [Part 2 - Usage experiences](/posts/identity/passwordless-journey-with-fido2-part-2-usage-experiences/) ![Open Image: FIDO2 Passwordless Future authentication process](/media/posts/identity/passwordless-journey-with-fido2-part-3-engine-troubles/fido2-passwordless-future-f49116ef89.png) ## Recent learnings Since the last article, many vendors are producing FIDO2 compliant security keys, but Microsoft requires vendors to be on an approved list for Azure AD to accept the key during enrollment. That's problematic if you bought keys from the "wrong" vendor. Tim Steiner from OnlyKey.io helped figure out how to whitelist a FIDO2 compliant key for your own tenant. ## Adding unsupported FIDO2 keys to Azure AD You can add specific unsupported vendor security keys to your Azure AD (or restrict to a specific list): ![Open Image: Azure AD FIDO2 key restriction settings](/media/posts/identity/passwordless-journey-with-fido2-part-3-engine-troubles/img_5e3d6af431986-bf4902c42c.png) To discover the **AAGUID** of your key, use the Python-fido2 tool from Yubico: [python-fido2 on GitHub](https://github.com/Yubico/python-fido2) ```bash $ python examples/get_info.py ``` ![Open Image: Output from python-fido2 get_info showing AAGUID](/media/posts/identity/passwordless-journey-with-fido2-part-3-engine-troubles/img_5e3d7766519b3-651bc07f76.png) Example AAGUID for OnlyKey: **79d699df01914b10b9035467e7ce8231** ## Ensurity ThinC-AUTH ![Open Image: Ensurity ThinC-AUTH FIDO2 key](/media/posts/identity/passwordless-journey-with-fido2-part-3-engine-troubles/ensurity-thinc-auth-key-cdn.webp) - Level 1 certified biometric FIDO2 key - Fully supported by Microsoft out of the box - Fast fingerprint reader - Bulky design but offers bespoke design options for businesses - Best unboxing experience with built-in user registration guide - HTML-based management app running customized Chromium ![Open Image: Ensurity ThinC-AUTH management software](/media/posts/identity/passwordless-journey-with-fido2-part-3-engine-troubles/img_5e3d805f9f514-6ffc03e283.png) More info: [Ensurity ThinC-AUTH](https://www.ensurity.com/Products/ThinC_AUTH) ## KEY-ID FIDO2+U2F and EzFinger 2 Very small FIDO2 devices with biometric and button versions. Requires AAGUID whitelisting for Azure AD but works out of the box with Windows Hello. ![Open Image: KEY-ID FIDO2 tiny security keys](/media/posts/identity/passwordless-journey-with-fido2-part-3-engine-troubles/img_5e3d843abb33b-8923ad89e4.png) ![Open Image: KEY-ID FIDO2 BIO Windows Hello](/media/posts/identity/passwordless-journey-with-fido2-part-3-engine-troubles/KEY-FIDO2-BIO-Windows-Hello-b813db808b.jpg) - Tiny enough to leave in your device (but defeats the purpose) - Fast fingerprint reading from all angles - Management exe is under 4MB - easiest to deploy ![Open Image: KEY-ID fingerprint management software](/media/posts/identity/passwordless-journey-with-fido2-part-3-engine-troubles/img_5e3d85dc1dcff-88644fcd87.png) More info: [KEY-ID Security Keys](https://www.key-id.com/fido-security-keys-overview/) ## OnlyKey A completely different kind of security key, made by whitehat hackers and security experts. Open source like the Solokey. ![Open Image: OnlyKey security device](/media/posts/identity/passwordless-journey-with-fido2-part-3-engine-troubles/onlykey-1024x1024-ab0f29ff95.jpg) - Uses a 6-digit minimum PIN on the physical numpad instead of biometrics - Self-wipes after 10 failed PIN attempts - Holds up to 24 separate static accounts accessible via the numpad - Works as a portable hardware-based password manager - Can configure via notepad (unique feature) ![Open Image: OnlyKey management GUI](/media/posts/identity/passwordless-journey-with-fido2-part-3-engine-troubles/onlykeyGUI-905e7b71e7.png) Not recommended for average users due to complex enrollment, but perfect for sysadmins and security-focused geeks. More info: [OnlyKey](https://onlykey.io/) ## Final words As organizations adopt passwordless, remember to encourage users to use their keys for both business and personal accounts. This drives adoption and awareness. And let them keep the key - don't make a fuss about tracking and returning keys. They should be considered expendable. --- ## [Conditional Access and the woes of being an external user](https://iphase.dk/posts/identity/conditional-access-and-the-woes-of-being-an-external-user) Date: 2020-01-19 Category: identity Tags: conditional-access, identity-and-access, microsoft-authenticator, consultants, mfa > UPDATED March 2026 -- This post has been reviewed and updated to reflect current Microsoft product names, portal locations, and technology status. See inline notes for specific changes. ## The Challenge ![Open Image: Microsoft Authenticator App](/media/posts/identity/conditional-access-and-the-woes-of-being-an-external-user/microsoft-authenticator-app-bb027a912a.jpg) Conditional Access and multi-tenancy can be tough on anyone used to "the old ways." As a consultant spending admin time in other tenants, taking my identity with me via Entra ID external user invites is extremely useful. Entra ID makes this easy by allowing customers to on-board me as an external user through a simple invite, granting permissions, and I'm good to go. ## An invited identity is still a separate identity If your customers require external users to authenticate with MFA (and they should), you'll be prompted to provide extra MFA details for the external user identity. The experience can be confusing because you see your own tenant's branding during initial logon, making it seem like you're feeding data into your own tenant. On smartphones it's especially hard to distinguish. **Remember:** Conditional Access can be evaluated in both tenants simultaneously, and you must pass both. The real pain comes when you change your smartphone or lose it. If you set up the Authenticator app in another organization, you might need them to activate "Require re-register MFA" to get back in. Not cool. ## The Modern Solution (Updated 2026) Microsoft has significantly improved the external user MFA experience since this post was written. The recommended approach for external users is now: - Use **passkeys** (device-bound via Microsoft Authenticator) -- these are tied to your device and work seamlessly across all tenants without per-tenant MFA registration - Use **FIDO2 security keys** -- register once, use across any tenant that supports external authentication - Configure **cross-tenant access settings** in Entra ID to trust MFA claims from the user's home tenant, eliminating the need for re-registration entirely The cross-tenant access approach is the cleanest solution for organizations that regularly work with the same external partners. See [Microsoft's cross-tenant access documentation](https://learn.microsoft.com/en-us/entra/external-id/cross-tenant-access-overview) for setup details. ## What to do The solution is simple: - Use a **FIDO2 key** for MFA as an external user - Or use **text message/phone call** verification methods when registering for MFA in external tenants (with acknowledged security trade-offs) ![Open Image: FIDO2 passwordless authentication](/media/posts/identity/conditional-access-and-the-woes-of-being-an-external-user/fido2-passwordless-future-f49116ef89.png) There's also the option of excluding Guests and External users from Conditional Access, but that's **not recommended** for obvious security reasons. Reference: [Microsoft identity access policies for guest access](https://docs.microsoft.com/en-us/microsoft-365/enterprise/identity-access-policies-guest-access) If you're using Microsoft Teams on mobile, linking the Authenticator app during the enhanced registration process (preview) can be hit-or-miss - sometimes it works, sometimes it doesn't. ## Final Words These are real-world experiences shared for your own evaluation. The multi-tenant external user experience with MFA is an area that still needs improvement. --- ## [Passwordless journey with FIDO2 - Part 2 - Usage experiences](https://iphase.dk/posts/identity/passwordless-journey-with-fido2-part-2-usage-experiences) Date: 2019-11-18 Category: identity Tags: fido2, passwordless, sso, yubico, yubikey, ewbm, solokeys > ARCHIVED -- This post has been archived. This post contains 2019-era hardware reviews for FIDO2 security keys. The products and firmware versions discussed are outdated and some devices reviewed are discontinued. The original content is preserved below for historical reference. --- Original content preserved below: --- ## Series Navigation - [Part 1 - Getting started with Security keys](/posts/identity/passwordless-journey-with-fido2-part-1-getting-started-with-security-keys/) ![Open Image: FIDO2 Passwordless Future](/media/posts/identity/passwordless-journey-with-fido2-part-2-usage-experiences/fido2-passwordless-future-f49116ef89.png) In the last part I wrote about the beginning of my passwordless journey and which keys I had available. In this second part I'll cover overall experiences with each vendor's security keys. A key fact true for all keys: The key only needs to be inserted at time of authentication, so don't leave it in all day. ## Solokeys Solo Tap USB-A (NFC) This key might be good for Google or Facebook, but it was not pleasant for Azure AD use. The pre-loaded firmware didn't allow adding it to Azure AD. Even after a less-than-pleasant firmware update process, with annoying prompts every second: ![Open Image: Annoying prompts during Solokey firmware update](/media/posts/identity/passwordless-journey-with-fido2-part-2-usage-experiences/update-solokey-annoying-prompt-23c2151d4b.gif) The mysignins page showed this key was "blocked by my organisation" - meaning Microsoft's block list, not my tenant's. ![Open Image: Solokey blocked by organisation error](/media/posts/identity/passwordless-journey-with-fido2-part-2-usage-experiences/img_5daca7bbd20d8-cc6bb9379c.png) **Moral:** Go with an approved vendor. Don't just use any FIDO2 Security Key for Azure AD. ## Yubico keys Unboxing was nice, easy to get started, and good build quality. No trouble registering with Azure AD. The built-in Windows Security Key Manager works nicely: ![Open Image: Windows Security Key Manager with Yubikey](/media/posts/identity/passwordless-journey-with-fido2-part-2-usage-experiences/img_5dc99f9486cae-f15c1682b1.png) The YubiKey Manager offers more features but is a 250MB install with over 3500 files: ![Open Image: YubiKey Manager application](/media/posts/identity/passwordless-journey-with-fido2-part-2-usage-experiences/img_5dc99fec9abc2-2ea5cff58f.png) Sign-in to Windows works, but without biometrics you need to enter a PIN each time - not as fast as biometric keys. A great feature: you can add a **static password** that types out when you long-press the touch sensor. This works because the Yubikey registers as a HID keyboard, enabling passwordless for legacy apps without SSO. Overall happy with Yubikeys, but the lack of biometrics kept me from using them more regularly. ## eWBM keys The eWBM keys come in a reusable box and seem very robust. Setup was smooth with no firmware upgrades or software needed. The BioManager application: ![Open Image: eWBM BioManager software](/media/posts/identity/passwordless-journey-with-fido2-part-2-usage-experiences/img_5dd1a937805d0-99c736cdae.png) The **super fast biometric fingerprint reader** is the standout feature. It's far superior to laptop fingerprint readers and makes daily use much smoother - insert key, touch, done. No PIN required. eWBM has achieved **FIDO2 Level 2 certification** - the highest practical level currently available: ![Open Image: FIDO Authenticator Certification Levels](/media/posts/identity/passwordless-journey-with-fido2-part-2-usage-experiences/FIDO-Certification-Levels-Graphics-01-1-1024x595-1-74a9afa1e6.png) This key doesn't suffer from feature creep - it's a focused FIDO2 key, which speaks to the company's seriousness about this one thing. ## The end of part 2 This is not a product review but one admin's opinion from daily use. For OS sign-in, Windows Hello for Business with Face ID is still preferred when compatible hardware is available. But security keys shine when connecting from any device other than your personally assigned one. If embarking on a serious passwordless journey, read Microsoft's passwordless strategy: ![Open Image: Microsoft's four steps to passwordless](/media/posts/identity/passwordless-journey-with-fido2-part-2-usage-experiences/four-steps-passwordless-1024x574-1b7553a0d9.png) Reference: [Microsoft Passwordless Strategy](https://docs.microsoft.com/en-us/windows/security/identity-protection/hello-for-business/passwordless-strategy) --- ## [Passwordless journey with FIDO2 - Part 1 - Getting started with Security keys](https://iphase.dk/posts/identity/passwordless-journey-with-fido2-part-1-getting-started-with-security-keys) Date: 2019-10-28 Category: identity Tags: fido2, passwordless, security-key, yubico, ewbm, solokeys, azure-ad > UPDATED March 2026 -- This post has been reviewed and updated to reflect current Microsoft product names, portal locations, and technology status. See inline notes for specific changes. ## Why Passwordless? ![Open Image: FIDO2 Passwordless Future](/media/posts/identity/passwordless-journey-with-fido2-part-1-getting-started-with-security-keys/fido2-passwordless-future-f49116ef89.png) FIDO2, Multifactor Authentication, passwordless, Windows Hello for Business, Microsoft Authenticator, Security keys - these security buzzwords are taking the spotlight, and with good reason. [![Open Image: FIDO2 Logo](/media/posts/identity/passwordless-journey-with-fido2-part-1-getting-started-with-security-keys/fido2-300x145-64ca1886f9.png)](https://msendpointmgr.com/wp-content/uploads/2019/10/fido2.png) [![Open Image: Azure AD Logo](/media/posts/identity/passwordless-journey-with-fido2-part-1-getting-started-with-security-keys/AzureAD-300x91-aed58a524e.png)](https://msendpointmgr.com/wp-content/uploads/2019/10/AzureAD.png) In a time of targeted ransomware attacks, a password alone is no longer enough. The benefits of going passwordless with FIDO2: - No more shoulder surfing - No more account hijacking - No more forgotten password helpdesk requests - No more password phishing - No more password reuse - No more typing "October2019#" several times a day - No more passwords! > NOTE (Updated 2026): Since this post was written, the industry has converged on "passkeys" as the unified term for FIDO2-based phishing-resistant credentials. Passkeys encompass both hardware security keys (covered in this series) and device-bound or synced passkeys in apps like Microsoft Authenticator. For the current state of passkeys and Microsoft's MFA mandate, see the [2026 MFA update post](/posts/identity/passkeys-personal-phone-mfa-update/). If you're on the fence, check out Microsoft's whitepaper: [Go Passwordless](https://aka.ms/gopasswordless) ## The Requirements - **Microsoft Entra joined devices** required for Windows 10 sign-in with FIDO2 (Hybrid-Joined support was in preview) - Token must support specific FIDO2 CTAP protocol features - FIDO2 Security key authentication enabled in your Tenant - Combined security information registration enabled - A browser that supports WebAuthN - Windows 10 1809 or newer > NOTE (Updated 2026): The minimum Windows version requirement has been updated. Windows 10 version 1809 is no longer supported by Microsoft. The current minimum supported version for FIDO2 security key sign-in is Windows 10 21H2. Windows 11 is recommended. For Hybrid-Joined or Microsoft Entra registered-only devices, passwordless is limited to websites via WebAuthN browser support. ## The First Few Hurdles Registering keys via the [mysignins](https://mysignins.microsoft.com) portal is simple after enabling the new registration experience, but watch out for: - Proxy/firewall blocking Microsoft sites causing infinite reload loops - Occasional "Sorry, we can't sign you in" glitch that resolves in seconds ![Open Image: Sign-in glitch message](/media/posts/identity/passwordless-journey-with-fido2-part-1-getting-started-with-security-keys/img_5db558f3df5bf-a7cf913027.png) Once in, manage your security keys: ![Open Image: Security key listing on mysignins page](/media/posts/identity/passwordless-journey-with-fido2-part-1-getting-started-with-security-keys/security-key-mysignins-a09bc3bc6d.png) For Windows 10 sign-in, I had to refresh (re-install) my 1903 machine to get the FIDO security key option on the lock screen: ![Open Image: FIDO security key sign-in option on Windows lock screen](/media/posts/identity/passwordless-journey-with-fido2-part-1-getting-started-with-security-keys/security_key_signin-c8268eb2ae.png) ## The Token Vendors Microsoft partnered with Feitian Technologies, HID Global, and Yubico at launch. Others have since joined. ### Yubico [![Open Image: Yubico Logo](/media/posts/identity/passwordless-journey-with-fido2-part-1-getting-started-with-security-keys/yubico_logo-300x90-473832e2ec.png)](https://msendpointmgr.com/wp-content/uploads/2019/10/yubico_logo.png) - Swedish/US based, Microsoft partner at launch - FIDO2 Certified (Level 1) - Wide range of keys, international shipping **Yubikey 5 NFC (USB-A) and Yubikey 5C (USB-C):** ![Open Image: Yubikey 5 NFC](/media/posts/identity/passwordless-journey-with-fido2-part-1-getting-started-with-security-keys/yubikey-5-nfc_3-150x150-99c48d2466.png) ![Open Image: Yubikey 5C USB-C](/media/posts/identity/passwordless-journey-with-fido2-part-1-getting-started-with-security-keys/yubikey-5c_2-150x150-dc2b79b41b.png) Full FIDO2 CTAP protocol support. The USB-C key is tiny - maybe too tiny. Durable and waterproof. Features overview: [Yubico YubiKey 5](https://www.yubico.com/products/yubikey-5-overview/) ### eWBM [![Open Image: eWBM Logo](/media/posts/identity/passwordless-journey-with-fido2-part-1-getting-started-with-security-keys/ewbm_logo-119f0a6f98.png)](https://msendpointmgr.com/wp-content/uploads/2019/10/ewbm_logo.png) - Korean/US based, Microsoft Intelligent Security Association member - Integrated biometrics - **FIDO2 Certified (Level 2)** - world's first and only at time of writing **Goldengate Security Key G310 (USB-A) and G320 (USB-C):** ![Open Image: eWBM Goldengate G310 and G320 security keys](/media/posts/identity/passwordless-journey-with-fido2-part-1-getting-started-with-security-keys/ewbm-goldengate-G310-G320-300x204-4dbf22e192.jpg) Endorsed by Microsoft, biometrics are fast, no NFC support. More durable than Yubikeys. Register multiple fingers but no finger index. Features: [eWBM Goldengate series](https://www.ewbm.com/page/Goldengate) ### Solokeys [![Open Image: Solokeys Logo](/media/posts/identity/passwordless-journey-with-fido2-part-1-getting-started-with-security-keys/Solokeys_logo-dac58a372f.png)](https://msendpointmgr.com/wp-content/uploads/2019/10/Solokeys_logo.png) - US based, crowdfunded - First open-source FIDO2 key - Not really a passwordless key per their FAQ - Not very robust - users will break them **Solo Tap USB-A (NFC):** ![Open Image: Solo Tap NFC key](/media/posts/identity/passwordless-journey-with-fido2-part-1-getting-started-with-security-keys/solo-tap-nfc-150x150-9c952a9008.png) Not officially supported by Microsoft for Azure AD. Has a real push button and NFC (Android only). ## The end of part 1 Next part: [Passwordless journey with FIDO2 - Part 2 - Usage experiences](/posts/identity/passwordless-journey-with-fido2-part-2-usage-experiences/) --- ## [2 Cool new password policy features in Microsoft Entra Connect Sync](https://iphase.dk/posts/identity/2-cool-new-password-policy-features-in-azure-ad-connect) Date: 2019-10-07 Category: identity Tags: azure-ad-connect, password-policy, user-accounts, entra-id > UPDATED March 2026 -- This post has been reviewed and updated to reflect current Microsoft product names, portal locations, and technology status. See inline notes for specific changes. ## The What ![Open Image: Microsoft Entra Connect Sync Password Policy Feature](/media/posts/identity/2-cool-new-password-policy-features-in-azure-ad-connect/azureAdConnectPasswordPolicyFeature-d6ca98cd8a.png) Two long-anticipated features have entered public preview in Microsoft Entra Connect Sync, killing off one of the last arguments for staying on AD FS or Pass-Through Authentication: 1. **Force password reset at logon** - Sync temporary passwords and force change on next logon 2. **Enforce cloud password policy for synced users** - Apply Entra ID password expiration to synced accounts ## The Why It makes little sense to enforce password expiration on-prem and have it go away after syncing to Entra ID. Same goes for enforcing temporary passwords after helpdesk resets. Many admins have been using PowerShell workarounds or stayed with AD FS/PTA because of this gap. If this misalignment never crossed your mind, reconsider why you have password expiration at all. Microsoft and NIST now advocate longer passwords that don't expire, paired with good MFA. ## The How ![Open Image: PowerShell is Cool](/media/posts/identity/2-cool-new-password-policy-features-in-azure-ad-connect/PowerShellIsCool-9a417b75fe.png) ### Enforce cloud password policy for synced accounts Run this against Entra ID (e.g., via Azure Cloud Shell): > NOTE (Updated 2026): The MSOnline module cmdlet below has been retired. The equivalent Microsoft Graph PowerShell SDK command is: `Update-MgDomain` or configure via the Entra ID portal under Password protection settings. ```powershell Set-MsolDirSyncFeature -feature EnforceCloudPasswordPolicyForPasswordSyncedUsers $true ``` > NOTE (Updated 2026): The MSOnline (Set-Msol*) and AzureAD (*-AzureAD*) PowerShell modules were retired in March 2024. Replace these cmdlets with the [Microsoft Graph PowerShell SDK](https://learn.microsoft.com/en-us/powershell/microsoftgraph/). The code above is kept for historical reference only. This disables the default behavior where synced user cloud identities are set to "password never expires." ### Syncing a temporary password Run this on your Microsoft Entra Connect Sync server: ```powershell Set-ADSyncAADCompanyFeature -ForcePasswordResetOnLogonFeature $true ``` ## The When Available now in preview. Microsoft preview features hold no production obligations, but abuse of this right is rare. Enable it and test. ## The Caveats ### Setting a permanent password from the cloud Users signing in with a temporary password through a cloud service will set their permanent password in Entra ID, **not** directly back to on-prem AD. You need **password writeback** and **SSPR** enabled for that. ### Expired users Disabled accounts can still sign in to cloud services even when the on-prem account expiration attribute is set. If you just disable terminated users (rather than expire them), Microsoft Entra Connect Sync will sync the disabled state properly. ### Service accounts Service accounts will now get their passwords expired. Fix this per-account: ```powershell Get-AzureADUser | Set-AzureADUser -PasswordPolicies "DisablePasswordExpiration" ``` > NOTE (Updated 2026): The MSOnline (Set-Msol*) and AzureAD (*-AzureAD*) PowerShell modules were retired in March 2024. Replace these cmdlets with the [Microsoft Graph PowerShell SDK](https://learn.microsoft.com/en-us/powershell/microsoftgraph/). The code above is kept for historical reference only. ### Password policy misalignment Your local password policy is **NOT** synced to Entra ID. If your on-prem policy expires at 120 days but Entra ID defaults to 90 days, users will get confused by mismatched expiration prompts. Align both policies. ## Final words Use new knowledge responsibly and remember to share. These features represent important steps in unifying the identity experience between on-prem AD and Microsoft Entra ID. --- ## [The Trouble with PEAP and Credential Guard](https://iphase.dk/posts/misc/the-trouble-with-peap-and-credential-guard) Date: 2018-07-14 Category: misc Tags: credential-guard, windows-10, security, peap, cisco-ise, certificates > UPDATED March 2026 -- This post has been reviewed and updated to reflect current Microsoft product names, portal locations, and technology status. See inline notes for specific changes. ## Windows 10 Credential Guard and Cisco ISE Conflicts Using PEAP ![Open Image: Credential Guard isolates your credentials to mitigate against MitM attacks](/media/posts/misc/the-trouble-with-peap-and-credential-guard/device-guard-windows-10-279e8a410d.jpg) > If you have enabled credential guard in Windows 10 and have a network security mechanism like Cisco ISE or just plain Enterprise WPA2 - then you **will** run into some issues if you have set your authentication method to PEAP (EAP-MSCHAPv2). Credential Guard is a powerful security mechanism against [Man-in-the-Middle attacks](https://en.wikipedia.org/wiki/Man-in-the-middle_attack) that have become more common with the rise of the Cryptolocker ransomware. The service enables virtualization-based security by using the Windows Hypervisor to support security services on the device. Microsoft makes this available to all their customers running Windows 10 on [supported devices](https://docs.microsoft.com/en-us/windows/security/identity-protection/credential-guard/credential-guard-requirements), and it is fairly simple to [implement](https://msendpointmgr.com/2016/06/15/enable-credential-guard-in-windows-10-during-osd-with-configmgr/). > NOTE (Updated 2026): Starting with Windows 11 22H2, Credential Guard is enabled by default on all eligible devices that meet hardware requirements. On Windows 11 Enterprise and Education editions, Credential Guard is enabled automatically during upgrade if the hardware supports it. This means the PEAP compatibility issue described in this post may now affect a much larger population of devices than when it was originally written. But it turns out that enabling the service will prevent the authentication supplicant in Windows 10 from sending the user's credentials to the Cisco ISE RADIUS service (or ANY RADIUS server for that matter). So if you have enabled Credential Guard in Windows 10 and have a network security mechanism like Cisco ISE or just plain Enterprise WPA2 - then you **will** run into issues if you have set your authentication method to PEAP (EAP-MSCHAPv2). And you will notice a lot of entries in the Cisco ISE live authentications view, similar to this: `5440 Endpoint abandoned EAP session and started new` ## What to Do? Unfortunately, a fix from either Cisco or Microsoft does not seem available at the time of writing this, so switching over to a certificate or smart-card based authentication is the only option short of disabling Credential Guard. > I recommend using certificate-based authentication with User certificates, which can be distributed either through Group Policy or via Microsoft Intune. And it might never get "fixed" since Credential Guard was developed to secure against tools like Mimikatz, which basically does the same thing as PEAP authentication - namely passing the users hashed credentials. Let's hope an alternative comes along in the future. As the PEAP option does provide some flexibility over using certificates, albeit being slower to authenticate. Though I doubt it as this is the price of added security. And PEAP is not as safe as some might think. That's why I recommend using certificate-based authentication with User certificates, which can be distributed either through Group Policy or via Microsoft Intune, leveraging [SCEP](https://msendpointmgr.com/2018/06/22/certificate-deployment-for-mobile-devices-using-microsoft-intune-part-3-install-ndes/). --- ## For Those Trying to Find This Info via Google Below is a sample of the steps that occur in Cisco ISE when the client tries to connect and fails: ``` Steps 11001 Received RADIUS Access-Request 11017 RADIUS created a new session 15049 Evaluating Policy Group 15008 Evaluating Service Selection Policy 15048 Queried PIP 15048 Queried PIP 15048 Queried PIP 15048 Queried PIP 15004 Matched rule 15048 Queried PIP 15048 Queried PIP 15004 Matched rule 11507 Extracted EAP-Response/Identity 12500 Prepared EAP-Request proposing EAP-TLS with challenge 12625 Valid EAP-Key-Name attribute received 11006 Returned RADIUS Access-Challenge 11001 Received RADIUS Access-Request 11018 RADIUS is re-using an existing session 12301 Extracted EAP-Response/NAK requesting to use PEAP instead 12300 Prepared EAP-Request proposing PEAP with challenge 12625 Valid EAP-Key-Name attribute received 11006 Returned RADIUS Access-Challenge 11001 Received RADIUS Access-Request 11018 RADIUS is re-using an existing session 12302 Extracted EAP-Response containing PEAP challenge-response and accepting PEAP as negotiated 12318 Successfully negotiated PEAP version 0 12800 Extracted first TLS record; TLS handshake started 12805 Extracted TLS ClientHello message 12806 Prepared TLS ServerHello message 12807 Prepared TLS Certificate message 12810 Prepared TLS ServerDone message 12305 Prepared EAP-Request with another PEAP challenge 11006 Returned RADIUS Access-Challenge 11001 Received RADIUS Access-Request 11018 RADIUS is re-using an existing session 12304 Extracted EAP-Response containing PEAP challenge-response 12318 Successfully negotiated PEAP version 0 12812 Extracted TLS ClientKeyExchange message 12804 Extracted TLS Finished message 12801 Prepared TLS ChangeCipherSpec message 12802 Prepared TLS Finished message 12816 TLS handshake succeeded 12310 PEAP full handshake finished successfully 12305 Prepared EAP-Request with another PEAP challenge 11006 Returned RADIUS Access-Challenge 11001 Received RADIUS Access-Request 11018 RADIUS is re-using an existing session 12304 Extracted EAP-Response containing PEAP challenge-response 12313 PEAP inner method started 11521 Prepared EAP-Request/Identity for inner EAP method 12305 Prepared EAP-Request with another PEAP challenge 11006 Returned RADIUS Access-Challenge 11001 Received RADIUS Access-Request 11018 RADIUS is re-using an existing session 12304 Extracted EAP-Response containing PEAP challenge-response 11522 Extracted EAP-Response/Identity for inner EAP method 11806 Prepared EAP-Request for inner method proposing EAP-MSCHAP with challenge 12305 Prepared EAP-Request with another PEAP challenge 11006 Returned RADIUS Access-Challenge (Step latency="1001 ms) 5440 Endpoint abandoned EAP session and started new ``` > Note that this is not a bug! It will affect any authentication using PEAP as this is the design of Credential Guard. ## Conclusion Please note that this is not a bug! It will affect any authentication using PEAP as this is the design of Credential Guard - so you might want to consider this problem if you have other services that rely on PEAP, and experience issues after enabling Credential Guard. Read more about this new security mechanism here: https://docs.microsoft.com/en-us/windows/access-protection/credential-guard/credential-guard --- ## [Getting Off to a Good Start with Microsoft 365 Groups](https://iphase.dk/posts/modernwork/getting-off-to-a-good-start-with-microsoft-365-groups) Date: 2017-12-23 Category: modernwork Tags: office-365, microsoft-365-groups, microsoft-teams, collaboration > UPDATED March 2026 -- This post has been reviewed and updated to reflect current Microsoft product names, portal locations, and technology status. See inline notes for specific changes. ## Introduction A must read for anyone contemplating the use Microsoft 365 Groups within their Organization. --- *Microsoft 365 Groups are here to stay!* and they offer huge benefits for collaboration on projects and daily tasks. It is however extremely easy to just turn this feature on, and then just let the users go crazy. But you really should consider the following points before jumping the gun. ![Open Image: Microsoft 365 Groups infograph](/media/posts/modernwork/getting-off-to-a-good-start-with-microsoft-365-groups/office365_groups_info-dbfc0cd745.png) ## A Few Pointers on Getting Off to a Good Start with Microsoft 365 Groups (UnifiedGroups) 1. **[Define a Naming Policy for your groups](https://support.office.com/en-us/article/office-365-groups-naming-policy-6ceca4d3-cad1-4532-9f0f-d469dfbbb552)**. - Prefix, suffix? Not a practical thing to change once you have 1000 groups... 2. **[Define one or more custom email domains specific to group creation](https://gist.github.com/mardahl/9154427d07f680cb8d427093f20a90f1)**. - E.g. groups.contoso.com. (so groups emails won't clash with regular email account names) 3. **[Make sure your users know just how much stuff comes with these Microsoft 365 Groups](https://en.share-gate.com/blog/office-365-groups-explained)**. - It's A LOT! (Consider setting up training sessions!) 4. **[Birth them through Teams if you are doing chat based collaboration](https://support.office.com/en-us/article/learn-about-office-365-groups-b565caa1-5c40-40ef-9915-60fdb2d97fa2#ID0EAACAAA=Create)**. - Not required though... But it will give the most features OOTB. - **UPDATE**: be aware of this change to outlook behaviour: https://www.microsoft.com/microsoft-365/roadmap?filters=&searchterms=26955 > NOTE (Updated 2026): Microsoft 365 roadmap links referenced in this post may have expired or changed. Visit [microsoft.com/microsoft-365/roadmap](https://www.microsoft.com/microsoft-365/roadmap) directly to find current feature status. 5. **[Consider restricting who can create the Microsoft 365 groups](https://support.office.com/en-us/article/manage-who-can-create-office-365-groups-4c46c8cb-17d0-44b5-9776-005fced8e618)**. - Or you will have chaos within a short amount of time. 6. **[Keep in mind that all groups have a file area to store data in](https://support.office.com/en-us/article/share-group-files-749bc73b-90c9-4760-9b6f-9aa1cf01b403)**. - Consider using a login script to have users OneDrive client populated with available file areas (/posts/modernwork/easy-automapping-office-365-groups-drives-with-onedrive/). 7. New things happen ALL the time with Microsoft 365 Groups! - You should consider reading the [official docs](https://docs.microsoft.com/da-dk/office365/admin/create-groups/office-365-groups?view=o365-worldwide)! 8. Microsoft 365 Groups are the foundation for Microsoft 365 Copilot collaboration features and Microsoft Loop workspaces. Ensure your Groups governance strategy accounts for AI-generated content and Loop component sharing. All of the above items, link to relevant reading / tricks / scripts. I suggest you dig your teeth into them if you want to get serious about Groups! The good Adam Fowler has also written a few gotchas! https://www.adamfowlerit.com/2019/05/office-365-group-as-a-distribution-list-gotchas/ This video from Ignite 2017 is also pretty great for IT Pros wanting to get more info on Microsoft 365 Groups: ![Open Video: Microsoft 365 Groups overview from Ignite 2017](https://www.youtube.com/embed/ZWu73ZTlQk8) > There are a lot more areas to consider, but these are a must in my opinion. ---