Skip to content

Add Microsoft 365 Office apps (Excel, Access, OneNote, Outlook, PowerPoint, Word) as Windows Fleet-maintained apps#38826

Closed
allenhouchins wants to merge 5 commits into
mainfrom
allenhouchins-excel-fma-windows
Closed

Add Microsoft 365 Office apps (Excel, Access, OneNote, Outlook, PowerPoint, Word) as Windows Fleet-maintained apps#38826
allenhouchins wants to merge 5 commits into
mainfrom
allenhouchins-excel-fma-windows

Conversation

@allenhouchins

@allenhouchins allenhouchins commented Jan 27, 2026

Copy link
Copy Markdown
Member

Summary

Adds the Microsoft 365 Office suite as Fleet-maintained apps for Windows: Excel, Access, OneNote, Outlook, PowerPoint, and Word.

All six install via the Office Deployment Tool (ODT) winget package (Microsoft.OfficeDeploymentTool). Each app's install script extracts ODT, detects any Office apps already present, and runs a generated config.xml that installs the target app while preserving the rest. The uninstall script reconfigures ODT to exclude the target app, removing Office entirely only when no other suite apps remain.

Notes / gotchas

  • ODT installer architecture flipped x64 → x86. Microsoft relabeled the ODT winget installer from x64 to x86 in every manifest after 16.0.19426.20170, which broke the original Excel input. Switched installer_arch to x86 — the ODT self-extractor is architecture-neutral; the config XML's OfficeClientEdition="64" is what installs 64-bit Office. Regenerated against the latest ODT build (16.0.19929.20090).
  • Version-skip in the validator. ODT-installed Office apps report the Microsoft 365 build version, which never matches the ODT installer version. Generalized the previous hard-coded Excel check into a shared officeODTApps map in cmd/maintained-apps/validate/windows.go so existence is verified without a version comparison for all six apps.
  • EXE installers treated as machine-scope in the winget ingester (carried over from the original Excel change).
  • Access is Windows-only — it has no macOS counterpart and no existing UI icon (see below).
  • sha256 is no_check / ignore_hash because the ODT self-extractor is a thin bootstrapper.

