Distributing Windows Desktop Apps Through Customer Intune Tenants — A Software Vendor Playbook for Win32, MSIX, Code Signing, and Updates

Tadashi Shigeoka ·  Sun, February 8, 2026

When you ship a Windows desktop app to enterprise customers, one question shows up in every deal: how does the customer’s IT department actually push your binaries to managed PCs? In 2026, the answer almost always starts with Microsoft Intune, Microsoft Configuration Manager, or co-management bridging the two. Whether your installer is accepted depends on whether the IT team can deploy it cleanly with the artifacts you provide.

Several of the defaults that used to be safe are no longer in effect in 2026. Microsoft Store for Business and Education has been retired, with the new Microsoft Store apps integration as its successor. EV code signing certificates no longer bypass SmartScreen, so every signature is reputation-based now. OV code signing certificates require HSMs or hardware tokens. Azure Artifact Signing (formerly Trusted Signing), Microsoft’s recommended signing service, is gated by region, with Public Trust enrollment limited to organizations in the US, Canada, EU, and UK.

This post is the software vendor playbook for shipping a Windows desktop app through customer Intune tenants. It covers the choice between Win32, LOB, MSIX, and the new Microsoft Store; building the .intunewin; the current state of code signing; how to split auto-update responsibility between vendor and IT; how to inject tenant configuration; and the deliverables that actually unblock customer IT teams. The lens is a B2B SaaS company that wants its desktop client to be as deploy-friendly as possible without losing control of release quality.

Why Win32 Apps Are the New Default

In 2026, the answer for “where do new apps go in Intune?” is Win32 apps (.intunewin). Microsoft Learn, Andrew Taylor’s writing, Patch My PC guides, and Recast Software’s detection rule writeup all converge on the same recommendation.

The reason is structural. Only Win32 apps run through the Intune Management Extension (IME) sidecar agent, which means only Win32 supports:

  • Custom detection rules (MSI ProductCode, file version, registry, PowerShell)
  • Requirement rules (OS version, architecture, free disk, memory, CPU, registry, PS scripts)
  • Up to 100 dependencies that auto-install before the parent
  • Up to 10 supersedence relationships for upgrades and replacements
  • Custom return codes and reboot behavior
  • Delivery Optimization eligibility

Traditional LOB (Line-of-Business) apps are processed by the OS-native MDM agent. Detection is locked to the MSI ProductCode, and there are no dependencies, no supersedence, and no support for multi-file packages. LOB only makes sense for “trivially simple MSI with at most one command-line argument.”

AspectWin32 app (.intunewin)LOB app (direct MSI)
Input formatMSI / EXE / PS1 plus support filesSingle .msi / .msix / .appx
Multiple filesYesNo
DetectionMSI / file / registry / PSMSI ProductCode only
DependenciesUp to 100None
SupersedenceUp to 10None
Size limit30 GBAbout 8 GB
Autopilot coexistenceRecommendedRisk of Another installation in progress failure when mixed with Win32

Microsoft Store for Business and Education has been retired. Its successor in Intune is the Microsoft Store apps (new) integration, which uses WinGet manifests and supports UWP, MSIX, and Win32. Intune keeps the version current automatically, which is great, but the requirement of public Store distribution rules it out as a primary path for most enterprise B2B SaaS clients.

The vendor-side conclusion is short: ship new apps as Win32 apps, reserve LOB for trivial MSIs, and treat the Store as an optional public-facing channel.

Choosing MSIX or MSI as the Source Format

A “Win32 app” is a delivery model in Intune; the actual installer inside the .intunewin can be MSI, EXE, PowerShell, or a combination. The question that comes earlier is whether to author the source as MSIX or as a classic MSI.

MSIX is the newer format Microsoft pushed as the UWP successor. The wins are real: container isolation, delta updates, clean uninstall (virtual registry and virtual files vanish together), .appinstaller-driven auto-update, and signature-enforced integrity protection. The catch is the container model excludes apps that need:

  • Kernel-mode drivers or specific shell extensions
  • Direct HKLM writes
  • Per-user Windows services
  • Always-on UAC elevation
  • Deep COM integration (Outlook add-ins, Office add-ins)

