How to develop an MAUI/Xamarin app with MDM support (including Intune example)

The article is a guide on developing and testing mobile apps with MDM support, which allows remote configuration of the apps by administrators.

How to develop an MAUI/Xamarin app with MDM support (including Intune example)

What is MDM and why Intune?

Mobile device management involves administering a large fleet of mobile devices, including smartphones, tablet computers, and laptops. You can deliver settings, apps, and certificates to end devices with MDM. There are various types of MDM solutions available, but I opted for Microsoft Intune as part of the Microsoft tech stack, which should be familiar to .NET developers and Azure IT experts. Additionally, it offers a trial period for us to test our app. It's worth noting that our current approach is compatible with any third-party MDM solution, such as SOTI, Citrix, Blackberry, and more.

Let's start right away with the source code for the demo app. You can find it through the following link.

How to develop an MAUI/Xamarin app with MDM support (including Intune example)

The primary purpose of MDM support is to deliver configurations to the app, known as Managed configuration. Each platform has a slightly different approach for obtaining data from MDM and testing it. We use MAUI as a basic implementation, but on Xamarin Forms, everything works similarly. This concept also applies to all native apps, so you can explore it even if you are unfamiliar with Xamarin or MAUI.

Implementation

Let's review the basic implementation. I've divided the implementation into several files and placed them on each platform. Hopefully, this will make it easier to copy the code to older Xamarin projects. While you can specify many managed configurations, for simplicity's sake, I've only created one. Here's a shared manager class that allows us to read the managed configuration by its key.

namespace MauiApp1
{
    public partial class ManagedConfigurationProvider
    {
        public partial string GetStringValue(string key);
    }
}

github.com/JTOne123/XAM-MDM/blob/b815a7c5f5..

Android

The foundation of the Android implementation is the RestrictionsManager. To begin, we must define our app's remote configuration options by including the next element in our manifest's <application> element.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    <application android:allowBackup="true" android:icon="@mipmap/appicon" android:roundIcon="@mipmap/appicon_round" android:supportsRtl="true">
        <meta-data android:name="android.content.APP_RESTRICTIONS" android:resource="@xml/app_restrictions" />
    </application>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />
</manifest>

github.com/JTOne123/XAM-MDM/blob/b815a7c5f5..

Then describe the main details of the restriction.

<?xml version="1.0" encoding="utf-8"?>
<restrictions xmlns:android="http://schemas.android.com/apk/res/android">
    <restriction
        android:title="@string/MyMDMConfigKey"
        android:key="MyMDMConfigKey"
        android:restrictionType="string"
        android:defaultValue=""/>
</restrictions>

github.com/JTOne123/XAM-MDM/blob/b815a7c5f5..

Next, retrieve the system service and read a value from the bundle.

using Android.Content;

namespace MauiApp1
{
    public partial class ManagedConfigurationProvider
    {
        public partial string GetStringValue(string key)
        {
            var manager = (RestrictionsManager)Platform.AppContext.GetSystemService(Context.RestrictionsService);
            var bundle = manager.ApplicationRestrictions;

            if (bundle != null)
            {
                if (bundle.ContainsKey(key))
                    return bundle.GetString(key);
                else
                    return null;
            }

            return null;
        }
    }
}

github.com/JTOne123/XAM-MDM/blob/b815a7c5f5..

For more information, please refer to the following link.

iOS

For iOS, the process is much simpler: we need to retrieve a specific dictionary from the user preferences. That's all there is to it.

using Foundation;

namespace MauiApp1
{
    public partial class ManagedConfigurationProvider
    {
        public const string MangedConfigurationKey = "com.apple.configuration.managed";

        public partial string GetStringValue(string key)
        {
            var dic = NSUserDefaults.StandardUserDefaults.DictionaryForKey(MangedConfigurationKey);
            if (dic != null)
            {
                NSObject value = null;
                if (dic.TryGetValue(new NSString(key), out value) && value != null)
                    return value.ToString();
            }

            return null;
        }
    }
}

github.com/JTOne123/XAM-MDM/blob/b815a7c5f5..

For more information, please see the following link.

UWP

The same applies to UWP as well.

using Windows.Storage;

namespace MauiApp1
{
    public partial class ManagedConfigurationProvider
    {
        public const string MangedConfigurationKey = "Managed.App.Settings";

        public partial string GetStringValue(string key)
        {
            ApplicationDataContainer container = null;
            if (ApplicationData.Current.LocalSettings.Containers.TryGetValue(MangedConfigurationKey, out container))
            {
                object value = null;
                if (container.Values.TryGetValue(key, out value) && value != null)
                    return value.ToString();
            }

            return null;
        }
    }
}

github.com/JTOne123/XAM-MDM/blob/b815a7c5f5..

To learn more, please refer to the following link.

Testing

This section will discuss how to test our code locally without publishing the app to app stores. Although the implementations are simple, testing is crucial to ensure the quality of the code. Let's take a look at the available options for testing.

Android

To test the Android app locally, Google recommends using their TestDPC app. To begin, install the app and enroll the device. Then select your app and apply managed settings.

iOS

For iOS, you can easily set user preferences using the xcrun command in your terminal and test it with a simulator. Use the following commands to set or remove preferences:

