The vendor sends a download link, the tech double-clicks it, and the pilot machine gets its app. Then the same file has to land on 200 devices overnight with nobody clicking Next. Whether that works depends on what you were sent: an MSI file, or an EXE that might be wrapping one.
What an MSI File Is
An MSI file is a database, not a program. It holds tables that describe files, registry keys, shortcuts, services and the order the Windows Installer service (msiexec.exe) should apply them in. The engine reads the package and does the work, which is why every MSI installs, logs, repairs and uninstalls the same way.
That engine ships with Windows. Microsoft's Windows Installer documentation puts version 5.0 in every release from Windows 7 and Server 2008 R2 onward, with no redistributable to chase. A package can be authored to install per machine or per user, and since version 4.5 the engine can install several packages as one transaction and roll all of them back if one fails.
Three things inside the package matter for deployment: the product code (a GUID you uninstall and detect by), public properties (capitalized switches like ALLUSERS that you set on the command line), and transforms (.mst files that edit the database at install time).
What an EXE Installer Is
An EXE installer is whatever the vendor decided to compile. It might be a thin bootstrapper that checks prerequisites and then runs an MSI it carries inside. It might be an Inno Setup or NSIS program that copies files itself and writes its own uninstall entry. It might be a self-updating app that installs into the user's profile and never asks for admin rights at all.
No shared engine means no shared command line. Each framework has its own silent switch, logging flag and exit codes, and a vendor can drop any of them. The first job with any EXE is finding out which framework built it.
| Framework | Silent switch | Notes from the framework's docs |
|---|---|---|
| Windows Installer bootstrapper | Usually /quiet or /qn passed through | Check the vendor's enterprise deployment guide |
| Inno Setup | /VERYSILENT /SP- /SUPPRESSMSGBOXES /NORESTART | /LOG writes a log to the user's Temp; /SILENT still shows a progress window |
| NSIS | /S | Case-sensitive; /D=path must be last and unquoted |
| Self-updating apps (browser-style) | Often an MSI or "enterprise" build on a separate page | The consumer EXE may install per user only |
MSI vs EXE for Silent Deployment
On one laptop the difference barely matters. For MSI vs EXE across a fleet, it decides how much work the package needs before it's ready.
| What you need | MSI | EXE |
|---|---|---|
| Silent install | Same switches every time: /qn or /quiet | Depends on the framework; sometimes not documented |
| Logging | Built in: /L*v path.log | Only if the framework offers it |
| Uninstall | msiexec /x by product code | Whatever the vendor wrote into UninstallString |
| Detection | Product code in the registry | File version or a registry key you find yourself |
| Group Policy software installation | Supported | Not supported without repackaging |
| Customization | Transforms and public properties | Config files, answer files or nothing |
| Repair | msiexec /f | Usually reinstall |
Group Policy is the hard line. Microsoft's guide to installing software through Group Policy works with Windows Installer packages on a network share, assigned to computers or users. An EXE doesn't fit that path, which is why exe-to-msi repackaging tools exist.
The EXE column is a lack of guarantees, not a failure. A well-built Inno Setup installer with a documented uninstall string deploys fine. The problem is the EXE you know nothing about, from a vendor whose deployment guide is a screenshot of a wizard.
The msiexec Switches Worth Memorizing
Microsoft documents two spellings: the classic options (/i, /x, /qn, /L*v) and the standard ones added with Windows Installer 3.0 (/package, /uninstall, /quiet, /log). They do the same thing; the classic form is what deployment tools show.
text:: install, no UI, no reboot, verbose log msiexec /i "C:\pkg\app.msi" /qn /norestart /L*v "C:\logs\app-install.log" :: install with a transform and a public property msiexec /i "C:\pkg\app.msi" TRANSFORMS="C:\pkg\corp.mst" ALLUSERS=1 /qn :: uninstall by product code msiexec /x {AAD3D77A-7476-469F-ADF4-04424124E91D} /qn /norestart :: repair, forcing every file back msiexec /fa {AAD3D77A-7476-469F-ADF4-04424124E91D} /qn
The reboot switch matters more than it looks. Per Microsoft's reference, /quiet with no reboot option lets the installer restart the machine whenever it decides to, with no prompt. Always pair it with /norestart and handle reboots yourself.
The log folder must already exist; /L won't create it, and a missing folder fails with 1622 before the install starts. To catch an install that fails before you can pass a switch, Microsoft's registry method (a Logging value of voicewarmupx under HKLM\Software\Policies\Microsoft\Windows\Installer) logs every MSI run to %temp% as Msi*.log until you remove it.
Exit codes are where deployment scripts get written wrong. These come from Microsoft's msiexec error reference:
| Code | Meaning | Treat as |
|---|---|---|
| 0 | Completed | Success |
| 3010 | Completed, restart required | Success, schedule a reboot |
| 1641 | Completed, installer started a restart | Success |
| 1618 | Another installation is already in progress | Retry later |
| 1603 | Fatal error during installation | Failure, read the log |
| 1638 | Another version of this product is installed | Failure, uninstall or upgrade first |
| 1619 | Package couldn't be opened | Failure, check the path and permissions |
A script that treats anything but 0 as failure will report a healthy 3010 install as broken on every machine that needs a reboot. Our PowerShell commands guide covers wrapping msiexec with Start-Process and reading the exit code from the ticket you're on.
This r/sysadmin thread digs into why vendors keep writing msiexec /I{GUID} into UninstallString instead of /X, and why that trips silent uninstalls:
Getting the MSI Out of an EXE
Before extracting anything, look for the MSI the vendor already publishes. Consumer downloads often have an enterprise or "for IT admins" page with an MSI, an offline installer or a documented silent switch, and that page saves the rest of this section.
If there's no MSI, the EXE may still be carrying one. Working practice, not a Microsoft-documented procedure: run the EXE until the first wizard screen and look in %temp% (and the folders under it) for a fresh .msi, since bootstrappers unpack there before calling msiexec. Some bootstrappers document an extract switch such as /extract or /a with a path. Archive tools can open some EXE containers directly. Whichever way it comes out, test the extracted MSI on its own, because the bootstrapper may have been passing properties or installing a prerequisite you'll now have to handle yourself.
Repackaging (recording an install and generating a new MSI) is the last resort. It captures whatever the installer did on the capture machine, drivers and services included, and the vendor won't support the result.
The thread below is a technician hunting for the MSI inside a vendor EXE, with the usual answers about Temp folders, extract switches and when to stop looking:
Transforms and Properties
A transform is how you change an MSI without editing it. Microsoft's TRANSFORMS property takes a semicolon-separated list of .mst files, applied in order, at every install and repair of the package. You build one in a table editor (Orca from the Windows SDK, or a third-party equivalent), save the differences, and pass the file on the command line.
Typical edits are the ones vendors never expose as switches: a license key, auto-update off, no desktop shortcut, your server address. Public properties cover some of these, and the property table inside the MSI lists them when the vendor's guide doesn't. One rule from Microsoft's reference: the installer needs the transform at every install and repair, so keep it next to the MSI on the share, not on a technician's desktop.
Packaging for Intune and RMM
Intune has two ways to take an MSI. The line-of-business app type accepts a single MSI with one command-line argument and nothing else; Microsoft's own guidance points anything more complex at Win32 app management. Win32 apps take the .intunewin format, built with the Microsoft Win32 Content Prep Tool:
textIntuneWinAppUtil.exe -c C:\pkg\app -s app.msi -o C:\intunewin -q
For an MSI source the tool reads the product code and fills in the install and uninstall commands. For an EXE you write both yourself, which is where the framework table above earns its keep. Two limits from Microsoft's documentation: 30 GB per app, and the install has to be silent, because Intune won't run anything that waits for a user.
Return codes follow the same logic as the msiexec table. Intune's defaults treat 0 and 1707 as success, 3010 as a soft reboot, 1641 as a hard reboot and 1618 as retry. An EXE that returns something else on success needs its code added to that list, or every install shows as failed.
Detection is the other half. For an MSI, the product code is the detection rule. For an EXE, you pick a file version or a registry key that only exists after a good install, and you check it by hand on a clean machine before the assignment goes live. Our Intune for MSPs review covers where the Win32 app model stops.
RMM tools follow the same pattern with fewer guardrails: a script downloads the package, runs the command line and reports the exit code. OpenFrame can run that script across a client's devices and collect each machine's output, so a 3010 on twelve laptops shows up as one list.
Allowlisting changes the picture on locked-down fleets. If WDAC or Smart App Control is enforcing, an unsigned installer stops before any switch is read, and the fix is a signed package or a rule, not a different command line.
Here's a walkthrough of silent MSI installs with msiexec, including the switches above:
Where MSIX Fits
MSIX is Microsoft's newer format and a different animal from both. Microsoft's April 2026 overview describes a signed, containerized package with a clean uninstall and differential updates in 64 KB blocks, deployable through Intune and Configuration Manager. Every MSIX must be signed before it installs. For the app you were sent this morning it's mostly irrelevant: you can only deploy MSIX for software that ships as MSIX or that you've converted with the MSIX Packaging Tool and tested in the container.
The Short Version
An MSI file gives you one command line, one log format, one uninstall method and Group Policy support, all from the Windows Installer engine. An EXE gives you whatever its framework gives you, which ranges from fully documented to nothing. Ask for the MSI first, learn the msiexec switches and exit codes, and package for Intune or your RMM with a detection rule you've tested. Next, read our post on software deployment tools for the systems that push these packages, and the WDAC guide for what happens when the installer isn't signed.
FAQ
Is an MSI file safe to run?
An MSI is as safe as its publisher. It's a package format, and malware has shipped in MSI files as well as EXEs. Check the digital signature, download from the vendor's own site, and deploy through a tool that logs what ran.
Why does my silent MSI install still show a dialog?
Either the switch didn't reach msiexec (a bootstrapper EXE may not pass /qn through) or a custom action inside the package opens its own window. Run the MSI directly with /qn and /L*v, then read the log for the action that fired.
What does exit code 1618 mean?
Another installation is already in progress. Windows Installer runs one install at a time, so a script that launches two MSIs back to back, or runs while Windows Update is installing, gets 1618. Wait and retry; don't count it as a failure.
Can I convert an EXE to an MSI?
Yes, with a repackaging tool that captures the install and builds a new package. It works, but the result is your package, not the vendor's, and it can capture things you didn't want. Look for a vendor MSI or an extractable one first.
Dmytro Koval
Head of Product Engineering
Hi! My name is Dmytro, but everyone calls me Dima. I’m a Software Developer and together with the development team, I help bring Flamingo to life — putting it on its feet from a technical perspective. Originally from Lviv, Ukraine 🇺🇦, but currently based in Spain, where I’ve been enjoying the blend of great weather, culture, and nature. I’m passionate about the mountains and love traveling — exploring new places and cultures really inspires me. These experiences constantly recharge me and give me a fresh perspective, both personally and professionally.