Open item

  • Access UI icon is missing (frontend/pages/SoftwarePage/components/icons). The other five share an icon with their existing macOS entries. Access needs a MicrosoftAccess icon generated from a PNG before merge (no .app bundle exists since it's Windows-only).

🤖 Generated with Claude Code

Introduces managed app support for Microsoft Excel on Windows, including input definition, install/uninstall PowerShell scripts, and output metadata. Updates the ingester to treat EXE installers as machine-scoped for managed deployments.
fleet-release
fleet-release previously approved these changes Jan 27, 2026
Updated the Windows app validation logic to skip version checks for Microsoft Excel when installed via Office Deployment Tool, as the ODT version does not match the installed Excel version. Also reformatted the categories array in the Excel winget input JSON for consistency.
@codecov

codecov Bot commented Jan 27, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 0% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 67.03%. Comparing base (6313e75) to head (bc284ac).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
ee/maintained-apps/ingesters/winget/ingester.go 0.00% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #38826      +/-   ##
==========================================
- Coverage   67.04%   67.03%   -0.02%     
==========================================
  Files        2894     2895       +1     
  Lines      225026   225243     +217     
  Branches    11772    11772              
==========================================
+ Hits       150867   150983     +116     
- Misses      60489    60588      +99     
- Partials    13670    13672       +2     
Flag Coverage Δ
backend 68.73% <0.00%> (-0.02%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@allenhouchins allenhouchins changed the title Add Microsoft Excel (Windows) managed app support Add Microsoft Excel as a Fleet-maintained app for Windows Jan 27, 2026
allenhouchins and others added 2 commits June 8, 2026 10:45
…uite

Microsoft relabeled the Office Deployment Tool winget installer from x64 to
x86 in every manifest after 16.0.19426.20170, so the Excel input could no
longer resolve an installer. Switch installer_arch to x86 (the ODT
self-extractor is architecture-neutral; the config XML's
OfficeClientEdition="64" still installs 64-bit Office) and regenerate against
the latest ODT build.

Also generalize the validator's ODT version-skip from a hard-coded Excel check
to a shared officeODTApps map so the rest of the Office suite can reuse it.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…apps

Extends the Microsoft Excel (Windows) ODT pattern to the rest of the Office
suite. Each app installs via the Office Deployment Tool, preserving any other
Office apps already present, and uninstalls by reconfiguring ODT (removing
Office entirely only when no other suite apps remain).

All six apps share the OfficeDeploymentTool winget package and the
officeODTApps version-skip in the validator. Access is Windows-only and has
no macOS counterpart.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@allenhouchins allenhouchins changed the title Add Microsoft Excel as a Fleet-maintained app for Windows Add Microsoft 365 Office apps (Excel, Access, OneNote, Outlook, PowerPoint, Word) as Windows Fleet-maintained apps Jun 8, 2026
…ma-windows

# Conflicts:
#	cmd/maintained-apps/validate/windows.go
#	ee/maintained-apps/outputs/apps.json
@allenhouchins

Copy link
Copy Markdown
Member Author

Why we're not breaking Microsoft 365 apps into individual Windows FMAs (for now)

Goal

Take the Microsoft Excel (Windows) FMA pattern and extend it to the rest of the Microsoft 365 suite — Access, OneNote, Outlook, PowerPoint, and Word — as separate per-app Windows Fleet-maintained apps.

TL;DR

All of these apps install through the Office Deployment Tool (ODT), which deploys Microsoft 365 as a single Click-to-Run (C2R) suite. Windows registers that as one Add/Remove Programs entry (Microsoft 365 Apps for business - en-us), not one per app. Because osquery's programs table — the only source for Fleet's Windows software inventory and patch detection — never contains per-app names like Microsoft Excel, per-app FMAs can't be cleanly detected, versioned, or patched. The single-suite FMA (#43938) is the correct model for M365 subscriptions, so we're not shipping six per-app variants at this time.

What we confirmed about Fleet's FMA model

  • fleet_maintained_apps has a unique constraint on slug only; package_identifier is not stored and isn't used for identity or dedup. So six apps sharing Microsoft.OfficeDeploymentTool is not itself a problem.
  • "Added" state and inventory matching key on the app's unique_identifier / title name matched against the host's programs inventory. This is the field that matters — and it's where C2R breaks down.

The core blocker: Click-to-Run registers one suite entry

  • ODT with O365BusinessRetail installs the whole suite via C2R. Per Microsoft's own docs, individual app names only appear in Add/Remove Programs if the app was purchased as a standalone product; suite components never get their own entry.
  • osquery programs therefore only ever shows Microsoft 365 Apps for business - en-us (publisher Microsoft Corporation) — never Microsoft Excel, Microsoft Word, etc.
  • Result: a per-app exists query like SELECT 1 FROM programs WHERE name = 'Microsoft Excel' can never match on a real host.

Why "Excel was passing validation" was misleading

The Excel-only CI run passed, but not because per-app detection worked. The validator matches a programs row by name or by a freshly-detected install directory:

WHERE LOWER(name) LIKE '%Microsoft Excel%' OR install_location LIKE '%<AppPath>%'
  • Validated alone on a fresh host, ODT created a new C:\Program Files\Microsoft Office folder → that path matched the suite entry's install_location → the officeODTApps version-skip returned true → green. It matched on the path, not the name.
  • Validated all six together, only the first install creates a new directory (they all share one Office install), so apps 2–6 produce "no changes detected," the path fallback is empty, the name clause can't match the suite entry, and every app fails.

So the per-app approach never truly worked — the single-app green check was an artifact of the validator's path fallback.

The version problem (breaks any patch policy)

The version the FMA pins (16.0.19929.20090) is the ODT tool version, not the installed Office build. The real Current Channel build is a different, higher number (e.g. 16.0.20026.20140 from clients.config.office.net). Because Fleet pins the ODT version, an auto-derived patched query (version_compare(version, '16.0.19929.20090')) compares against the wrong number — so patch status is meaningless. This is why the Excel FMA carries an existence-only version-skip, which makes the patch policy effectively "always patched."

Options we evaluated

Option Install Version Exists Patched Verdict
Single suite FMA (#43938) ✅ (suite build) ✅ (suite entry) ⚠️ ODT-version mismatch Correct for M365 subscription, but one app, not six
Suite detection, 6 apps ✅ but identical across all 6 ⚠️ Collapses per-app identity — adding one effectively flags all
Per-app file-table detection ✅ (file_version) ✅ genuinely per-app ⚠️→✅ only if version is fixed Possible, but needs ingester + validator changes
Perpetual standalone (Excel2024Retail, …) ✅ real per-app ARP entries Only clean per-app path, but perpetual license, won't activate under M365

There is no subscription standalone product ID for Access/Excel/PowerPoint/Word (verified against Microsoft's supported-product-ID list) — only perpetual 2021/2024 SKUs (plus evergreen OutlookRetail and free OneNoteFreeRetail), which are a different licensed product and conflict with an existing M365 install.

A working per-app design is technically possible — but not worth the cost now

We confirmed it could be done by combining:

  1. A per-app file-table exists query (…\Office16\EXCEL.EXE), which the patch generator already supports via file_version; and
  2. Fetching the real Current Channel build from https://clients.config.office.net/releases/v1.0/OfficeReleases (Monthly channel) and pinning that as the FMA version.

That delivers per-app install + version + exists + a meaningful patched policy. However, it requires:

  • New ingester logic to fetch and pin the Office build (shared code) and keep it current via the auto-update cron,
  • Validator changes to detect via exe path + file_version with a tolerant ("newer is fine") version check, since ODT always installs the latest build,
  • Hard-coded default 64-bit install paths and a hard dependency on Channel="Current".

Decision

Given the complexity, the shared-code/validator changes, and the fragile assumptions, we're not breaking the M365 apps into individual Windows FMAs at this time. The single Microsoft 365 Apps suite FMA (#43938) covers Microsoft 365 subscription customers correctly. If per-app Windows FMAs are needed later, the realistic paths are (a) the file-table + Current-Channel-version design above, or (b) perpetual standalone products for organizations that actually hold perpetual Office licenses.

@allenhouchins allenhouchins deleted the allenhouchins-excel-fma-windows branch June 12, 2026 17:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants