Microsoft Intune Enterprise App Management Explained

Working in end-user computing, one of the things I consider constantly is the extent to which you need additional products to do the job efficiently. There’s always a trade-off; between the additional cost on the one hand, and the increased functionality or ease of use on the other. Sometimes functionality is absorbed into the core Microsoft product set, and sometimes it remains outside.

Last year, Microsoft introduced the Enterprise App Management (EAM) feature for Intune. This extends app deployment for Windows with a catalog of pre-packaged apps. Up to this point, even the smallest and simplest app needed to be wrapped in a custom intunewin file and configured with deployment parameters. With EAM, you just select an app and assign it.

This article looks at how far the EAM feature goes in meeting enterprise app deployment requirements. Does it replace third-party solutions, or even your app packaging engineers? Let’s take a look.

Enterprise App Management

EAM is a premium add-on to Intune. It provides a catalog with pre-packaged configurations, ready to deploy an app simply by selecting it. It does many of the things an engineer would otherwise need to do:

  • Fetch a current version of the media from the vendor
  • Apply a command line to install and uninstall the app silently
  • Decide on the context: system or user
  • Handle return codes (e.g. soft reboot)
  • Create a detection rule, to determine if the installation was successful, or if the app is already installed.

Common and standard apps

I would guess there are at least 8 to10 apps in any environment where a standard configuration is enough:

  • Browsers, like Chrome and Firefox
  • Videoconference clients, like Zoom and Webex
  • Virtual desktop clients, like Citrix, VMware or AWS
  • The Microsoft Visual C++ Redistributable stack.

There is also often a tail of apps that are either free or enterprise-licensed, like 7-Zip, Notepad++ and Visual Studio Code.

Customisation in EAM

You can apply your own customisations to catalog apps. In this case the catalog at least gives you a start. Most obviously, you can edit the install command. You can also, of course, create a dependency or a custom requirement (to test whether to install or not).

Example

A good example of this is the Citrix Workspace app. Citrix XenServer and NetScaler create a large and complex technical environment, and the Workspace app is the means of access to it. A Citrix user might have: a) different identities, b) different environments to connect to, and c) different functional requirements, like copy/paste or file transfer.

The Intune EAM catalog app gives this command install:

"CitrixWorkspaceApp24.9.10.28.exe" /silent /noreboot /AutoUpdateCheck=disabled

It also gives the uninstall command, to save figuring it out:

"%ProgramFiles(X86)%\Citrix\Citrix Workspace 2409\bootstrapperhelper.exe" /uninstall /cleanup /silent

That performs a basic install and uninstall, obviously. But what is this client going to connect to, and how? For that, you need to understand the whole client configuration in the Citrix Workspace App command-line parameters; which is what a packaging engineer does. So you might, instead, have an install command of:

"CitrixWorkspaceApp24.9.10.28.exe" /silent /noreboot /AutoUpdateCheck=auto /includeSSON

You might also appreciate that the Store the Workspace app connects to can be configured in policy, instead of the installation, which enables you to change it without re-installing. So there is an architecture behind the deployment that needs to be developed and understood before you can deploy the app, even with the EAM catalog.

Limitations

Although you can edit the catalog app, at present you cannot use an MST (transform file), or a script with a catalog app, because there is no facility to upload additional files. However, Microsoft told me in January this year that: “We have a solution in the pipeline for this today. Not much more to say about it for now.” So it looks as though this will be possible in future.

My point in this trivial example is that, even with a catalog app and a standard configuration, you may be able to achieve what you want for a subset of your apps.

Beyond the Catalog

These are fairly simple app deployments. There are two cases where the catalog cannot help you:

  1. Where you need more extensive customisation
  2. Where the app is not in the catalog.

Extensive customisation

Once beyond the collection of simple apps, app deployment expands into a world of great complexity. There have been a few like this in every migration programme I have worked on. Sometimes these are legacy apps. Sometimes they are not legacy, but complex nevertheless.

The open source PSAppDeployToolkit (PSADT) covers several of the more common customisations. Essentially, this adds wrap-around functions to the execution of the command line:

  • Pre or post install scripts
  • Copy or delete files
  • Modify the registry
  • Generate verbose logs

You could write these actions into your own script, but it would get tedious after a while, and you would probably write common functions, just like PSADT.

Then there are installations that need to be interactive. Suppose the app is an update or upgrade, and needs to close the current app? Or suppose it needs to close all Office apps while it installs? PSADT uses an interactive dialogue to do this, including to pause or defer the installation if now is not a convenient time.

Normally, in Intune, this dialog would not be seen because there is no interaction between the system context and the user session. The installation would just time out, waiting for user input. But the ServiceUI.exe utility from the Microsoft Deployment Toolkit (MDT) provides this capability. So PSADT creates a dialogue to prompt the user for input; and ServiceUI surfaces the dialog to the session of the logged on user.

If you needed any of these options, you would wrap the command line in the PSADT template, then package it as an intunewin file and upload it. The install command becomes the command to run the PSADT package, instead of the app command line. PSADT will exit with a return code that Intune will interpret as a result.

In this model, PSADT controls the app install command, and Intune controls the PSADT execution.

The Intune Enterprise App Management feature is not going to be able to do this without a very large enhancement. I have no idea whether Microsoft has this in mind, or is content to leave it as a catalog of fairly simple apps with fairly simple command line installs.

Not in the catalog

Inevitably, there will also be legacy apps or uncommon apps that are not in the EAM catalog. You can see that the Microsoft catalog currently contains mostly free apps or free clients to larger paid-for systems. They say they will add more, and I am sure they will. But, in the meantime, you still need someone to package them. Some apps are unlikely ever to be in a catalog. They may be proprietary, or have a very specialised customer base, or have customisations that are unique to the organisation, or just be very old.

The future of app deployment

So now I go back to my basic question: does it replace third-party solutions, or even your app packaging engineers?

The beginning of app deployment

Right from the beginning, app deployment in Windows had command lines for unattended install. These existed in InstallShield packages, in Windows Installer MSIs and other installers like NSIS (Nullsoft), Inno and WiX Toolset. As a consequence, there was, and is, an ecosystem of open and closed libraries of install commands. As a packager you have three options:

  1. Read the vendor documentation
  2. Deduce the commands from the installer type, or from the /? help
  3. Use a search engine or even AI to find the commands.

Catalogs

It is a small step from there to provide a catalog of pre-packaged apps with standard commands. Altiris did this many years ago for common apps like Adobe Reader, Flash, Java Runtime. These were especially useful in the days before automatic updates, because you really did need to keep updating Flash and Java runtime every time a vulnerability was discovered. Now many vendors offer pre-packaged apps as part of an endpoint management solution. It is really quite easy to offer an app with a standard command line install and uninstall.

