//

Modify Azure AD tenant settings with Graph in C#

6 mins read

This might come in handy if you want to create an app or dashboard where admins should be able to modify these tenant settings via a UI. As those settings are only available through Powershell at the moment. First we should create an Azure AD app for authentication to Graph. You could also achieve this with user credentials, but if you’ll ever need this. It’s probably best practice to create an Azure AD app.

Create Azure AD App for authentication

1. Check out my previous blog post how to create an Azure AD app. A Redirect URI does not need to be set for the purpose of authenticatin a GraphServiceClient.

2. Give the Azure AD app permissions to modify the Tenant settings. If you ask yourself where you can find the required permissions. The official docs of Microsoft are a very good reference for all Graph calls to check this information. In this case we are doing an App-only authentication, so we should look at the Application permissions.

3. Generate a client secret for our Azure AD app.

4. Copy the client secret value right after it is created. Because it will be hidden after refreshing your page once. Get the Client ID of your Azure AD app and client secret key you just created. Now we can move onto the next step.

Install Microsoft.Graph.Beta NuGet

To install the Beta Graph SDK for C# you should run the following command in the Package Manager Console.

Install-Package Microsoft.Graph.Beta -Version 0.12.0-preview

Check the official NuGet page for the latest version of the Microsoft.Graph.Beta here.

If you are not able to use the Graph Beta reference yet you might be using the Graph v1.0 aside of the Beta. Read this to fix the issue when you are using both together in one project.

Create GraphServiceClient with app-only auth

extern alias BetaLib;

using Beta = BetaLib.Microsoft.Graph;

public static class Authentication
{
    private static AuthenticationContext GetAuthenticationContext()
    {
        //you can find your tenant name in the Azure AD - Overview tab in the Azure portal
        var tenant = "tenant.onmicrosoft.com"
        var authString = $"https://login.microsoftonline.com/{tenant}";

        return new AuthenticationContext(authString);
    }
    
    public static Beta.GraphServiceClient CreateGraphServiceClient()
    {
        var AuthContext = GetAuthenticationContext();
        string accessToken = AuthContext.AcquireTokenAsync("https://graph.microsoft.com", new ClientCredential("ClientID", "ClientSecret")).Result.AccessToken;
        Beta.GraphServiceClient client = new Beta.GraphServiceClient("https://graph.microsoft.com/beta", new DelegateAuthenticationProvider(
            (requestMessage) =>
            {
                requestMessage.Headers.Authorization = new AuthenticationHeaderValue("bearer", accessToken);

                return Task.FromResult(0);
            }));
        return client;
    }
}

We can now call Authentication.CreateGraphServiceClient() to get an authenticated Beta graph client in C#.

Modify tenant settings using the Graph beta endpoint

Note: The setting we will apply in the code snippet below will disable all group creation tenant wide. This will also disable people from creating Teams and more.

extern alias BetaLib;

using Beta = BetaLib.Microsoft.Graph;

var newSettings = new Beta.DirectorySetting()
{
    Values = new List<Beta.SettingValue>()
    {
        //Here we set the new values for the tenant settings. We will now disable group creation tenant wide
        new Beta.SettingValue() {
            Name = "EnableGroupCreation", 
            Value = "False"
        }
    }
};

var betaGraphClient = Authentication.CreateGraphServiceClient();
var currentSettings = await betaGraphClient.Settings.Request().GetAsync();
Beta.DirectorySetting settingToUpdate = null;

foreach (var setting in currentSettings)
{
    if (setting.Values.Count() > 0 && setting.TemplateId == "62375ab9-6b52-47ed-826b-58e47e0e304b")
    {
        settingToUpdate = setting;
        break;
    }
}

if (settingToUpdate != null)
{
    //UPDATE (PATCH)
    foreach (var newValue in newSettings.Values)
    {
        if (settingToUpdate.Values.Where(x => x.Name == newValue.Name).FirstOrDefault() == null)
        {
            var listValues = settingToUpdate.Values.ToList();
            listValues.Add(new Beta.SettingValue()
            {
                Name = newValue.Name,
                Value = newValue.Value
            });
            settingToUpdate.Values = listValues;
        }
        else
        {
            settingToUpdate.Values.Where(x => x.Name == newValue.Name).First().Value = newValue.Value;
        }
    }

    var updateTrigger = await betaGraphClient.Settings[settingToUpdate.Id].Request().UpdateAsync(settingToUpdate);
}
else
{
    var directorySettingsTemplate = await betaGraphClient.DirectorySettingTemplates[Helpers.DirectoryTemplates.TenantConfigTemplateId].Request().GetAsync();

    var settingList = new List<Beta.SettingValue>();

    foreach (var settingTemplateValue in directorySettingsTemplate.Values)
    {
        settingList.Add(new Beta.SettingValue()
        {
            Name = settingTemplateValue.Name,
            Value = settingTemplateValue.DefaultValue
        });
    }

    for(int i = 0; i < settingList.Count; i++)
    {
        var newSetting = newSettings.Values.Where(x => x.Name.ToLower() == settingList[i].Name.ToLower()).FirstOrDefault();
        if (newSetting != null)
        {
            settingList[i].Value = (newSetting.Value != null && newSetting.Value != "") ? newSetting.Value : settingList[i].Value;
        }
    }

    //CREATE new setting (POST)
    var newDirectorySetting = new Beta.DirectorySetting()
    {
        TemplateId = Helpers.DirectoryTemplates.TenantConfigTemplateId,
        Values = settingList
    };

    settingToUpdate = await betaGraphClient.Settings.Request().AddAsync(newDirectorySetting);
}

For more information on the tenant wide settings that you can modify. Do a GET call to this URI in the Graph Explorer. https://graph.microsoft.com/beta/directorySettingTemplates/62375ab9-6b52-47ed-826b-58e47e0e304b

This directorySettingTemplate will list all the available setting values with a short description about what the setting does.

Leave a Reply

Your email address will not be published.

Previous Story

Setup, test and debug an Azure AD protected Web API - ASP.NET

Next Story

Convert SharePoint files (Word, Excel, PowerPoint, ...) to PDF in .NET using Microsoft Graph