If a Windows 365 Cloud PC fails over to its backup region during a regional outage, how would you actually know - other than a user emailing you to ask why their desktop looks different? Until Microsoft's September 2026 Graph update, the honest answer for most admins was "we wouldn't, not without asking the user." There was no field to query, no status to check, nothing to build a dashboard or an alert around.
That's changed. Microsoft has added a new property and two new status values to the Cloud PC object in Microsoft Graph, specifically so you can see disaster recovery state programmatically. This post explains what a Cloud PC and disaster recovery actually are in plain English first, then gets fully technical: the exact Graph properties, the PowerShell to query them, and a script that reports which Cloud PCs in your tenant are currently failed over.
A Windows 365 Cloud PC is a Windows desktop that runs entirely in Microsoft's cloud instead of on a physical machine. Disaster recovery (DR) means Microsoft can temporarily run a licensed user's Cloud PC in a different geographic region if their normal region has an outage - and until now, there was no way to check that state through code. Microsoft Graph's beta API now exposes a boolean isDisasterRecoveryActive property on the Cloud PC object, plus two new values - failoverInProgress and failbackInProgress - for the existing status property. Together, these let you build a script or dashboard that shows exactly which Cloud PCs are mid-failover, currently running from a DR region, or on their way back home - something that was previously invisible to automation entirely.
The problem: a Cloud PC can fail over and nobody in IT would know
Picture a regional Azure outage. A handful of your users' Cloud PCs automatically fail over to a backup region so those people can keep working. From the user's side, this is mostly invisible - they get a warning message and then a working desktop. From IT's side, until this Graph update, it was also mostly invisible - there was no property on the Cloud PC object that said "this one is currently running from its disaster recovery region."
That gap matters for a few concrete reasons. Compliance and data residency teams often care which region a Cloud PC's data is physically sitting in - a DR failover can temporarily move that. Help desk teams debugging "my Cloud PC looks different today" tickets had no fast way to confirm DR was the cause. And nobody had a way to build a simple dashboard or alert that says "here's how many Cloud PCs are currently running out of their backup region right now."
Why it happens: what a Cloud PC and disaster recovery actually are
Skip this section if you already work with Windows 365 daily - everyone else, keep reading, because the rest of the post assumes you know these terms.
A Cloud PC is a full Windows desktop that Microsoft runs for you in Azure, on Microsoft's hardware, in one of Microsoft's data center regions. A user connects to it over the internet from any device, and it behaves like a normal PC - their apps, their files, their settings - except the actual computer doing the work lives in the cloud, not on the desk in front of them. This is the product Microsoft sells as Windows 365.
Disaster recovery, in this context, is an optional add-on: if the Azure region hosting a user's Cloud PC has a major outage, Microsoft can spin up a temporary copy of that same Cloud PC - same apps, same settings, same data, up to the last backup point - in a different, geographically separate region, so the user can keep working. This is called a failover. Once Microsoft declares the original region healthy again, the user is automatically moved back to their normal Cloud PC - this is called failback. Microsoft's own documentation is specific about the timing: failback happens automatically within up to 7 days of the region being declared healthy, and that 7-day window is fixed - it can't be extended.
Disaster recovery only applies to Cloud PCs that meet two conditions: the user has a Windows 365 Cross Region Disaster Recovery add-on license, and that user is included in a disaster recovery user setting in the admin center. It is not automatic for every Cloud PC in a tenant, and admins activate and deactivate it manually - it's an emergency response tool for genuine outages, not something that runs continuously in the background.
How to verify: the exact Graph properties, and the one header you'll forget
Three things on the cloudPC resource carry the DR signal, and they live in the Microsoft Graph beta endpoint - this feature is not yet in the stable v1.0 API, so every request below needs https://graph.microsoft.com/beta/..., not /v1.0/....
| Property | Type | What it tells you |
|---|---|---|
isDisasterRecoveryActive | Boolean | true if this Cloud PC is currently running in its disaster recovery region right now, after a failover |
status = failoverInProgress | Enum value | The move to the DR region is actively happening - not finished yet |
status = failbackInProgress | Enum value | The move back to the primary region is actively happening, after the outage was resolved |
There's also a separate, related property worth knowing: disasterRecoveryCapability, an object containing primaryRegion, secondaryRegion, and capabilityType. This tells you whether a Cloud PC is set up for DR at all and which two regions it moves between - independent of whether a failover is happening right now.
That command lists every Cloud PC that has disaster recovery capability configured at all - useful as a first check, since a Cloud PC with no capability configured will never show a meaningful isDisasterRecoveryActive value (it defaults to null, meaning the setting is disabled, not "false" in the sense of "healthy").
failoverInProgress and failbackInProgress are documented as evolvable enum members - Microsoft's term for new enum values that aren't returned by default, to avoid breaking existing code that wasn't written to expect them. If you query status without doing anything extra, a Cloud PC mid-failover may come back with a generic value instead of the specific one you actually want. You must add the header Prefer: include-unknown-enum-members to the request to guarantee you see failoverInProgress and failbackInProgress when they occur. Skip this header and your monitoring script can silently miss the exact event it was built to catch.The equivalent raw REST call, with the header that matters:
Permission-wise, this is a single, narrow scope: CloudPC.Read.All, available as either a delegated permission (signed-in admin) or an application permission (for an unattended script or Azure Automation runbook). There is no separate "DR-specific" permission - if your app or script already has read access to Cloud PCs for any other reason, it already has what it needs for this.
The fix: a PowerShell script that reports every Cloud PC in DR
Rather than running the query above by hand every time someone asks "are we in a DR event right now," wrap it into a script that checks the whole tenant and flags anything currently failed over, mid-failover, or mid-failback.
- In the Entra admin center, register an app (or use an existing automation identity) and grant it the CloudPC.Read.All application permission, with admin consent.
- Install the beta Graph PowerShell module if it isn't already present:
Install-Module Microsoft.Graph.Beta.DeviceManagement.Administration -Scope CurrentUser. - Authenticate - interactively for a one-off check (
Connect-MgGraph -Scopes "CloudPC.Read.All"), or with the app's certificate/secret for a scheduled job. - Run
Get-CloudPCDisasterRecoveryStatus.ps1(below). It queries every Cloud PC, applies thePreferheader so the new status values actually show up, and reports anything currently infailoverInProgress,failbackInProgress, or withisDisasterRecoveryActiveset totrue. - Schedule it (Azure Automation, a scheduled task, or an Intune platform script pointed at a management workstation) to run every 15-30 minutes during business hours, and wire its non-zero exit code into whatever alerting your team already uses.
isDisasterRecoveryActive = true for several days without an active failoverInProgress/failbackInProgress status isn't stuck - it's simply mid-way through that window. Use the script's summary count to track how many Cloud PCs are currently affected, not to chase an individual device that "should" have failed back already.Script for this post is in Daily-Tasks. Download and run it directly - no sign-in required. It is read-only (Graph GET requests only) and makes no changes to any Cloud PC; validate it in your own environment before scheduling it.
Proof it worked
Disaster recovery is an opt-in add-on that most tenants only have active on a small subset of licensed users, and only during a genuine or test failover - it isn't something you can trigger on demand to capture a live example safely. The output below shows the script's real field names and structure exactly as Microsoft documents them, with illustrative values standing in for an actual DR event rather than a real tenant's data.
Read it the same way the script's summary line reads it: Finance-CloudPC-014 is still moving to its backup region right now (failoverInProgress) - not finished yet. Finance-CloudPC-021 has already completed its move: its status has settled back to the normal provisioned value, but isDisasterRecoveryActive stays true, which is exactly why that property exists - the transient status values only catch the few minutes a move is actively happening, while isDisasterRecoveryActive tells you the ongoing fact that a device is currently living in its backup region, for as long as that remains true.
References
- What's new in Microsoft Graph - the September 2026 entry confirming
isDisasterRecoveryActiveand the newstatusvalues. - cloudPC resource type - Microsoft Graph beta - the full property list, including
isDisasterRecoveryActive,disasterRecoveryCapability, and everystatusenum value. - Cross region disaster recovery in Windows 365 - licensing requirements, RTO/RPO targets, and the fixed 7-day failback window.
- List cloudPCs - Microsoft Graph beta - the exact request syntax and permission scopes used in this post.