But, as you do this, you run into exactly the problems I described above: more complex customisations, and apps not in the catalog.

Two vendors now offer PSADT as part of their app catalog packages: PatchMyPC and Apptimized. That means they can provide an extended range of customisations. PatchMyPC have taken stewardship of PSADT, and played a role in the major upgrade to v4.0 of the toolkit. Both companies offer a large catalog of pre-packaged apps, and a packaging service for custom packages.

It is not my aim to compare Intune Enterprise App Management in detail with other products and vendors like PatchMyPC and Apptimized. I just want to provide some context. In summary, there is a scale of complexity:

  1. Common apps with simple command line installs
  2. More complex but still standard customisations, for example with PSADT
  3. Complex customisations, and legacy or uncommon apps.

Intune Enterprise App Management currently hits Level 1. This gives a rough feature parity with other endpoint management solutions.

PSADT provides the wrapper for a standard set of more complex customisations at Level 2. But you still need to be a fairly experienced packager to use it effectively. Anyone can wrap a command line in a nice PSADT dialogue. The skill is to know what needs to be customised and how best to do it; registry, policy, file, script? PatchMyPC and Apptimized have products that do this as a service. Either they have the package already prepared, or can create it as a custom app.

However, in any large organisation, there will still be a requirement for more complex customisations. There will also be legacy or uncommon apps. You could just hand all the material over to a packaging factory and tell them what you need. But a) finding out what you need is most of the challenge, and b) then you are using a specialist, just not employing them.

So Enterprise App Management is a great addition to Intune. It will save time with the simpler and more common apps. The apps in the catalog can still be customised a little, and there will probably be more customisation in time. But it does not have the range of customisation options available in PSADT, or through services like PatchMyPC and Apptimized. Even then, you will probably need a specialist application packager for a few of the most difficult apps.

Autopilot Timings

This post gives test timings for different configurations in Autopilot. It follows on from a previous one about modern deployment in 2025. The aim is to see how the new Autopilot Device Preparation (Autopilot v2.0) compares with the classic Autopilot (Autopilot v1.0).

Autopilot v2.0 has significant differences in architecture, which Microsoft says will provide a faster and more reliable setup. This is important for the end-user experience. I have run different configurations in a test environment to see how they compare, and these are the results.

Methodology

First is a description of the test methodology. The tests were done as follows:

  • Using two identical VMs in Hyper-V
  • Each VM has 4 GB of vMem, and 12 vCPUs
  • Running on an HP Z2 workstation G9
  • With about 650 Mbps download and 65 Mbps upload speed
  • A clean ISO of Windows 11 24H2
  • One VM registered as an Autopilot device, the other not
  • In Intune, security baselines and a policy each for Microsoft 365 Apps, Edge and Device Inventory: same policies for all.

For apps:

  1. The built-in Microsoft 365 Apps (actually delivered by the Office CSP)
  2. Company Portal
  3. Custom win32 app for Adobe Acrobat Reader DC
  4. Microsoft Visual C++ 2008 Redistributable
  5. Microsoft Visual C++ 2015-2022 Redistributable
  6. 7-Zip
  7. Google Chrome
  8. Microsoft Visual Studio Code.

The first three apps on the list were used for a partial list of apps. The next five came from the new Enterprise App Catalog.

The Enterprise App Catalog apps were used as an easy way to pad out the deployment. Curiously, however, they cannot be added to a list of apps in either version of Autopilot.

All apps were assigned to both a dynamic device group for Autopilot-registered devices, and a static device group for Device Preparation.

Pre-provisioning cannot be done with a Hyper-V VM, so this was not tested. As there is no pre-provisioning in Autopilot Device Preparation, it would not be possible to make a comparison.

Configurations

  1. OOBE
    • Account not assigned a Device Preparation profile, and device not registered as an Autopilot device
    • Represents the least possible time to deploy a device.
  2. Autopilot with 3 blocking apps
    • Device is registered as an Autopilot device
    • Profile is configured with 3 blocking apps.
  3. Autopilot with all apps blocking*
    • Device is registered as an Autopilot device
    • Profile is configured with all apps blocking.
  4. Autopilot Device Preparation with 3 reference apps
    • User is a member of group assigned the device preparation profile
    • Profile is configured with 3 reference apps.

* In this configuration, I had the same intermittent error described here: Autopilot error with Microsoft 365 Apps.

Timing

Timings given are the average of three runs, given in minutes and seconds.

ConfigurationTimeTime minus OOBEIntune TimeComment
OOBE03:0500:0000:00
Autopilot with 3 blocking apps10:1507:1007:38No more apps installed on completion
Autopilot with all apps blocking12:3009:2510:19All apps installed
Autopilot Device Preparation with 3 reference apps13:0710:0209:27Apps continue to install after completion

OOBE represents the time taken for activities that are common across all configurations: authentication, MFA prompts, language and keyboard settings, Windows updates and reboots, Windows Hello for Business. The main difference is that, in Device Preparation, the privacy settings are not suppressed. This adds possibly 5-10 seconds. You can set a policy to “Disable Privacy Experience”, but I did not.

The time minus OOBE represents the amount of variable time, depending on the work. I would expect a production deployment to take a multiple of this, having more apps and a slower network. For example, a time of 09:05 times 2 equals 18:10, plus 03:05 for OOBE equals 21:15 would be good for a user-driven deployment in my experience. A time of 09:05 times 3 equals 27:15, plus 03:05 for OOBE equals 30:20 would not be unusual.

The Intune time is the time reported in Intune by the enrollment monitoring service. From observation, this is the time in the “Setting up for work or school” dialogue.

Interpretation

In this test, the new Autopilot Device Preparation is not faster than classic Autopilot.

Device Preparation with 3 reference apps is significantly slower than Autopilot with 3 blocking apps. Device Preparation with 3 reference apps is still slower than Autopilot with all apps blocking (i.e. installing 8 apps), although less so.

This is surprising. Enrolment Time Grouping, in Autopilot Device Preparation, is supposed to make it faster because Intune only needs to enumerate the apps assigned to the one group. In classic Autopilot, in the ESP, you can see a significant amount of time spent in “Apps (Identifying)”. But this change does not seem to result in a shorter elapsed time for Device Preparation.

I was not able to test Device Preparation with all apps (actually a maximum of 10) referenced. But I can estimate it would be 2-3 minutes slower, because that is the amount of extra time taken in classic Autopilot.