These are the same constraints that pushed Microsoft itself to retire the Microsoft Store installation type of Microsoft 365 Apps. The Office case is instructive: even Microsoft found the MSIX sandbox a poor fit for apps with deep COM and add-in ecosystems. Industry write-ups from Advanced Installer and others have made the same point about complex line-of-business apps.

If your app does not need any of those features, MSIX is genuinely worth considering. The clean uninstall and signature-enforced integrity story holds up well in regulated industries that care about endpoint hygiene.

The practical decision tree for a software vendor looks like this:

flowchart TD
    Start[Windows desktop app to ship] --> Q1{Drivers / shell extensions / HKLM / per-user service / always-on UAC?}
    Q1 -- Yes to any --> MSI[Author MSI, ship via Win32]
    Q1 -- No --> Q2{Acceptable to publish to the public Store?}
    Q2 -- Yes --> Store[Microsoft Store app - new]
    Q2 -- No --> Q3{OS integration shallow?}
    Q3 -- Yes --> MSIX[Ship MSIX via Win32 / LOB]
    Q3 -- No --> MSI

For Electron apps, electron-builder’s NSIS installer defaults to dropping binaries into %LOCALAPPDATA% per-user, which trips up enterprise distribution (per-machine layout is possible with oneClick: false plus perMachine: true, but is not the default). The first-choice generator is electron-wix-msi, which produces a per-machine MSI with ALLUSERS=1. Microsoft ISE’s own playbook (Packaging an Electron app for managed distribution) builds the MSI with the WiX Toolset before wrapping it as .intunewin. .NET desktop apps (WPF, WinForms, WinUI 3) have the same playbook with WiX or Advanced Installer, with the .NET runtime either bundled (self-contained) or pinned as a separate Intune dependency.

Building the .intunewin and Designing Detection Rules

Once the source format is decided, you generate the .intunewin with the Microsoft Win32 Content Prep Tool (IntuneWinAppUtil.exe). It encrypts the contents of a folder into a single archive that Intune can ingest.

IntuneWinAppUtil.exe -c <SourceFolder> -s <SetupFile> -o <OutputFolder> [-q]

Two pitfalls show up in practice. First, never put the Content Prep Tool itself inside the source folder. If you do, the tool ends up inside the .intunewin and inflates every package you ship. Second, Intune’s hard limits are 30 GB per app and silent-install only. Apps that miss either constraint will not deploy at all.

Detection rules tell Intune whether the app is installed. Wrong detection rules lead to one of two failure modes: Intune reinstalls the app on every check-in because it cannot find the install signature, or it reports success even when the installer failed. The four detection mechanisms each have a fit:

Detection ruleScoreFitVersioning
MSI ProductCodeHighMSI only, simplestEnable MSI product version check = Yes for version-aware behavior
File (version compare)HighestEXE / Squirrel / ElectronCompare File Version property of main executable, easiest version-aware option
RegistryMediumDetect EXE or MSI via the Uninstall keyString / version / integer comparison
PowerShell customMediumComplex conditions, file timestampsexit 0 plus STDOUT means “installed”

The vendor-side rule is to keep the ProductCode unique per version while keeping the UpgradeCode constant for the lifetime of the product. Use WiX’s <MajorUpgrade> element to declare it. Without version-aware detection, Intune marks an old version as “installed” and never starts the upgrade.

The PowerShell script installer option for Win32 apps, which lets you separate install logic from the binary .intunewin and edit it inside the Intune admin center, is also worth using. You can ship just the binaries inside the .intunewin and keep per-customer adjustments in the script.

A complete detection rule example to hand to customer IT looks like this:

# Intune Win32 detection rule example (MSI)
detection_rules:
  type: MSI
  msi_product_code: "{12345678-90AB-CDEF-1234-567890ABCDEF}"
  msi_product_version_check: yes
  msi_product_version_operator: greater_than_or_equal
  msi_product_version_value: "1.2.3.0"
 
# Alternative: file-version detection
alternative:
  type: File
  path: "%ProgramFiles%\\YourCompany\\YourApp"
  file: "YourApp.exe"
  detection_method: version_greater_than_or_equal
  version: "1.2.3.0"
  associated_with_32bit: false

