WIN-011 · Script
Software Package Deployment
Installs, updates, or removes one approved MSI or EXE software package silently, with optional file hash verification.
What it does
Deploys a single software package that you supply, from a local path, a network share, or an HTTPS download link. Before installing, it checks the uninstall registry for an app whose display name matches -AppName and compares the installed version with -Version, so devices that are already current are skipped. When -ExpectedSha256 is set, the file hash must match before anything runs, which helps make sure only the approved file is used.
Report mode (default) only checks and logs what -Action would do. Apply mode runs it: Install installs the package when it is missing or older than -Version (also updates)
- Remove: uninstalls the app that matches -AppName, using the MSI product code when there
is one, or the app's own quiet uninstall command
MSI packages run with msiexec /qn /norestart unless you supply other arguments. EXE packages need the vendor's silent switches in -InstallArgs. Exit code 3010 (restart required) is treated as success and logged as a warning. This script never restarts the device. Runs silently as SYSTEM from any RMM or Intune. No prompts.
Requirements
Windows PowerShell 5.1+, run as SYSTEM or local admin
How to run it
- Run as: SYSTEM or a local administrator
- Run from: any RMM or MDM, Intune, a Group Policy startup script, a scheduled task, or an elevated PowerShell window
- Script type: PowerShell, 64-bit
- User interaction: none; the script never prompts
- Timeout: 10 minutes (30 for Windows Update installs)
Settings
| Name | What it does | Options | Default |
|---|---|---|---|
| Mode | Report (default) = check only and log what would happen. Apply = make the change. | Report, Apply | Report |
| Action | Install (default) = install or update the package. Remove = uninstall the app. | Install, Remove | Install |
| AppName | Display name to look for in installed apps, wildcards allowed, for example "Google Chrome" or "7-Zip*". Required for every mode. | ||
| Version | Target version, for example "24.08". Install skips devices that already have this version or newer. Leave empty to install only when the app is missing. | ||
| PackagePath | The installer file: a local path (C:\Installers\app.msi), a share (\\server\apps\app.exe) or an HTTPS link. Needed for -Action Install. | ||
| InstallArgs | Silent install arguments. For MSI the default is "/qn /norestart". For EXE use the vendor's switches, for example "/S" or "/quiet /norestart". | ||
| UninstallArgs | Extra arguments added to an EXE uninstall command when the app has no quiet uninstall command, for example "/S". MSI removals always use /qn /norestart. | ||
| ExpectedSha256 | Optional SHA-256 hash of the approved installer. If set and the file does not match, nothing is installed. | ||
| SuccessCodes | Extra installer exit codes to treat as success, for example 1641. 0 and 3010 are always treated as success. | (none) | |
| TimeoutMinutes | How long to wait for the installer or uninstaller before giving up. Default 30. | 30 |
Exit codes
- 0 = Already compliant, or install/removal succeeded
- 1 = Report: change needed. Apply: installer failed, hash mismatch or app not found
- 2 = Script error
Testing steps
- Run it first with the mode set to Report on one test device. Nothing is changed in that mode.
- Read the log and confirm the planned changes are what you expect.
- Run your chosen settings on the same test target and confirm the result.
- Check the exit code: 0 = OK, 1 = needs attention, 2 = error (see log), 9 = this copy is past its Valid until date.
- Roll out to a small group next, then everyone.
Rollback steps
To undo an install, run the script again with -Mode Apply -Action Remove and the same -AppName. To undo a removal, run it with -Action Install and the original installer. Updates cannot be rolled back automatically; reinstall the older version from its installer if needed.
Version and change log
| Version | Date | Changes |
|---|---|---|
| 1.0.0 | November 2026 | First release. |