In effect, the reference apps feature of Device Preparation enables you to close the gap on how much slower it is than classic Autopilot.

Curiously, the times reported in Intune give a shorter time for Device preparation with 3 reference apps than for classic Autopilot with all apps blocking, whereas the total elapsed time was longer. At the moment, I do not know if this is because they measure different things, or some other reason outside this calculated time.

Conclusions

The new Autopilot Device Preparation (Autopilot v2.0) service is not faster than classic Autopilot (Autopilot v1.0), despite the changes in architecture.

However, the new Reference Apps feature will make deployment faster in situations where you have more default applications, or large ones, or both. I can see this being quite a common scenario.

With classic Autopilot, if you select to block on only a few apps, Intune does not carry straight on at the end of Autopilot to install the remaining apps. Instead, it halts and waits for a new sync cycle. This limits the usefulness of blocking. With Autopilot Device Preparation, if you select only a few reference apps, Intune does carry straight on afterwards with the remaining apps. I think this makes it a practical choice with an acceptable experience for the user. The more apps you have, the more useful it is.

Speed is not the only factor for deployment, of course. Reliability is also important. But this post is only about the timings.

Modern Deployment 2025

Bulk deployment of end-user computing (EUC) devices is a fact of corporate life, and has been for at least 20 years. The vendors and products change, but the task remains essentially the same: how to distribute devices to staff with the desired applications and configurations.

This blog is about deploying Windows devices, and for the managers of the process rather than the technicians. Windows deployment is a mainstream topic with some excellent technical commentary from Michael Niehaus, Peter van der Woude, Rudy Ooms and others. There is rather less about the pros and cons of different methods.

Autopilot v1.0 provides a cloud service for Windows deployments, to replace on-premises re-imaging. But it can be unreliable, and is a slower experience for the end user unless you prepare (pre-provision) the device in advance.
Autopilot v2.0 (called Autopilot Device Preparation) is significantly simplified and so should be more reliable. Currently, it lacks a pre-provisioning mode, which restricts it to the slow experience. But this is mitigated by a new feature that allows you to select which apps are installed as a priority before the user reaches a working desktop. The more standard apps you have, the more of an advantage this is.
It may be unfashionable, in the age of cloud services, but an on-premises re-imaging service combined with Autopilot v2.0 will probably provide the most efficient result overall.

Deployment

The aim of deployment has been remarkably consistent. I can’t see that it has changed at all: take a device from the manufacturer, and convert it to one that is ready for work as efficiently as possible.

Image –>Re-image –>Identity –>Applications –>Configurations
  1. Image
    • The OS image deployed to the original equipment by the manufacturer (OEM)
    • Because manufacturers generally compete in consumer as well as business sectors, the OEM image tends to contain a variety of other applications: freeware, trialware and vendor utilities.
  2. Re-image
    • A custom image deployed in place of the OEM one
    • Either simply to remove all the vendor-added software
    • Or to do that as well as add corporate software, in order to speed up the overall process of delivering a fully ready device
    • Done by a wide variety of imaging tools: historically, Ghost; then Altiris, Windows Deployment Services (WDS), Microsoft Deployment Toolkit (MDT), FOG and many others.
  3. Identity
    • Enrolment in an identity management system, so that the device is recognised as a corporate device, and the user logging on is recognised as a corporate user
    • Either on-premises Active Directory, or cloud Entra ID, or a hybrid of both.
  4. Applications
    • The installation of corporate applications by an agent on the device
    • The agent can go on to patch and replace applications during the life of the image
  5. Configurations
    • The configuration of different settings on the device
    • Everything from BitLocker to certificate authorities to Kerberos to application configurations (if the application is designed to store settings in the registry)
    • Ultimately these are done by settings in the registry, or by running a script or executable
    • The available settings are defined either in XML-formatted templates (ADMX) or Configuration Service Providers (CSPs)
    • Different device management tools generally provide an interface to set these configurations.

So the aim is to get from 1 to 5 as efficiently as possible. What are the obstacles?

Step 2 is an expensive step. The OEM device has to be unboxed, re-imaged, and re-boxed for delivery. If you re-image with a “thin” image (no applications), then there has to be time to install all the applications later. If you re-image with a “fat” image (all the applications) then by the time it gets to the end user there is a good chance that some of them need to be updated. If you re-image well in advance, the device will need Windows updates and possibly even a full feature update e.g. from Windows 11 23H2 to 24H2.

Step 3 is a complicated dance that has to be carefully controlled. The process has to ensure that only the devices you want to enrol can enrol (e.g. not personal devices); and that all the devices you want to enrol are enrolled (i.e. not bypassed).

Steps 4 and 5 are really about timings. You don’t want to deliver a device to a member of staff until it is ready to use; but you also don’t want them sitting idle watching a progress bar.

Up until perhaps 2018-2020, this process was performed with on-premises infrastructure, SCCM being perhaps the most common but with many alternatives.

Autopilot

Windows Autopilot, introduced in 2017, changed this model in a really quite radical way. What it did was to make every single new Windows desktop OS in the entire world check in first with the Autopilot cloud service to see whether it is a corporate device. It is worth having a look at the Autopilot flowchart. If we simplify it a little, we have two flows:

  1. Start, and connect to the Internet; get the unique hardware ID of the device; then check with the cloud Autopilot registration service whether the device is registered; if it is, get an Autopilot profile for setting up the device.
  2. Follow the Autopilot profile to enrol the device in Entra ID and in Intune; then use Intune apps and device configuration profiles to set up the device.

Autopilot also has a secondary flow, to set the device up in a technician phase first; and then, if the device is assigned to a user and not used as a kiosk-type device, perform a second phase depending on the user account. This technician phase is equivalent to the re-imaging phase in Step 2 above.

Autopilot changes the way devices are deployed because, using the first workflow (“user-driven mode”), you can send the OEM-supplied device direct to the end-user. The device will always check first whether it is registered in Autopilot, and then set itself up accordingly. Or, using the secondary workflow, you can part set it up, then deliver it to the end user to complete. Being a cloud service, it also appealed to organisations that wanted to reduce their on-premises services.

There were two main problem with this. The first is that the process has been (in my experience) unreliable. The second is that, unless you insert the additional step of pre-provisioning the device, the setup is inherently a slow experience for the end user.