Install Context and Silent Install

Intune offers System and User as install contexts. For enterprise distribution the answer is System. Reasons:

  • Per-machine installation that is shared across all users
  • Ability to register Windows services, write to HKLM, and configure Defender exclusions
  • Completes during the device phase of the Autopilot Enrollment Status Page (ESP), so it does not wait for user logon
  • Effectively required for Microsoft Entra-joined devices

Choosing System passes ALLUSERS=1 to the MSI by default. Vendor CI should verify the installer behaves correctly under ALLUSERS=1 and never silently flips into per-user mode (MSIINSTALLPERUSER=1).

Intune does not support interactive installs. Anything that needs a UI button press or a UAC prompt during install will hang and fail in System context. Microsoft also explicitly does not support workarounds like serviceui.exe to force user-session interaction. Validate your installer using Sysinternals psexec with psexec -s -i cmd.exe, which gives you a SYSTEM prompt to run the silent install command in.

The silent install commands are the vendor’s responsibility to document.

:: Standard silent install (minimum)
msiexec /i "YourApp-1.2.3.msi" /qn /norestart /l*v "%TEMP%\yourapp-install.log"
 
:: With config injection
msiexec /i "YourApp-1.2.3.msi" /qn /norestart ^
  TENANT_ID="acme-corp" ^
  API_BASE_URL="https://api.example.com" ^
  ALLUSERS=1
 
:: Uninstall
msiexec /x {YOUR-PRODUCT-CODE-GUID} /qn /norestart /l*v "%TEMP%\yourapp-uninstall.log"

EXE installers have no standard for silent flags (/silent, /S, /quiet, /qn), so you must publish a table that lists yours. MSIs and EXEs without this documentation will get stuck at the customer’s validation stage every time.

Dependencies, Supersedence, and the Auto-Update Split

Win32 apps support up to 100 dependencies, which Intune installs before the parent app. Keep the dependency graph thin. A reasonable target is .NET Desktop Runtime, VC++ Redistributable x64, and VC++ Redistributable x86 registered as separate Intune apps and wired in as dependencies.

.NET Desktop Runtime is required for WPF and WinForms; the plain .NET Runtime is not enough. C++ apps need the latest Visual C++ Redistributable at or above the MSVC toolset used to build them, and the architectures (x64, x86, ARM64) must match.

Supersedence replaces an old version with a new one. Up to 10 relationships per app, and the “Uninstall previous version” flag changes the behavior:

  • No: in-place upgrade (relies on the app handling the upgrade itself, e.g. MSI <MajorUpgrade>)
  • Yes: uninstall the old version, then install the new one (clean replacement)

There is one trap that catches every team eventually. Auto-update for Available-assigned Win32 apps requires both a supersedence relationship and the Auto-update toggle on the assignment, and rollout takes two device check-ins (typically 8 to 16 hours). If you operate as if “ship date equals fleet rollover,” your support queue fills with confusion. Communicate the rollout lag explicitly to CS and customer IT admins.

Auto-update is where vendor instincts often need a reset. Built-in updaters like Squirrel.Windows, electron-updater, or a custom MSI downloader are great for consumer apps. In the enterprise, they are often actively unwanted because:

  • Customers want to pin validated versions (financial, healthcare, public sector)
  • Their WSUS / Intune / SCCM rollout rings already do staged deployment
  • Bandwidth, proxy, and TLS-inspection settings tend to break independent updaters

The vendor default should be inverted:

  1. Disable in-app auto-update by default
  2. Enable only when a registry key or ADMX setting (EnableAutoUpdate=1) explicitly turns it on
  3. Treat the Intune supersedence path as the canonical one
  4. Offer Stable / Beta channels separately for customers that want to opt back in

Code Signing — SmartScreen, HSMs, and the Geo Issue

Code signing is the foundation for proof of origin, tamper detection, SmartScreen reduction, AppLocker / WDAC publisher allow rules, and PowerShell AllSigned execution policies. Three current-day premises matter.

