Before you write another GPO workaround, check what one script can already do.
The Problem Nobody Talks About
Every sysadmin and IT-adjacent developer has been here: you need to deploy Microsoft 365 across a fleet of workstations, and the official Microsoft documentation sends you into a labyrinth of Office Deployment Tool downloads, XML config files, and cryptic setup.exe flags. It's 2025. This should not be a multi-hour yak-shave. Enter Install-Microsoft365 â a MIT-licensed PowerShell script sitting quietly at 61 stars that wraps the entire ODT workflow into a single, parameterized command. It's not glamorous. It doesn't have a slick landing page. But if you've ever manually crafted a configuration.xml file at 11pm before a mass deployment, this repo is going to feel like someone read your mind.
What It Actually Does
The script handles the full M365 install lifecycle in one shot: it dynamically fetches the latest Office Deployment Tool URL from Microsoft's website via the Get-ODTURL function (no hardcoded URLs that go stale), downloads it, generates or accepts a configuration XML, and runs the silent install. The default configuration bakes in sensible enterprise defaults â 64-bit, Current channel, O365ProPlusRetail, MatchOS language, AcceptEULA TRUE, and RemoveMSI to clean up legacy Office installs. That last one alone saves you a separate uninstall step that most people forget.
The real value is the parameter surface. You're not stuck with the defaults. Need to pin to SemiAnnual channel for a compliance-heavy environment? -Channel SemiAnnual. Deploying to a shared terminal server? -SharedComputerLic is right there. Want to skip Teams and Groove bloat? -ExcludeApps Teams,Groove handles it. The -LanguageIDs parameter accepts an array, so multilingual deployments aren't a special-case nightmare anymore.
Technical Deep-Dive
The architecture is straightforward but deliberately so. The Get-ODTURL and Get-XMLFile helper functions were extracted into a Helpers.psm1 module back in October 2022 â a refactor that signals the author thinks about reusability, not just one-off scripting. This matters for deployment scenarios: if you're staging this in a package manager or MDM pipeline, you can pull the module separately and compose it with your own tooling.
For the regex fix pushed in December 2024 (Get-ODTURL function), this is a meaningful maintenance signal. Microsoft occasionally changes the download page structure for the ODT, and a hardcoded scrape breaks silently â your deployment just fails and you have no idea why. The fact that this was caught and patched recently means someone is actually running this in production and keeping it honest.
The cleanest deployment path is through the PowerShell Gallery: Install-Script -Name Install-Microsoft365. From there, a full install with custom options looks like:
powershell
.\Install-Microsoft365.ps1 -Channel SemiAnnual -ExcludeApps Teams,Groove -IncludeVisio -OfficeArch 64
If you already have a battle-tested configuration.xml from a previous deployment, you just pass it directly: -ConfigurationXMLFile "./OfficeConfig.xml" and the script defers to it entirely. That's the right design â don't force people to relearn your abstractions when they already have working configs.
The -OfficeInstallerDownloadPath parameter is worth flagging for air-gapped or bandwidth-constrained environments. You can pre-stage the ODT download and point the script at it, skipping the web fetch entirely. This is not documented prominently, but it's a genuinely useful escape hatch for enterprise environments where outbound downloads during deployment are restricted.
Critical Take: Who Should NOT Use This
Let's be honest about the gaps. At 61 stars, this is a single-maintainer project. There's no organizational backing, no SLA, and no guarantee the Get-ODTURL regex won't break again the next time Microsoft redesigns their download page. If you're building a production MDM pipeline for thousands of seats, you probably want some