For unreliable, see my previous blog: Autopilot and Intune faults. Just to be absolutely clear, these are not configuration errors. They are backend faults in the service causing unpredictable and unsolvable failures in the status monitored by the Enrollment Status Page (ESP). It is hard to put a number on this, but I would say it was perhaps 2-5% of all deployments. That might not sound a lot, but lets take two scenarios:

  • The device is sent to a member of staff working from home; it fails to build correctly; they are stuck at “setup failed”. What happens now? They are at home. The support staff can’t see the screen.
  • You are helping a group of people migrate to their replacement device, in a large migration. One or two fail at Account Setup. The staff can’t leave, because the device doesn’t work. Do you try a reset and start again? Do you give them another device and start again? Do you try to fix it?

For slow, a user-driven deployment might take perhaps 20-30 minutes on an excellent network, depending mainly on the number of applications to install and uninstall. If you are on a poor network, say at home, then it might be a lot longer. For the end user, this is time spent simply waiting. If they go away to do something else, they will not come back and find it done, because it will be waiting at a logon prompt before starting the Account Setup phase.

In contrast, I would say that an on-premises deployment should be 99.9% successful and fast. The device is almost fully built by a technician, before being handed over. I really cannot remember any significant level of faults, once the deployment is fully tested and piloted, so the user phase is short and reliable. Of course, it requires double handling, as in Step 2. But the double-handling is the same in the case of pre-provisioning.

Autopilot Device Preparation

Autopilot v2.0 was introduced this year, 2024. It is a radical rethink of the original version. There are four main changes in the architecture. The question is: will they make the process more reliable, and faster?

  1. There is no pre-registration of the device hardware ID
  2. There is, as yet, no pre-provisioning or unassigned-user mode (called “self-deploying”)
  3. The ESP is, by default, replaced by an extension of the Out of Box Experience (OOBE)
  4. A list of priority apps and scripts is used instead of a list of blocking apps.

No pre-registration

Instead of using a global registration service, it works as follows:

  • The end-user account is added to a security group
  • When the account signs in on any unmanaged device, that device is automatically enrolled in Entra ID and Intune
  • Intune assigns a Device Preparation profile to members of the user group
  • The profile adds the device to a device group
  • That device group is used to install applications and configure the device.

This is a big change in architecture. The hardware ID used for device registration is a bit like the boot configuration used to prevent Windows licence fraud. It is explained in this blog: Autopilot hardware hash. Registration ensures that only a registered device can enrol, and that all registered devices are enrolled.

Registration was not difficult, for a large organisation. Either the vendor registered all new devices, or a script could be run to extract them from all existing devices. It is another step, but not a big one. I think removal of this step is more of an advantage for small organisations, where extracting the hash could be quite difficult.

If the step was not needed, why was it there, and what are the consequences of removing it? It seems to be a balance of risk. Autopilot v2.0 now allows an option of providing a simpler corporate device identifier. This could be used to prevent enrolment of unauthorised devices. But, for Windows, the identifier still has to be pre-loaded as a CSV of the device manufacturer, model and serial number. It is just slightly easier, since it does not require access to the device to obtain it.

No pre-provisioning

Autopilot v2.0 currently only supports the primary, user-driven, workflow. Microsoft says in the FAQs that: “The pre-provisioning mode and self-deploying mode scenarios will be supported in the future, but aren’t part of the initial release.”

Pre-provisioning is a fundamentally different workflow from user-driven.

  • At this stage, we usually don’t know what user will receive the device. It is a bulk preparation process, similar to re-imaging
  • Because there is no user account, and so no authentication or authorization, it uses a different process to validate the identity of the device
  • This process requires the “attestation”, or proving the identity of, the Trusted Platform Module (TPM), the unique hardware component incorporated in the device by the vendor. This proves that the device is the one registered in Autopilot, and not an imposter.

Since there is no pre-registration in Autopilot v2.0, it will not be possible to attest that the device is the one registered. We will have to wait and see how Microsoft solves this. But, without it, we lose the ability to cut the end-user wait time in half. An alternative is to re-image the device with standard applications installed, before handing over the device for a deployment with Autopilot v2.0.

No Enrollment Status Page

The ESP controls the flow of Autopilot v1.0. A failure at any step causes Autopilot to end with an error. Depending on the profile, the user can then either reset the device and start again, or continue anyway to a part-completed desktop.

As I have described elsewhere, the failures are sometimes caused by faults in configuration, but often by unknowable back end failures in the cloud services. Microsoft even recommended at one stage to not use the ESP to track progress.

In Autopilot v2.0, the ESP is optionally replaced by a simple progress indicator during the OOBE dialogue. I think this is easier for a user to understand. The percentage progress, however, is not the actual progress through the work. It is the percentage of the total time allowed before the process times out, default 60 minutes.

Autopilot v1.0 ESP

Autopilot v2.0 OOBE

The ESP itself is not the cause of failures. However, other failures in the process cause it to terminate Autopilot, even if those failures are not fatal to the deployment.

List of reference apps

The change with the biggest impact on the end-user experience is the list of “reference apps”. It is an ambiguous term. It means the apps to install during deployment. All other apps are installed after the setup is complete.

Autopilot v1.0 has the concept of “blocking apps” in the ESP. These hold the deployment until they are installed, and raise an error if they fail. The choice is none, selected apps, or all. If you configure All, then the deployment will take longer than if you configure Selected (although, if you pre-provision, this time does not matter). However, if you configure Selected, other apps are not installed. Instead, they will wait perhaps an hour for the next sync cycle. This may or may not be acceptable. In my experience it is not.

Autopilot v2.0 replaces this with “apps you want to reference with this deployment”. These apps are installed during the deployment. Unlike v1.0, all other apps continue to install without a pause, but without holding the setup. This gives a better user experience than v1.0, because it might only be another 5 -10 minutes before all the required apps are installed. With this design, I think it is reasonable to finish setup with a subset of apps, for example Office 365, Company Portal and a VPN or zero-trust network client, and perhaps any configuring “apps” (scripted configurations deployed as custom win32 apps). There is always more to do in the minutes immediately after setup is complete, and while the other apps are installing.

You might say this is making the best of a bad job, because with no pre-provisioning the only alternative is to hold the setup until all the apps are installed. But I think it is actually a realistic alternative to pre-provisioning. It really depends on whether you can package everything up to deliver an acceptable desktop in an acceptable amount of time.

The list of reference apps also cuts out a minute or more spent enumerating apps in Autopilot v1.0. Instead, Autopilot v2.0 only installs apps from the single device group specified in the profile. Microsoft calls this Enrollment Time Grouping.

Summary

I am optimistic that Autopilot Device Preparation (Autopilot v2.0) will be more reliable than v1.0, because the process has been simplified: in particular with no ESP and so fewer reasons for failure.