The first is that EV code signing certificates no longer grant instant SmartScreen bypass. SmartScreen treats every signature as reputation-based, so a new build signed with OV, EV, or Azure Artifact Signing can show Windows protected your PC until the certificate and binary accumulate reputation. Buying EV new for SmartScreen reduction is no longer justified.

The second is that OV code signing certificates require HSMs or hardware tokens. The CA/Browser Forum Baseline Requirements mandate FIPS 140-2 Level 2 / Common Criteria EAL 4+ hardware for private key generation, and CSR-based browser submission is no longer accepted. CI/CD integration is either a USB token physically attached to the build server, or a cloud HSM service like DigiCert KeyLocker or Sectigo Cloud Signing.

The third is that Microsoft’s recommended Azure Artifact Signing (formerly Trusted Signing) is geo-restricted for new Public Trust enrollment. Per the official Artifact Signing FAQ, Public Trust enrollment is currently available to organizations in the US, Canada, EU, and UK (with individual developers limited to the US and Canada). Software vendors based in Japan, Australia, India, and other regions are excluded for public distribution. Private Trust (intended for internal PKI scenarios) is still available, which limits its usefulness for shipping to external customers.

PremiseImpact
EV no longer grants instant SmartScreen bypassLittle economic case to buy EV new
OV HSM / token mandateBrowser-based CSR is gone, cloud HSM or USB token only
Azure Artifact Signing geo-restrictionPublic Trust enrollment limited to US / Canada / EU / UK organizations

For software vendors outside the eligible regions, the practical answer is to buy an OV code signing certificate from a public CA. DigiCert, Sectigo, and GlobalSign (and their regional resellers) cover the same ground. For organizations that have engineering teams across multiple geographies, cloud HSM services are usually a smoother fit than shipping USB tokens to each office. Some CAs ship USB tokens domestically only, which is worth checking when picking a vendor.

The signing recipe itself is short. Use SHA-256 and an RFC 3161 timestamp. Without the timestamp, signatures stop validating once the cert expires.

signtool sign /tr http://timestamp.digicert.com /td sha256 /fd sha256 /a "YourApp.msi"
# MSIX
signtool sign /fd SHA256 /td SHA256 /f .\codesign.pfx /p <password> /tr <timestamp-url> .\YourApp.msix
signtool verify /pa /v .\YourApp.msix

Tenant Configuration and License Injection — MSI Properties and ADMX

A B2B SaaS desktop client almost always needs to receive a tenant ID, an API base URL, and a license key per customer. Where you accept that injection shapes both the deployment story and the runtime config story.

MechanismTimingCompatibilityConfidentiality
MSI public propertiesInstall timeIntune Win32 / SCCM / GPO all goodVisible on the command line
MST (Transform)Install timeClassical GPO / SCCM, also Intune Win32Binary form
HKLM registryInstall time + read at runtimeUniversal, can be set laterACL controls
Config file under %PROGRAMDATA%Install time / post-installWin32 with PowerShell post-stepFile ACL
Intune configuration profile (ADMX ingestion / OMA-URI)Any timeIntune-specificAdmin-managed
First-launch online authRuntimeUniversalOAuth / Device Code Flow

The recommended default is a three-layer stack: MSI public properties for the initial install, ADMX/ADML for runtime overrides, and first-launch online auth as the final fallback.

Name MSI public properties in uppercase (TENANT_ID, LICENSE_KEY, API_BASE_URL). Lowercase names become secured properties and cannot be passed on the command line. In WiX, declare them with <Property Id="TENANT_ID" Secure="yes"/> and use a CustomAction to write them into the registry or a config file at install time.

ADMX/ADML ingestion in Intune is the way enterprise customers expect to manage your settings. Ship a YourProduct.admx plus localized .adml files, and customer IT can use the same templates in both GPO and Intune. The Intune custom configuration profile for the ADMX itself uses this OMA-URI:

./Vendor/MSFT/Policy/ConfigOperations/ADMXInstall/<ProductName>/Policy/<ProductName>Admx

And the per-setting OMA-URI is:

./Device/Vendor/MSFT/Policy/Config/<ProductName>~Policy~<Category>/<SettingName>

