As a broad and deep platform, Microsoft 365 can be challenging to enforce appropriate technical change management on. The sheer number of configuration options available is staggering when you take into account each workload on offer, not to mention settings that impact across multiple workloads like SharePoint configuration impacting Teams functionality. This isn’t helped by the fact that a true configuration level backup service for Microsoft 365 doesn’t exist.

As a result, making changes to any configuration item in Microsoft 365 can be very difficult to test and quite onerous to track and revert. Alerting can be configured for certain changes and some aspects like the Microsoft Defender for Office 365 Configuration Analyzer can help detect configuration skew over time but this doesn’t extend to the rest of the platform.

Microsoft 365 Desired State Configuration

To fill the gap of an effective “snapshot” of Microsoft 365 configuration, a lot of organizations have turned to configuration as code. The basic principle here is that the desired state configuration (DSC) of the tenancy is scripted to ensure that it can be reverted to an agreed baseline by rerunning the script against the environment. DSC isn’t a new concept and has been used in many other technologies throughout the years, however Microsoft 365 DSC leverages DSC to help solve the tenancy configuration challenge.

Microsoft 365 DSC is an open source, Microsoft lead, community driven project which allows for extraction, comparison and even remediation of configuration within a Microsoft 365 tenancy or even across multiple tenancies. In this article, I’ll detail how it can be used to “snapshot” your tenancy configuration and then compare this snapshot against and updated configuration to detect changes in the environment.

Prepare an Azure AD App

To secure authentication to resources, you will need register a new Azure AD app. While the module does allow passing user credentials directly, this can be tricky in secure environments, so all components of the DSC module are being upgraded to leverage the Microsoft Graph PowerS hell SDK module under the hood.

Create a new Azure AD app registration (as I did in this article) and take note of the Tenant ID, Client IP and Client Secret (for production use I recommend using Certificate authentication but Client Secret works fine for testing).

Next, to grant permissions to the app, check the documentation for the associated resources you would like to include. For example, I’ll add the application permissions for Conditional Access – “AADConditionalAccessPolicy” (Figure 1), don’t forget to grant consent on the permissions once they are added. For export, you only need the permissions listed under “Export”, if you want to automate remediation (which I won’t go into here) then you will need the permissions listed under “Automate.”

Add permissions for each resource you want to include
Figure 1: Add permissions for each resource you want to include

For larger sets of resources, the DSC module which is detailed below contains the cmdlet Get-M365DSCCompiledPermissionList which can be passed a list of resources and returns the required permissions:

Get-M365DSCCompiledPermissionList -ResourceNameList @('AADConditionalAccessPolicy')  

Install the Microsoft 365DSC module

Microsoft 365 DSC comes in the form of a simple PowerShell module. To get started, open up a PowerShell session and run the command:

Install-Module -Name Microsoft365DSC

This might take a little while as it will need to download a lot of dependencies to allow the DSC module to do its job.

Extract a Configuration

To extract a configuration, run the Export-M365DSCConfiguration cmdlet, passing in the resources you want to extract, along with the app details as shown in Figure 2.

Export-M365DSCConfiguration -Components @(<Component List>) -ApplicationId <AppID> -TenantId <TenantName>  -ApplicationSecret <AppSecret> -Path <Path for Export> -ConfigurationName  <Configuration Name> -FileName <Name of export file .ps1>

Run the Export-M365Configuration cmdlet to export configuration details
Figure 2: Run the Export-M365Configuration cmdlet to export configuration details

This will export the configuration to the specified path as a DSC configuration .PS1 file. In the file you will see the details of the exported configuration for the specified resources, in this case, Conditional Access policies however there are a lot more options available. You can even use the web-based export tool to generate your export command for you, selecting the resources and workloads you want to include.

Create a configuration report

The PS1 Configuration file exported by DSC isn’t a very user friendly way of reviewing the tenant config. The configuration can be exported to Excel or HTML format by using the New-M365DSCReportFromConfiguration cmdlet (Figure 3).

Generating a report from a configuration
Figure 3: Generating a report from a configuration

The exported configuration will be exported in a much easier to read format (Figure 4).