It is not faster. You might expect it to be, and Microsoft claims it to be (because of Enrollment Time Grouping). But my tests do not bear this out. It takes a given amount of time to download and install apps, and this does not change. It is possible there is less time spent enumerating the apps to install, but this does not translate into a shorter time overall.

However, the new ability to specify the must-have apps, and for installation of other apps to continue outside of the setup window, gives an opportunity to cut the waiting time for an end user.

The lack of a pre-provisioning mode means that you cannot take the theoretically fastest route (barring failures) of preparing the device with all apps before giving it to the end user. It might be unfashionable, but this means there is a rationale for re-imaging the device with a conventional on-premises technology before shipping it to the end user to complete with Autopilot v2.0.

Autopilot and Intune Faults

“When sorrows come, they come not single spies, but in battalions.” We are deploying thousands of devices with Autopilot and Intune, and the service faults come in battalions.

We have been tracking these faults for a while. There are two types:

  1. Microsoft identifies a fault with a service announcement
  2. We raise a ticket, there is no cause found for the fault. No service announcement.

In mid-May, account setup failed to complete on pre-provisioned devices. The setup just hung. No cause found.

There was a service incident at the same time (now rolled over in the logs). Users unable to use Autopilot. Different problem, but possibly related.

Application failed to unzip after downloading. No cause found.

Application failed to download from Intune, with “endpoint failed to respond.” No cause found.

Late June, Autopilot failed at the beginning, before entering ESP. Error is 80072ee2. DNS query failed for “enterpriseregistration.microsoft.com”. Network timeout trying to register the device at DRS. No cause found.

From 21 June to 7 July, incident IT396955 “Users’ devices may have incorrectly appeared as non-compliant after Autopilot pre-provisioning in Microsoft Intune”. We don’t allow non-compliant devices to connect, so this caused a complete failure. Root cause: “A recent fix for an unrelated issue.” Although the incident dates from 21 June, it was only identified as an incident on 4 July.

On 21 July, incident IT402961 “Users and admins may have been unable to access the Microsoft Intune service or see limited functionality.” Root cause: “a network gateway outage.”

The facts show that the Autopilot service, with Intune, is fundamentally unreliable. If it were Intune alone, users would experience a failure of policy updates, or application deployments. But, during Autopilot, the result is a failed deployment.

At present, I recommend not using Autopilot to deploy devices, for the next year or so. It is too unreliable. My guess is that an internal service agreement has the wrong incentives.

Intune, WDAC and Managed Installer

WDAC has an option (Option 13) to allow apps installed by a Managed Installer. This sounds great! Everything you install using your preferred installer would be allowed, without going to the trouble of creating rules. But there’s a snag. There is no Configuration Service Provider (CSP) to deliver this policy in Intune.

The Managed Installer option actually uses the same method to allow executables to run as the Intelligent Security Graph option (Option 14). When a file is authorised by one of these methods, an extended attribute is written to the file. You can see this attribute with the fsutil utility. The method is documented here: Automatically allow apps deployed by a managed installer with Windows Defender Application Control.

The documentation on Managed Installer is a little confusing. The main documentation shows a policy that allows the Intune Management Extension, as well as the SCCM extension.

<FilePublisherRule Id="55932f09-04b8-44ec-8e2d-3fc736500c56" Name="MICROSOFT.MANAGEMENT.SERVICES.INTUNEWINDOWSAGENT.EXE version 1.39.200.2 or greater in MICROSOFT® INTUNE™ from O=MICROSOFT CORPORATION, L=REDMOND, S=WASHINGTON, C=US" Description="" UserOrGroupSid="S-1-1-0" Action="Allow"> <Conditions> <FilePublisherCondition PublisherName="O=MICROSOFT CORPORATION, L=REDMOND, S=WASHINGTON, C=US" ProductName="*" BinaryName="MICROSOFT.MANAGEMENT.SERVICES.INTUNEWINDOWSAGENT.EXE"> <BinaryVersionRange LowSection="1.39.200.2" HighSection="*" /> </FilePublisherCondition> </Conditions> </FilePublisherRule>

So, looking at that, we would obviously be able to allow Intune apps in Intune, right? But we cannot. The reason is that the documentation also describes implementing this policy in a GPO. But in Intune we cannot use GPO’s and, instead, we use Configuration Service Providers (CSP). The Managed Installer option is implemented as an AppLocker policy, and the AppLocker CSP does not contain a section for the Managed Installer rule collection type.

Although we cannot implement this as an Intune policy (because there is no CSP), we could theoretically implement it another way. With a registry key, for example, even if there were no CSP to configure the registry key, we could simply add, change or delete it in script. With AppLocker policies, we can use PowerShell to create a policy from an XML file, using Set-AppLockerPolicy. So the solution is to deliver a custom AppLocker policy with PowerShell, to enable the Intune agent as a Managed Installer in WDAC.

There are three significant drawbacks:

  1. The effort and constraints in managing the policies manually through PowerShell. For example, there is no Remove cmdlet for a policy in PowerShell
  2. Managed Installer tags the installed files, but not automatic updates. To allow the updates, you would either have to reinstall, or apply rules to allow the updated files, which would defeat the purpose.

Autopilot Faults and Logs

This is a post about where to look to find the cause when Autopilot fails.

By “Autopilot”, I am referring to the whole process of deploying, enrolling and setting up a Windows device. The process really contains several distinct parts:

  • The Out of Box Experience (OOBE) like selecting language, region and keyboard
  • Enrolment in Intune and joining the Azure AD domain (or hybrid)
  • Implementing all the policies and apps assigned to the user or device by Intune
  • The Enrollment Status Page (ESP) which monitors and controls the process nearly from the beginning to the end.

But I am using the term “Autopilot” to refer to all these, for convenience.

We can distinguish two types of failure. One, when setting the process up and testing it to see if it works. Another, during deployments when everything is supposed to be working. This post is about the second. For the first, you can generally follow the guides for setting up Autopilot and ESP, and search the documentation if it is not working. For the second, you need a good understanding of how the process works, what happens when it goes wrong, and where to look to find the cause.

Here is the best end-to-end diagram of the process: Windows Autopilot deployment process. And here is the page that best describes what happens in each phase of EPS: Enrollment Status Page tracking information. It is worth studying these in detail.

Getting the logs for Autopilot is straightforward. From a command prompt, run:

“mdmdiagnosticstool.exe -area DeviceEnrollment;DeviceProvisioning;Autopilot;Tpm –cab C:\Temp\Autopilot.cab”.