The app should read in this priority order: HKLM\SOFTWARE\Policies\<Vendor>\<Product> first (so policy enforcement wins), then HKLM\SOFTWARE\<Vendor>\<Product>, then HKCU\SOFTWARE\<Vendor>\<Product>. This matches what GPO admins expect and avoids surprising per-user overrides.

Network, Delivery Optimization, and Proxy Pitfalls

Intune deployment goes through IME, which downloads the .intunewin from cloud storage and unpacks it to C:\Windows\IMECache\ before installing. The bottleneck for large deployments is bandwidth, which is why you should know Delivery Optimization.

Delivery Optimization is the P2P caching layer for content delivered through Intune. Win32 app content is automatically eligible. The most important setting is the download mode:

SettingRecommended startNotes
Download modeSingle site LAN(1), multi-site/WAN Group(2)Group + DOGroupID for site-bound P2P
Minimum content file size50 MBDefault
Minimum disk size32 GBCache budget
Minimum RAM4 GBDefault
Max cache size20%Default
VPN peeringOff at startDisabled by default

A vendor-side note: small .intunewin files (under 50 MB) bypass the P2P layer and download directly on every device, but this is usually fine for B2B SaaS clients. Apps over 500 MB need an explicit P2P story or you risk saturating customer bandwidth.

The proxy pitfall is real. IME runs as SYSTEM, and a user-configured browser proxy does not apply to that context. The classic “users can browse the web fine, but Intune apps fail to download” symptom comes from this gap. Three remedies:

  1. Allow direct, unauthenticated traffic to *.manage.microsoft.com, *.delivery.mp.microsoft.com, and other Intune endpoints at the firewall (recommended)
  2. Use netsh winhttp set proxy to set a static proxy at the OS level (which covers SYSTEM)
  3. Use WPAD for autodiscovery

The vendor’s documentation should always include the FQDNs, ports, TLS versions, and certificate-pinning behavior of your own app:

[Install time]
- None, fully local
 
[First launch]
- https://api.example.com/auth (TCP 443, TLS 1.2/1.3)
- https://login.microsoftonline.com (TCP 443, MSAL)
 
[Telemetry, opt-in]
- https://telemetry.example.com (TCP 443)

If your app pins certificates, document how to disable it. Customers running TLS inspection will hit broken connections immediately, and the standard expectation is that WinHTTP and Schannel use the system trust store.

Monitoring and First-Pass Troubleshooting

The Intune admin center surfaces per-app status (Installed, Not installed, Failed, Pending, Not applicable) along with last check-in time and version per device. When you support a customer’s IT team, this is your first stop, but it is rarely sufficient on its own. The IME client logs are.

Log fileLocationUse
IntuneManagementExtension.logC:\ProgramData\Microsoft\IntuneManagementExtension\Logs\IME overall, policy fetch, download status
AppWorkload.logSameWin32 app DL / verify / install detail (added 2024)
AgentExecutor.logSamePowerShell script execution
ClientHealth.logSameAgent health

Read them with CMTrace or OneTrace. The Intune admin center can also “Collect diagnostics” remotely, returning up to 250 MB of logs.

Two error codes are worth knowing because vendors can prevent them:

  • 0x87D1BC26 (detection error): install actually succeeded, but the detection rule is wrong. Avoid baking version numbers into install paths, and use UpgradeCode/ProductCode correctly.
  • 0x87D300C9 (unmonitored process timeout): the installer is silently waiting on a UI prompt. CI tests in System context catch this before a customer does.

Microsoft also recommends excluding C:\Program Files (x86)\Microsoft Intune Management Extension\Content and C:\Windows\IMECache from antivirus scans. When a customer reports slow or failing deploys, this exclusion is the first thing to verify.

What to Hand to Customer IT