To set

xcrun simctl spawn booted defaults write com.pavlodatsiuk.xammdm com.apple.configuration.managed -dict 'key1' 'VALUE1'

To remove

xcrun simctl spawn booted defaults delete com.pavlodatsiuk.xammdm

UWP

Unfortunately, there is no straightforward approach for delivering settings locally for UWP. However, you can build a local package and deliver it with Intune along with its settings. So, let's move on to the next section of this article right away.

Intune

Let's log in to our Intune portal using the following link. Please note that you must have an Azure AD Premium P2 license or trial, and you can obtain a free trial on the Azure portal.

I want to explain how to install apps from app stores as the primary source. So, before proceeding with this article, it is generally required that you publish your app on official stores to make it available in the stores for Intune. However, we will make an exception for Windows and deploy the app to test our implementation before releasing it to the Microsoft Store.

To configure everything for your apps, we will switch between two primary tabs on the left side of the Intune website: Apps and Devices.

intune website left tabs

The overall configuration requires three main steps:

  1. Add an app from the store.
  2. Select assignments for users.
  3. Set up managed configuration.

Prerequisites

  1. Microsoft Endpoint Manager admin center
  2. Azure AD Premium P2 license (or trial)
  3. Azure Active Directory

Android

To add your app, go to the Apps section and select Android. Then, click on the Add button. Choose "Managed Google Play app" as the app type. You must log in to your Google Play account using your credentials, and you need to do this once. After logging in, find your app in the window that appears. Click on the "Approve" button, followed by the "Sync" button. new android app

Once you have added your app, you must assign it to end users or end devices. For testing purposes, you can assign it to everyone. assigment

The final step is to configure your app's managed settings. Go to the Apps tab and select "App Configuration policies" followed by "Managed devices". android configuration

Then select the platform, profile, and the app itself. In our case, it should be Android Enterprise or iOS/iPadOS for iOS. We must select your managed configuration and permission if required on the next screen. android configuration

That's it! You need to wait for the changes to take effect. If you want to speed up the process, you can force the changes by clicking on the "Sync" button under Devices -> Android -> Android devices -> Your devices.

iOS

The configuration process for the iOS app is nearly identical to that of the Android. Please refer to the Android section above for guidance. The only difference lies in adding the Apple MDM Push certificate under the Devices tab. To upload the certificate, simply follow the instructions provided on the Apple Push Certificates Portal webpage. Additional information can be found at the following link. ios mdm push certificate Once the MDM push certificate has been added, return to the Apps tab, and proceed with the app configuration process. To add a new app, click on the Add button located in the Apps -> iOS store app, and follow the same steps as for Android.

UWP

There are a few points regarding the UWP app that I would like to highlight:

  1. We intend to distribute the app package for testing purposes.
  2. The app can also be installed from the Microsoft Store, like how it was set up for Android and iOS.
  3. The process for configuring managed settings is notably different.

The local app package for testing

To deliver an app packaged in an msixbundle, please follow these steps:

  1. Go to the "Apps" tab.
  2. Click the "Add" button.
  3. Select "Other/Line-of-business app."
  4. Upload the app package.
  5. Sync the device.

line-of-business app

Please be aware that the installation process may fail if you have not installed a test certificate that is automatically included in the app package. To avoid this issue, install the certificate in the Trusted People certificate store. For more information, please refer to the link provided. You can either manually install the certificate or deliver the root certificate with Intune to the end device.

From Microsoft Store

Another option for setting up Windows apps is similar to Android, which involves selecting an app from the Microsoft Store. To do this, go to the "Apps" tab and click the "Add" button. Then, select the "Microsoft Store app (new)" option and choose the desired app.

When configuring the app, make sure to specify assignments to user groups or devices, as it is a required step. So, don't forget to complete this step.

Managed configuration

As mentioned, delivering managed configuration to the Windows app requires a slightly different approach. To deliver managed configuration for Windows apps, you must follow a slightly different approach. First, go to the "Devices" section and select "Windows" to view your Windows devices. Then, move to the "Configuration Profiles" section and create the "Custom" profile using templates for the Windows 10 platform. windows configuration profiles

Define a name for the profile and click "Next". In the "Configuration settings" step, add a new OMA-URI setting and fill in all necessary fields. Enter ./User/Vendor/MSFT/EnterpriseModernAppManagement/AppManagement/AppStore/maui-package-name-placeholder_9zz4h110yvjzm/AppSettingPolicy/MyMDMConfigKey in the OMA-URI field, where maui-package-name-placeholder_9zz4h110yvjzm refers to the package family name and MyMDMConfigKey is the managed configuration name defined in your code. uwp managed configuration uwp package family name

Finally, proceed to the subsequent steps and assign the relevant user groups. Sync your device and wait for the delivery of the configuration.

End Devices Enrollment

First, you must enroll your end devices by installing the Intune Company Portal app and logging in to your account. This account consists of a list of users defined in your AAD. All other configurations for your end devices can be completed through the Intune website.

In conclusion, I hope this article has provided more clarity than confusion. Please follow me for exciting future reads.

Did you find this article valuable?

Support Pavlo Datsiuk by becoming a sponsor. Any amount is appreciated!