You will need to run elevated to get the TPM diagnostics. You will also need to make sure that whoever runs the command is able to save in the location specified. If you are asking a standard user to run the diagnostics, you can use Settings > Accounts > Access work or school > Export your management log files.

Michael Niehaus has written scripts to provide a quick interpretation of the diagnostics logs: Get-AutopilotDiagnostics. Running this script against the cab file is the first place to start.

There are a few points to note about the diagnostics:

  • You need to run it as soon as possible after the problem occurs. Several of the event logs contained in the diagnostics collection roll over, so events will be lost if you only run it later.
  • If you are reproducing a reproducible fault, you can add other tools like netsh, by breaking in with Shift+Fn10 before the fault occurs.
  • The diagnostic logging only captures events relating to Autopilot and enrolment. If you want a wider selection of logs, you may want to run One Data Collector at the same time. It only takes a few minutes to run.
  • Running Get-AutopilotDiagnostics with the –Online parameter will fetch the application name to match the ID, saving you a lot of time in trawling logs to find the name of a failed app ID.

If the failure occurred before the ESP started, then this is Autopilot proper. The place to look is in the event log: Applications and Services logs > Microsoft > Windows > ModernDeployment-Diagnostics-Provider > Autopilot.

When the ESP starts, we can find the place that it fails in the registry. This is obtained from: HKLM\Software\Microsoft\Provisioning\AutopilotSettings. Each sub-category has a status of: notStarted; inProgress, succeeded; or failed. It would be great if these could be surfaced somewhere more accessible. As it is, they can be found in the diagnostics log file: MdmDiagReport_RegistryDump.reg.

For example, see this obscure fault: Error code 0x80180014 when re-enrolling using self-deployment or pre-provisioning mode. The documentation is not correct. Normally, when you do a “Fresh Start” or a “Wipe”, the object in Intune is soft-deleted. But, occasionally, this back-end process fails. As a result, when you do a reset, it will fail in Device Preparation, at the “Registering your device for mobile management” stage i.e. enrolling in Intune. The status is recorded at: HKLM\Software\Microsoft\Provisioning\AutopilotSettings\DevicePreparationStatus.Category.

This happens because the Intune object has not been deleted as it should be. The solution is to find the object and delete it manually. Knowing the stage it failed at enables you to investigate why this happened.

It can be useful to know exactly when the fault occurred. This helps us to correlate different logs. Bizarrely, the time is shown in the event log: Applications and Services logs > Microsoft > Windows > Shell-Core > Operational. Use the “Find” action to search for the word “failed”. This will show the CloudExperienceHost Web App Event with “Subcategory ID = DevicePreparation.MdmEnrollmentSubcategory; state = failed.” When you know the time, you can search other logs to see if anything distinctive happened at exactly that time.

As I said at the beginning, the purpose of this post is to describe how to investigate unexpected faults. Once you know where and when in the process the fault occurred, you can follow the trail to diagnose it. If you know the type of fault, you may well need to reproduce it with additional logging to find the cause.

Autopilot Faults and the Network

The list of network requirements for Intune and Autopilot is extensive. This post is about finding out if the client cannot connect to one or more of the required endpoints during Autopilot.

Microsoft publishes the list of required endpoints for Autopilot and Intune. There is no point in repeating the information here. The important points to note are:

  • The documents also contain references to secondary services. For example, it requires access to Windows Activation, Azure AD (for authentication), NTP time service and others
  • In an enterprise, HTTP and HTTPS traffic will be intercepted by a proxy. Proxy servers may inspect the traffic, and require authentication. All this traffic needs to bypass the proxy; or bypass inspection and authentication. This is not easy to do, and it is easy to make mistakes.
  • The lists often require URL’s and wildcards, for example *.microsoftaik.azure.net for TPM attestation.

As a result, you may need to troubleshoot things that should be working, but are not. You need to be able to find out what is blocked, or not connecting.

The simplest way, which everyone will be familiar with, is to use Wireshark. You can install Wireshark at the beginning of Autopilot, and use Alt+Tab to get back to it after the problem has occurred (see Autopilot and Shift+Fn10).

You may think you are looking for a dropped connection. But the place to look for that is on the firewall. In reality the packet capture will require a lot more work to analyse than that. Almost all the traffic is encrypted HTTPS. You cannot see the contents of the transactions. What you will see (roughly) is:

  • A DNS query to resolve one of the required endpoints
  • A DNS response resolving the query to an IP address corresponding to a traffic manager, load balancer, CDN
  • TCP SYN
  • TCP ACK
  • Client Hello
  • Server Hello, Certificate, Server Key Exchange, Server Hello Done
  • Client Key Exchange, Change Cipher Spec, Encrypted Handshake Message
  • Application Data

Azure Traffic Manager is a DNS service that distributes client traffic to the closest available Azure endpoint. If the client makes a DNS query for (for example) fe2cr.update.microsoft.com, it will obtain the IP address of an endpoint corresponding to fe2cr.update.msft.com.trafficmanager.net.

This means you can’t expect to see traffic to and from the endpoints contained in the lists of endpoints. A query for account.live.com will result in traffic to and from l-0013.l-msedge.net.

If you use a display filter of “dns”, you will see all the queries made. You can check on the proxy that all those names bypass inspection and authentication. If they do not, you may expect to see:

  • No application data after a handshake
  • A TCP FIN followed by another attempt to connect with a new TCP SYN.

As the Autopilot traffic is nearly all HTTPS, you could also use Fiddler to capture the exchange between client and server. When you install Fiddler, you choose to accept the Fiddler certificate. This means that the traffic can be proxied and decrypted by Fiddler. As a result, you should be able to see the content of the transactions.

I recently had a case where Autopilot failed at the start of the Account Setup phase of Autopilot. As it happens, I could see in the Microsoft-Windows-Shell-Core/Operational event log that a “AAD user token request failed” but not why it failed. I wanted to do a packet capture during the time this request failed. But you cannot break into Autopilot during the account setup phase and, even if you could, it would be too late to start a capture. Ideally you want to start a capture at a stopped point in the process, so that you have time to set it up before continuing.

This was a case where the Network Shell utility (netsh.exe) can help. Netsh can record a trace file (*.etl) using different providers. Most importantly, it is not limited to packet capture. It records the activity of each provider specified in the command. Providers are bundled up in “scenarios” for different types of network problem. The “InternetClient” scenario, for example, contains the following providers that we may be interested in:

  • Web-Http
  • WinInet
  • WebIO
  • WinHttp
  • DNS-Client
  • TCPIP.