The full vendor deliverable list, suitable for ISO 27001 / SOC 2 / regional privacy compliance, looks like this. With these in place, customer IT teams can deploy on Intune, SCCM, GPO, Workspace ONE, ManageEngine Endpoint Central, or PDQ Deploy without having to fill in gaps.

  1. Signed MSI (SHA-256 plus RFC 3161 timestamp)
  2. .intunewin packaging script (or a pre-generated .intunewin)
  3. Detection rule examples (MSI ProductCode, file version, registry, all three)
  4. Silent install / uninstall command reference
  5. ADMX / ADML templates with locale variants
  6. MSI public property reference (TENANT_ID, API_BASE_URL, LICENSE_KEY, ENABLE_AUTO_UPDATE, TELEMETRY_OPTOUT)
  7. System requirements doc (OS, .NET, VC++ Redistributable)
  8. Network requirements (FQDN, ports, TLS version, certificate pinning behavior)
  9. AppLocker / WDAC policy templates (publisher-based allow rules)
  10. SBOM (CycloneDX or SPDX, per release)
  11. Vulnerability disclosure policy (e.g. Critical 7d / High 14d / Medium 30d / Low 90d)
  12. Support policy (e.g. N-2 major versions, minimum 12-month EOL notice)
  13. Intune deployment guide (with localization for non-English customers and screenshots)

A premium option worth pursuing is having your product included in the Intune Enterprise App Catalog. Microsoft pre-validates the install command, requirements, and detection defaults for catalog apps, and Guided Update Supersedence keeps customer IT from having to repackage every release. Inclusion is curated by Microsoft and EAM packaging partners (Patch My PC and similar) rather than a self-serve vendor submission. Note that the catalog is part of the Intune Suite Enterprise App Management (EAM) add-on, which is a paid subscription on the customer side, so this option assumes the customer has the add-on. For vendors that want to minimize customer-side packaging effort, this is the smoothest path.

Considerations for Vendors Outside the US

Two friction points come up regularly for software vendors based outside the US.

The first is the Azure Artifact Signing geo-restriction described above. Software vendors in Japan, Australia, India, and similar regions cannot enroll for Public Trust, so the signing pipeline has to use a regional public CA’s OV certificate. Cloud HSM services from DigiCert and Sectigo are still accessible globally; some CAs (regional GlobalSign affiliates, for example) ship physical USB tokens domestically only, which matters for distributed engineering teams.

The second is character encoding and locale. %USERPROFILE% paths can contain non-ASCII characters in many regions. File I/O should be UTF-8 / UTF-16LE consistently, and Shift_JIS or other legacy encodings should be avoided. The Win32 Content Prep Tool’s Unicode handling has improved (v1.7+), but keeping the source path ASCII-only is still the safer convention.

There is also a softer point worth keeping in mind. In many markets, customer IT teams are small mixed-responsibility groups, not dedicated endpoint specialists. Shipping a localized deployment guide with screenshots, in addition to your English documentation, makes a noticeable difference in adoption.

Summary

Distributing a Windows desktop app through customer Intune tenants in 2026 looks like a multi-option decision but converges quickly:

  • Ship new apps as Win32 apps (.intunewin). LOB is for trivial MSIs, Microsoft Store for Business is gone, and Microsoft Store apps (new) require public Store distribution.
  • Decide MSIX vs MSI by capability. If your app has drivers, shell extensions, HKLM writes, per-user services, or always-on UAC, author MSI and wrap it. Otherwise MSIX is on the table.
  • Sign with SHA-256 plus RFC 3161 timestamp. EV no longer grants instant SmartScreen bypass, OV requires HSM/token, and Azure Artifact Signing is geo-restricted. For vendors outside the eligible regions, an OV cert from a public CA is the practical baseline.
  • Use System install context, silent install, no UAC interaction.
  • Default in-app auto-update to off. Let IT manage releases through Intune supersedence.
  • Inject configuration via MSI public properties plus ADMX/ADML. Read HKLM\SOFTWARE\Policies\<Vendor>\<Product> first.
  • Hand customer IT the full kit: MSI, .intunewin, detection rules, ADMX, SBOM, support policy, and a localized deployment guide.

When all of that is in place, “please deploy our app on Intune” becomes something a customer IT team can actually act on. Without it, even a technically functional app stalls at the procurement gate.

For the broader question of what language to use when shipping scripts through MDM platforms (which can complement Intune Win32 distribution for smaller fixes), see the companion post Choosing a Language for MDM Script Distribution.

That’s all from the Gemba, where we mapped out the software vendor playbook for distributing Windows desktop apps through customer Intune tenants.

References