HTML and Excel export files for configurations
FIgure 4: HTML and Excel export files for configurations

Compare configurations

Reporting is great but the exported configuration can also be compared to the current configuration to identify any changes since the original export. To generate a comparison, make some changes to Conditional Access and then run the export again specifying a different file name. This will generate another file with the latest configuration in the same folder.

The files can then be compared by running the New-M365DSCDeltaReport cmdlet, specifying the source (Initial), destination (Updated) configurations and an output path for the resulting HTML file. The syntax of the command is shown below:

New-M365DSCDeltaReport -Source 'C:\DSC\UpdatedConfig.ps1' -Destination 'C:\DSC\InitialConfig.ps1' -OutputPath 'C:\dsc\Delta.html'

The command generates the HTML delta report shown in Figure 5. This report highlights any missing, additional, or different components detected in the comparison.

The delta report highlights any discrepancies between configurations
Figure 5: The delta report highlights any discrepancies between configurations

In this example, the delta report shows that the Conditional Access Policy “Teams via MCAS” is no longer present and the “IncludeApplications” setting on the policy “MFA” has been modified from “All” to a single application.

More than just comparison

Reporting and comparison are only the beginning of the possibilities with Microsoft 365 DSC. The real value comes by expanding on this concept out to have regular consistency checks and even automated remediation of configuration drift. DSC can also be useful for cloning tenancies for testing. It can even be deployed to containers, Azure Automation and Azure DevOps to enhance the governance, deployment, and update of configurations. For more information on Microsoft 365 DSC, check out the project website here.

About the Author

Sean McAvinue

Sean McAvinue is a Microsoft MVP in Office Development and has been working with Microsoft Technologies for more than 10 years. As Modern Workplace Practice Lead at Ergo Group, he helps customers with planning, deploying and maximizing the many benefits of Microsoft 365 with a focus on security and automation. With a passion for creative problem solving, he enjoys developing solutions for business requirements by leveraging new technologies or by extending the built-in functionality with automation. Blogs frequently at https://seanmcavinue.net and loves sharing and collaborating with the community. To reach out to Sean, you can find him on Twitter at @sean_mcavinue

Comments

  1. Ricardo Silva

    For Conditional Access that uses TermsofUse PowerShell asked for the required roles: Agreement.Read.All, Agreement.ReadWrite.All

    I had to run the following order to get it working.

    Run Powershell as administrator
    Install-Module Microsoft.Graph
    Install-Module Microsoft365Dsc
    Update-M365DSCDependencies -Force
    Update-M365DSCAllowedGraphScopes -ResourceNameList @(“AADConditionalAccessPolicy”) -Type ‘Read’

  2. Ricardo Silva

    For Conditional Access that uses TermsofUse PowerShell asked for the required roles: Agreement.Read.All, Agreement.ReadWrite.All

    I had to run the following order to get it working.

    Run Powershell as administrator
    Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force
    Install-Module Microsoft.Graph
    Install-Module Microsoft365Dsc
    Update-M365DSCDependencies -Force
    Update-M365DSCAllowedGraphScopes -ResourceNameList @(“AADConditionalAccessPolicy”) -Type ‘Read’

    # Getting application information for Application + Secret authentication
    $ApplicationId = Read-Host -Prompt ‘Application Id’
    $ApplicationSecret = Read-Host -Prompt ‘Application Secret’
    $TenantId = Read-Host -Prompt ‘Tenant Id’

    # Exporting resources using application
    Export-M365DSCConfiguration -Components @(“AADConditionalAccessPolicy”) -ApplicationId $ApplicationId -ApplicationSecret $ApplicationSecret -TenantId $TenantId

  3. Ron

    Nice article, but it’s just the tip of the proverbial iceberg. The Help documentation on the M365DSC website is pretty poor as well, as it’s all over the place and not in the order it should be following considering I’ve just attempted to do a tenant to tenant config change – unsuccessfully so far. I’m stuck at the import stage, which you didn’t mention here. Any clues?

    1. Tony Arnill

      Interested, wish there was a recording of the event and not just a powerpoint

Leave a Reply