A unique advantage of Netsh is the “Persistent” parameter. This enables the trace to continue through a restart. By making it persistent, we can start a trace in the Device Setup phase, continue through a restart into the Account Setup phase, and then stop the trace when the fault has occurred.

A difficulty to overcome is that the trace needs to be started and stopped in the same security context. In Device Setup, the console user is DefaultUser0 with admin rights. But this account does not persist into Account Setup.

To get around this, we need to use PsExec. This is the SysInternals utility that enables me (among many other things) to run a command in the system context. If I start the trace in the system context, then I can do the same to stop it. So the full plan of attack is:

  • Shift+Fn10.
  • In the console, download PsExec or copy it from a USB stick.
  • Run: “psexec.exe –s –i cmd.exe”. This brings up a new console running in the System context.
  • In the new console, run: “netsh trace start capture=yes report=yes persistent=yes traceFile=[path to trace.etl] scenario=InternetClient”. Depending on the circumstances, you can use maxSize to limit the size of the trace file. By default, the logging is circular.
  • Continue through to when the fault occurs.
  • In this case, because Autopilot was failing in Account Setup, I needed to use the “Continue” option in the Enrollment Status Page (ESP) profile, so that I could finish and get back to a user session, to be able to run PsExec again and stop the trace with “Netsh trace stop”.

A significant disadvantage of Netsh is that the best way to read the ETL file is with Microsoft Message Analyzer. But this is now obsolete and no longer available to download. There are utilities to convert the ETL to pcap, so it can be read in Wireshark, but that loses the benefit of the network provider logging, like DNS-Client and WinInet. I keep a copy of Microsoft Message Analyzer just for this.

So, this post has given three tools and methods to investigate a network fault causing Autopilot to fail. You will need to adapt the methods to the particular circumstances of the case.

Autopilot Faults and Shift+Fn10

Most people probably know that you can break into Autopilot by pressing Shift+Fn10 to bring up a command prompt. Here are some aspects that people may be less aware of.

The Command Prompt runs in the security context of DefaultUser0. This is a local admin account used for deployment. The account and the profile are supposed to be deleted at the end of Autopilot, but they are not. You can still see the profile in C:\Users.

Obviously, you can run any command line actions. But you can also bring up GUI applications:

  • “explorer” to open Windows Explorer. From there, you can navigate to run other GUI applications.
  • “control panel” to open the Control Panel (or “appwiz.cpl” to bring up Programs and Features)
  • “compmgmt” to bring up Computer Management, for Services, Device Manager, Disk Manager, Event Viewer, Scheduled Tasks, Users and Group
  • “eventvwr” for Event Viewer
  • “taskmgr” for Task Manager
  • “start ms-settings:” to bring up the Settings app.

You can run “powershell.exe” to run PowerShell cmdlets in the Cmd console. Or you can use Explorer to navigate to PowerShell and run it from there.

You can open the Edge Chromium browser to download or upload stuff.

You can use Shift+Fn10 at the beginning, to create a configuration before the main Enrollment Status Page (ESP) phases begin. You can use it when Autopilot fails in Device Preparation or Device Setup. You can use it any time in between. But you cannot use it in the Account Setup phase because, in this phase, the session runs in the user security context and not DefaultUser0.

Some of the things you may want to do at the beginning:

  • Increase the size of the Microsoft-Windows-DeviceManagement-Enterprise-Diagnostics-Provider/Operational event log, from the default 1028 KB
  • Install Wireshark (but, if you do this, you need to make sure the VC++ dependency does not interfere with any VC++ app deployment)
  • Create a C:\Temp folder to save logs and exports.

After you open the Command Prompt, if you navigate back to the ESP, the console will be hidden again. But it is still running. Click Alt+Tab to open it again, or to select any of the GUI applications that are still running. For example, if you started Wireshark at the beginning, then you can go back to the same Wireshark at any time with Alt+Tab.

Troubleshooting Faults in Autopilot

I have experienced a lot of faults in the Autopilot service recently. Autopilot is the Microsoft service that configures a Windows desktop out of the box (OOBE), when it first boots up.

If you google for Autopilot Failure, or Enrollment Status Page (ESP) Failure, you will find a lot of Microsoft documentation, and secondary documentation expanding on similar faults. There’s a very long list of resolved issues, and a list of continuing known issues. To be fair, there are many variables, and many possible scenarios leading to different types of failure: virtual machine; TPM version; user-driven vs. self-deploying; hybrid AAD join. The most obvious cause of a failure is that you might actually have something wrong with the network, or with an application deployment.

But this post is not about these failures. It is about what to do if the service is failing and it does not seem to be caused by one of these documented faults. We have experienced quite a number of these. The fact is, the troubleshooting steps documented by Microsoft are based on known and expected faults, and not on unexpected faults; and certainly not on faults in the Microsoft infrastructure supporting the Autopilot service.

I think I will probably break this post out into separate snippets on how to perform various troubleshooting tasks. Otherwise it will be too cluttered. But let me first illustrate what I mean. If you go to the Intune Tenant Administration page, you will see a tab for the “Service health and message center”. The incidents here roll over very fast, but you will see a continuous flow of faults. We’ve found that only a percentage of faults are acknowledged in this way. But you can get an idea of what is happening from the explanations.

“Admins may have seen provisioning failures when attempting to create new Cloud PCs within Windows 365.”

  • Start time: Wednesday, January 26, 2022, at 12:00 PM UTC End time: Friday, April 1, 2022, at 11:59 PM UTC [over two months later]
  • Root cause: An Azure Host Operating System change resulted in provisioning failures when admins attempted to create new Cloud PCs within Windows 365.

If you are lucky, when a fault occurs, you will find a known service health incident. But how many faults in infrastructure and code are actually acknowledged? Based on my experience it is less than half. We had a total outage of the Autopilot service from 14 Feb to 28 Feb. There was no service health message. But we received an explanation from an internal MS channel to tell us that a code update had gone wrong. I think the reason for this disparity is that Intune and Autopilot are not really homogenous services. They are supposed to be. But it seems clear that they are really a collection of instances of services. The incidents often refer to “customers on the affected infrastructure”. How do you know if you are on the affected infrastructure? You don’t. How does Microsoft know if the affected infrastructure is working or not? It doesn’t. Microsoft incidents refer to telemetry. But telemetry will only tell you what the metrics are measuring. This does not seem to include actual successful completion of transactions.  We have often asked Microsoft Premier Support to reproduce faults for themselves, instead of asking us to repeatedly collect logs for them. They can’t.

So, let’s get into the elements of how to find out what is going on.

  1. Shift+Fn10
  2. Network
  3. Logs

