Microsoft 365 Desired State Configuration: The Practical Guide to Keeping Your Tenant in Check
If you’ve ever tried to keep a Microsoft 365 tenant consistent over time, you already know it can feel a bit like trying to nail jelly to a wall.
New features roll out constantly, admins make manual changes in the portal, policies evolve, and suddenly your production, test, and dev environments don’t really look alike anymore. Security settings drift, Teams policies become inconsistent, and no one is entirely sure which configuration is the “real” one.
That’s exactly the kind of chaos Microsoft 365 Desired State Configuration (M365 DSC) is designed to solve.
In this article, we’ll break down what Microsoft 365 Desired State Configuration is, how it works under the hood, and how you can actually use it to:
- Represent your entire Microsoft 365 tenant as code
- Automate deployments and configuration changes
- Detect and repair configuration drift
- Clone configurations between tenants (for example, prod → dev)
- Generate reports and assessments to understand what’s really going on
To be honest, once you see it in action, it’s hard to go back to clicking around in admin centers as your primary way of managing configuration.
What Is Microsoft 365 Desired State Configuration (M365 DSC)?
Microsoft 365 Desired State Configuration (often shortened to M365 DSC) is an open-source PowerShell module that lets you define your Microsoft 365 tenant configuration as code.
Instead of configuring everything manually through various admin portals (Azure AD, Teams admin center, Exchange admin center, SharePoint, etc.), you describe the desired state of those settings in a configuration file. DSC then:
1. Applies that configuration to your tenant, and
2. Continuously checks that your tenant stays in that desired state.
It’s built on top of PowerShell Desired State Configuration (DSC), a feature introduced in Windows PowerShell 4.0 and supported in PowerShell 5.1 and PowerShell 7+. The Microsoft 365 flavor simply extends that idea to cloud configuration rather than just servers.
### How M365 DSC Works Under the Hood
PowerShell, Graph, and Workload Modules
Under the covers, Microsoft 365 Desired State Configuration uses a mix of:
- PowerShell DSC – The core engine for defining, testing, and applying configuration
- Microsoft Graph PowerShell SDK – To talk to Microsoft 365 workloads via Microsoft Graph
- Workload-specific modules, for example:
- PnP PowerShell for SharePoint Online
- Exchange Online Management Shell for Exchange Online
- Other Microsoft 365 and Azure AD modules as needed
The M365 DSC module itself is published to the PowerShell Gallery, so installing it is as simple as:
```powershell
Install-Module Microsoft365DSC
```
(Or `Install-Module Microsoft365DSC -Scope CurrentUser` if you don’t have admin rights.)
That one command pulls down M365 DSC and all the required dependencies and Graph modules. After that, you’re ready to start exporting configuration from an existing tenant or defining your own from scratch.
Configuration as Code: What It Actually Looks Like
In practice, a Microsoft 365 DSC configuration file is a PowerShell DSC configuration that uses M365 DSC resources. It looks a bit like JSON at first glance, but it’s really PowerShell DSC syntax.
Here’s a simplified example of what defining a Teams meeting policy might look like conceptually (this is not an exact snippet from the transcript, but reflects the idea):
```powershell
TeamsMeetingPolicy "DemoMeetingPolicy"
{
Identity = "Demo Meeting Policy"
AllowAnonymousUsersToStartMeeting = $false
Ensure = "Present"
}
```
When this configuration runs, M365 DSC will:
1. Connect to your tenant
2. Check if a Teams meeting policy named “Demo Meeting Policy” exists
3. If it does not exist → create it with the specified settings
4. If it does exist → update its settings to match the desired state
You can also tell it that something must not exist. For example, to make sure a certain policy can never live in your tenant, you can set:
```powershell
Ensure = "Absent"
```
That way, if someone creates it manually, DSC will detect it and, depending on your mode, either report it or remove it.
Key Capabilities of Microsoft 365 Desired State Configuration
The transcript breaks down M365 DSC around a few core pillars. Let’s walk through the important ones in practical terms.
1. Automation: Consistent, Repeatable Deployments
The most obvious benefit is automation.
With M365 DSC you can define multiple workloads in a single configuration: Azure AD, Teams, Exchange Online, SharePoint, Intune, Security & Compliance, Planner, OneDrive, licensing, and more (the transcript mentions roughly 140 macro components supported at the time).
A single configuration file might define things like:
- Azure AD app registrations and their Graph permissions
- Teams calling and meeting policies
- Exchange organization settings
- SharePoint configuration
- Security and compliance policies
- Intune settings
To give you a concrete scenario:
- You define an Azure AD application called `Nick Demo App` with delegated permission `User.Read` and application permission `Channel.Create` via Microsoft Graph.
- In the same configuration, you define a custom Teams calling policy named `Nick Calling Policy` with a specific set of flags (e.g., voicemail, forwarding, delegation settings, etc.).
Run the configuration and DSC will go off and create or update both: the Azure AD app (including permissions) and the Teams calling policy. No more copy‑pasting settings across tenants or trying to remember what you set in the GUI last time.
In my experience, this is where most teams first see the “DevOps for Microsoft 365” lightbulb go off. You stop treating portal clicks as a configuration strategy and start treating code as the source of truth.
2. Snapshot and Export: Capture Your Current Tenant
One of the surprisingly powerful features of M365 DSC is the ability to export a current tenant’s configuration into a DSC file.
Once you’ve installed the module, you can use:
```powershell
Export-M365DSCConfiguration
```
This launches a graphical export tool where you:
1. See a list of all available M365 DSC resources
2. Pick and choose what you want to export (for example: Azure AD applications, Exchange org settings, Teams policies)
3. Generate the PowerShell command needed for the export
4. Run that command to output a `.ps1` DSC configuration file
In other words, you don’t need to write every configuration file by hand. You can:
- Start with an existing tenant
- Take a snapshot of its configuration
- Use the generated file as your baseline, then tweak it
This is great if you’re coming to DSC a bit late and your environment already exists (which, let’s be honest, is almost always the case).
3. Cloning Tenants: Dev, Test, and Mergers
Cloning tenant configuration is one of the most useful real‑world scenarios.
Many organizations want a dev tenant that looks like production, at least from a configuration perspective, without copying all user data.
Here’s how people generally do it with M365 DSC:
1. Export the configuration from Production using `Export-M365DSCConfiguration`.
2. Adjust anything that must differ (like domain names, environment‑specific settings, etc.).
3. Apply that configuration to the Dev tenant.
Now Dev is effectively a clone of Prod’s configuration.
The same approach works for tenant-to-tenant migrations or mergers. You can:
- Export Tenant A configuration
- Export Tenant B configuration
- Use the assessment/delta features (we’ll touch on that later) to see what’s different
- Decide which tenant’s config becomes the “gold standard” and deploy accordingly
This is much cleaner than clicking around two portals trying to visually compare pages and toggles.
Preventing and Detecting Configuration Drift
Defining and deploying configuration is only half the story. The real magic of Desired State Configuration is making sure things stay that way.
Microsoft 365 DSC uses the underlying DSC engine to routinely test your tenant against the desired configuration and detect drift.
How Drift Detection Works
Behind the scenes, DSC uses something called the Local Configuration Manager (LCM). Even though the name sounds very on-premises, the concept works similarly for cloud configuration.
The LCM periodically runs a method called `Test-DSCConfiguration`:
1. Connect to your tenant
2. Pull the current state of the resources defined in your configuration
3. Compare that with the desired state in your DSC file
4. Report where there are mismatches (drifts)
In the Teams calling policy example from the transcript, the demo intentionally introduced a drift:
- The desired configuration said a setting (like `AllowDelegation`) should be `True`.
- Someone changed it manually in the Teams admin center to `False`.
When `Test-DSCConfiguration` ran, M365 DSC reported:
- Which resource drifted (the specific Teams calling policy)
- Which property drifted (e.g., `AllowDelegation`)
- The current value (`False`)
- The desired value (`True`)
So you don’t just get a vague “something is wrong” result; you get a clear, targeted description of exactly what is off.
Apply and Monitor vs. Apply and Autocorrect
You can tune how aggressive DSC should be in enforcing configuration. Broadly, there are two main modes (simplifying a bit for clarity):
1. Apply and Monitor
- DSC checks for drift
- Logs discrepancies (for example, into Event Viewer or pipeline logs)
- Does not automatically fix them
2. Apply and Autocorrect
- DSC checks for drift
- If it finds a mismatch, it automatically reapplies the desired configuration
- In effect, it “self-heals” your environment
You don’t have to pick one global behavior for everything. One of the strengths of M365 DSC is you can slice and dice by workload:
- For something like SharePoint team sites, you might only want drift reported, not auto-fixed, because changes there can be more nuanced.
- For Security & Compliance settings, you may want strict auto-correction, plus notifications, because the risk of misconfiguration is much higher.
A common real-world pattern is:
- Configure DSC to test every 12 hours (for example, 6 AM and 6 PM). The transcript notes that the technical minimum is every 15 minutes, but that’s usually overkill in production.
- Treat security‑sensitive components more strictly than collaboration workloads.
You can also hook the drift detection into external systems:
- Use Azure DevOps release pipelines or scheduled runs
- On drift detection, send email alerts or push notifications
- Call a webhook to open a support ticket or trigger another workflow
To be honest, this is where M365 DSC starts to feel less like a script and more like the backbone of a configuration governance process.
Assessment, Comparison, and Reporting
Beyond deployment and drift control, Microsoft 365 Desired State Configuration includes tools to help you understand your environment better: assessments, comparison reports, and exports to HTML or Excel.
Comparing Two Tenants with Delta Reports
You’re not always starting from scratch. Sometimes you already have two tenants and you simply want to know: what’s different between them?
M365 DSC supports this with a delta report feature. At a high level, the process goes like this:
1. Export a DSC configuration from Tenant A (for example, Prod)
2. Export a DSC configuration from Tenant B (for example, Dev or a merger target)
3. Run:
```powershell
New-M365DSCDeltaReport \
-Source 'ProdConfig.ps1' \
-Destination 'DevConfig.ps1' \
-OutputPath 'DeltaReport.html'
```
Under the hood, M365 DSC parses both configurations into PowerShell objects, then compares them.
The resulting HTML report shows:
- Which components exist in one tenant but not the other (for example, an Exchange malware filter policy present in Dev but missing in Prod)
- Which properties have different values between the two
This kind of side‑by‑side comparison is extremely useful when you’re:
- Preparing for a merger or acquisition
- Auditing configuration drift between Prod and Test
- Trying to align a sandbox environment to match production behavior
Using Your Current Configuration as the New Desired State
One interesting use case from the transcript is organizations who don’t want DSC to immediately start changing things. Instead, they want visibility first.
Their pattern looks like this:
1. Use M365 DSC to get a full snapshot of the current tenant:
- “Tell me how you’re currently configured.”
2. Take that exported configuration and push it right back as the desired state.
3. From that point on, any change (manual or otherwise) to those settings shows up as drift.
This is a clever way to:
- Adopt DSC without forcing a bunch of immediate configuration changes
- Use it initially as a reporting and compliance tool
- Gradually move towards more automated remediation (autocorrect) as your processes mature
It’s essentially saying: “We’re not changing you today. We’re just officially documenting what you are, and from now on, we’ll know when you change.”
HTML and Excel Reports: Putting “Lipstick on the Pig”
The transcript jokingly refers to a feature as “putting lipstick on the pig,” but it’s actually quite useful in practice: converting configurations into human-friendly reports.
M365 DSC can take a configuration file and output:
- An HTML report, or
- An Excel report
The Excel export is usually more practical because you can:
- Filter by workload or resource type
- Sort by property names or values
- Build charts and summaries (for example, all Teams policies, or all Exchange policies)
For governance teams, auditors, or architects who aren’t as comfortable reading DSC configuration code, this is a much easier way to review and discuss how the tenant is set up.
Scaling with Microsoft Graph and Dynamic Resources
One of the big challenges with any tool that manages Microsoft 365 is just keeping up. Microsoft is constantly shipping new features and toggles.
The transcript mentions an important development: a dynamic resource generator that uses Microsoft Graph OpenAPI definitions.
In simple terms:
- Instead of manually creating new DSC resources every time Microsoft adds a new Graph endpoint, M365 DSC can automatically wrap Graph endpoints into DSC resources.
- The rule of thumb becomes: “If it’s on Microsoft Graph (in the management plane), we can likely support it via DSC.”
There is one caveat: M365 DSC focuses on configuration, not data. So for example, it’s not meant for managing individual SharePoint list items or end‑user content. It stays on the config level: policies, settings, objects like apps and policies.
This approach helps ensure Microsoft 365 Desired State Configuration stays relevant as the platform evolves, without the maintainers constantly playing catch‑up by hand.
Documentation and Permissions Awareness
Each supported resource type in M365 DSC comes with documentation that typically includes:
- Which properties are supported
- What those properties mean
- Which permissions (for example, Graph permissions or admin roles) are required to:
- Export configuration
- Apply configuration
This matters quite a bit in real environments because exporting certain security or compliance settings often requires more privileged access. In my experience, having this spelled out saves a lot of trial and error with permission issues during adoption.
Microsoft 365 Desired State Configuration (M365 DSC) brings DevOps-style thinking to Microsoft 365: configuration as code, repeatable deployments, drift detection, and consistent environments across tenants.
Instead of relying on a web of manual changes scattered across Azure AD, Teams, Exchange Online, SharePoint, Intune, and elsewhere, you can:
- Describe your tenant in a single, version-controlled configuration file
- Export your current state to get started without rewriting everything
- Clone or align tenants for dev, test, or mergers
- Detect and optionally auto-correct configuration drift
- Assess and report on differences between environments in a structured way
To be honest, it does require a mindset shift—from “we configure things in portals” to “we treat configuration as code and source of truth.” But once you get through that initial ramp-up, the benefits in control, auditability, and consistency are hard to ignore.
If you’re responsible for a Microsoft 365 environment and you’re feeling the pain of uncontrolled changes or inconsistent tenants, a practical next step is:
1. Install the `Microsoft365DSC` module from the PowerShell Gallery.
2. Run an export of a subset of your tenant (for example, just Teams and Exchange org settings).
3. Review the generated configuration and maybe export it to Excel for easier discussion with your team.
From there, you can decide how far you want to take it—whether as a reporting and drift-detection tool, or as the backbone of a full “configuration as code” strategy for Microsoft 365.

