Type to search 66 articles.

    Practical engineering guidance

    Intune app deployment: detection rules, requirements and supersedence

    The detection rule is the part that decides whether an application is installed. Get it wrong and Intune reinstalls forever, or reports success for software that is not there.

    Series: Intune and Configuration Manager

    • Intune
    • Application deployment
    • Implementation

    Packaging an application for Intune is mostly mechanical. The .intunewin file wraps an installer, and the install command line is whatever it always was.

    The part that determines whether the deployment works is the detection rule, and it is where almost every problem I have seen originates. Intune has no other way to know whether the application is present — it does not inspect the installer’s result beyond the exit code, it runs your detection rule. A rule that is wrong produces one of two failures, both unpleasant.

    The problem: two failure modes, opposite in appearance

    The rule never returns true. Intune installs the application, checks, decides it is not installed, and installs it again. Repeatedly. Users see reinstallations, the device may reboot unexpectedly, and during Autopilot the Enrollment Status Page waits forever for an application that is already there — the most common cause of the ESP failures in Windows Autopilot enrolment failures.

    The rule returns true when it should not. Intune reports the application as installed and does nothing. The software is absent, or it is a version older than intended, and the compliance report says everything is fine. This is worse, because it is silent.

    Both come from the same cause: a detection rule that does not accurately describe what a successful installation leaves behind.

    Design: choosing a detection method

    Four methods are available, and they are not equally good.

    MSI product code. Use it when the installer is a straightforward MSI. It is reliable, requires no thought, and checks the product code. Its limitation is version handling — a product code that changes between versions means the rule stops matching after an upgrade, which is sometimes what you want and sometimes not.

    File or folder. Checking for a file, optionally with a version or a date. Reliable if you check the right file, which means the main executable rather than a configuration file the application might recreate. Always include a version comparison when checking an executable; detecting mere existence means any version satisfies the rule, including a broken one.

    Be careful with the path on 64-bit systems. An application installing to Program Files while your rule checks Program Files (x86) is a classic, and the setting controlling 32-bit redirection matters.

    Registry. Checking a key, a value, or a value’s contents. Good for applications that record their version in the registry, which most do. The same 32-bit versus 64-bit caution applies — an application writing to the 64-bit hive with a rule reading the WOW6432Node view, or the reverse, fails silently.

    Custom script. A PowerShell script that returns output and exit code 0 when detected. Necessary for anything genuinely complex — multiple conditions, a version comparison the built-in rules cannot express, an application with no clean marker.

    The rules for a detection script are specific and worth stating, because they are the cause of most script-based failures:

    • Exit 0 and write something to standard output to indicate detected.
    • Exit 0 with no output, or a non-zero exit code, means not detected.
    • Keep it fast and side-effect free. It runs frequently, in system context.
    • Do not have it install, repair or change anything. A detection script that fixes things is a detection script that will fix them at an inconvenient moment.
    # Detect an application by version recorded in the registry.
    $path = 'HKLM:\SOFTWARE\Contoso\SampleApp'
    $minimum = [version]'4.2.0'
    
    try {
        $installed = (Get-ItemProperty -Path $path -Name 'Version' -ErrorAction Stop).Version
        if ([version]$installed -ge $minimum) {
            Write-Output "Detected $installed"
            exit 0
        }
    } catch {
        # Fall through to not-detected.
    }
    
    exit 1

    Note that this returns not-detected for an older version, which is what causes Intune to upgrade it. Whether that is what you want is a deliberate choice.

    Design: requirements, which are a different thing

    Requirement rules decide whether the application is applicable to a device. Detection rules decide whether it is installed. Conflating them is common.

    Use requirements for: architecture, minimum operating system version, disk space, and any custom condition determining whether this device should receive the application at all.

    A device failing a requirement reports as not applicable rather than failed, which keeps your reporting honest. Putting that logic in the detection rule instead produces a device that reports as failed forever.

    Design: dependencies and supersedence

    Dependencies install another application first — a runtime, a framework, a prerequisite. Intune installs dependencies before the dependent application and can be configured to install them automatically.

    Supersedence replaces one application with another, and can be configured either to uninstall the previous version first or to install over it. This is how upgrades and replacements are handled.

    Three cautions:

    Keep the chains shallow. Deep dependency and supersedence chains take a long time to evaluate and to run, and they are difficult to reason about when something fails. There are limits on chain depth; check the current ones rather than discovering them.

    Supersedence changes what happens at the Enrollment Status Page. A superseding application may need to uninstall and reinstall during provisioning, which lengthens the critical path.

    The uninstall command must actually work. Supersedence with uninstall relies on the previous application’s uninstall command line. Test it in isolation — an uninstall that prompts interactively, or that returns a non-zero code on success, breaks the chain.

    Deployment

    1. Package with the Microsoft Win32 Content Prep Tool into an .intunewin file.
    2. Write the install and uninstall command lines, and test both manually on a clean device as SYSTEM before uploading. Most “the deployment failed” cases are an install command that was never tested outside a user context.
    3. Write the detection rule, and test it independently — run the script, check the registry path, confirm the file version — on a device where the application is installed and on one where it is not. Both directions.
    4. Set requirements for applicability.
    5. Assign to a small pilot group as required.
    6. Watch the install status, then widen.

    Testing in both directions at step 3 is what catches the silent failure mode, and it takes two minutes.

    Validation

    • On a device without the application: it installs, and the status becomes installed.
    • On a device that already has it: it reports installed and does not reinstall. Check this explicitly by watching over a day — the reinstall loop is only visible over time.
    • On a device that does not meet the requirements: not applicable, not failed.
    • Uninstall it through Intune and confirm it is removed and reports as such.
    • For supersedence: confirm the old version goes and the new one arrives, and that the device is usable throughout.

    Check the install status per device rather than only the aggregate. An aggregate of ninety-five per cent success hides the five per cent that are looping.

    Operations

    Version your applications properly in Intune, and use supersedence rather than editing an existing application in place. Editing in place makes the deployment history unreadable.

    Keep the ESP list short, for the reasons in the Autopilot article. Every blocking application is a way for provisioning to fail.

    Revisit detection rules when an application updates. A vendor changing where they record the version, or moving the install path, breaks a rule that has worked for years — and the failure is the silent kind.

    Watch for the reinstall loop as a specific signal. An application with a high install count relative to its device count is looping, and that ratio is worth checking periodically.

    Rollback

    Change the assignment from required to available, or remove the assignment. Neither uninstalls the application from devices that already have it — removing an assignment stops future installs, and only an explicit uninstall assignment removes software.

    For a bad supersedence configuration, remove the supersedence relationship before doing anything else, because otherwise every device that checks in continues to act on it while you are trying to fix it.

    Verification and limits

    Win32 app packaging, the four detection rule types, detection script exit code and output behaviour, the distinction between requirement and detection rules, and dependency and supersedence behaviour were checked against current Microsoft documentation on 20 September 2026. The testing discipline and the failure-mode framing are my own practice.

    No application was packaged or deployed for this article. Required assignments install software on every device in scope — pilot first, test detection in both directions, and verify the uninstall command before configuring supersedence. Win32 app behaviour and chain depth limits change between releases; confirm current limits before designing a deep chain.

    References