Basic Flaws in Intune Package for Microsoft 365 Apps

Intune (or Microsoft Endpoint Manager) has a built in package for Microsoft 365 Apps. This is the obvious package to use to deploy Office 365. But there are several fatal flaws.

Intune deploys the Microsoft 365 Apps as a policy. This sounds strange, but it is deployed by the Office CSP. What happens is that this policy installs two small Click to Run MSI’s, which then pull down the Microsoft 365 Apps like Word, Excel, Outlook etc.

Sometime back in about 2018 Microsoft chained the Teams installation to Office 365. Consequently, you can select Teams as one of the suite of apps to install. What happens is that sometime after the other apps have been installed, the Teams MSI runs to install the Teams Installer. The Teams Installer is the component that detects a user logon and installs Teams itself for the user, in the user’s %AppData% folder. Teams is not actually installed as part of the Office Click to Run. It is a separate MSI chained to the Office setup.

Because the Microsoft 365 Apps are installed by a policy, the installation is performed by the OMA-DM policy agent, and not by the Intune Management Extension (IME). The IME is the agent that is used to install all Win32 apps. Policies are applied as soon as the Device Setup starts, so before even the IME agent (itself an MSI) has been installed, and before the Win32 apps to be installed have been evaluated. Because the Office Click to Run MSI’s are small, they are installed before other app processing has started.

Microsoft warns that you should not mix Win32 apps and Line of Business (LOB) apps in an Autopilot deployment. The wording in Microsoft docs is particularly poor, because “LOB” can mean different things. I have spoken to several Premier Support engineers who clearly don’t know what it is supposed to mean. In this case it refers to the single MSI packages that were used before Microsoft introduced the IME agent. Before the IME agent, you could install applications but only if they used a single MSI file (no folders, no transform). This installation of a LOB MSI is performed by the OMA-DM agent.

As an example of poor documentation, this page Add a Windows line-of-business app to Microsoft Intune says the following: ”When deploying Win32 apps using an installation file with the .msi extension (packaged in an .intunewin file using the Content Prep Tool), consider using Intune Management Extension. If you mix the installation of Win32 apps and line-of-business apps during AutoPilot enrollment, the app installation may fail.” But it fails to say what is meant by a “line-of-business” app (and it is Autopilot, not AutoPilot).

In contrast, this page Set up the Enrollment Status Page says the following: “It’s preferable to deploy the offline-licensed Microsoft Store for Business apps. Don’t mix LOB and Win32 apps. Both LOB (MSI) and Win32 installers use TrustedInstaller, which doesn’t allow simultaneous installations. If the OMA DM agent starts an MSI installation, the Intune Management Extension plugin starts a Win32 app installation by using the same TrustedInstaller. In this situation, Win32 app installation fails and returns an ‘Another installation is in progress, please try again later’ error message. In this situation, ESP fails. Therefore, don’t mix LOB and Win32 apps in any type of Autopilot enrollment.”

The reason not to mix LOB and Win32 apps is obvious. Any MSI is actually executed by msiexec.exe, which calls the Windows Installer service. If you have ever tried to run an MSI when one is already running, you will have seen a warning that another installation is in progress, please wait.

If you have two different agents running msiexec and calling Windows Installer, they will conflict. This is exactly what happens with the Teams MSI in the Microsoft 365 Apps package. In other words, the Microsoft 365 Apps package is guilty of exactly the fault that Microsoft warns you to avoid.

In the verbose Microsoft 365 Apps log, you will see this error:

01/01/2021 01:01:01.010        OFFICECL (0x2264)        0xdc4                Click-To-Run Non Task Error        co7l2        Monitorable        C2R::TeamsAddon::Install {“MachineId”: “a3b97b64ce6fff4980eaef7d16bed3bd”, “SessionID”: “a7e42957-b65a-45f2-93d7-fdb88842597a”, “GeoID”: 242, “Ver”: “16.0.14430.20342”, “C2RClientVer”: “16.0.14430.20314”, “ContextData”: “{\”message\”:\”InstallTeams: MsiInstallProduct failed due to install already in progress.\”,\”Status\”:\”1618\”}”}

You get the verbose log by breaking into Autopilot and setting this registry key: HKLM\SOFTWARE\Microsoft\ClickToRun\OverRide: LogLevel = DWORD 3.

Amazingly, the Microsoft 365 Apps setup process does not detect that the Teams installation has failed. It carries on and exits with a success code. So it will never try again. In practice, what happens is that sometimes Teams wins the race for Windows Installer, and gets installed, and sometimes it doesn’t. If it wins, then the standard retry in the IME will ensure that whichever app lost to Teams will try again and get installed. So the result is that, apparently randomly, some devices will complete Autopilot without Teams, and with no way to get it back.

But there is more. The Intune package for Microsoft 365 Apps automatically includes OneDrive. You can’t select or unselect it. OneDrive is already natively installed on Windows, but as a per-user application in the user’s %AppData% folder. The Microsoft 365 Apps package installs the 32-bit per-device version of OneDrive, and removes the per-user version. But Microsoft recommends using the 64-bit version of OneDrive on standard Windows devices. So, if you create a package to install the 64-bit version, Intune will first install the 32-bit version, then (hopefully) uninstall it and install the 64-bit version.

And there is more. Visio and Project are both available in the Microsoft 365 Apps package. But, if you select (say) Visio without the other apps (Word, Excel, Outlook etc), then all those other apps will be uninstalled. One Microsoft 365 Apps packages entirely replaces, rather than adds to, another. If you select Visio with the other apps, then the existing installation of Office will be removed, and replaced with the new one. Obviously, there are different combinations: with Visio but not Project; with Project but not Visio; with Visio and Project. It is completely unworkable. In addition, the installation of Visio or Project will force-close other Office apps, which is not nice.

And there’s more! Microsoft Surface devices come pre-installed with Microsoft 365 Apps in 13 languages. If you run the built-in Intune package, it will not uninstall the pre-installed languages. You might say this doesn’t matter. But, if you do a Fresh Start on a device, then it will not have the 13 languages, and so you will have different devices with different configurations.

Taking all this into account, we decided to build our own packages for all Office apps. Once you have a basic script to run the setup, and after you generate the required XML, it is fairly easy to adapt to the different packages you need for Office 365, Teams, OneDrive, Visio and Project. The good thing is that you are still using exactly the same core method: setup.exe with an XML file. You can do some of this by using the XML option instead of the Configuration Designer option in the Intune package, but we needed to do more, including making the Visio and Project installations interactive, so we chose to go entirely custom.