WinGet, the Windows Package Manager, makes installing, upgrading, and managing software on Windows fast, scriptable, and repeatable. When you need reliable unattended deployments, two topics matter more than anything else: avoiding install conflicts and getting the right silent switches. This guide shows you exactly how to do that—complete with practical examples, ready-to-use commands, YAML manifests, and PowerShell scripts you can copy and adapt.
Whether you’re building a golden image, pushing apps in bulk, wiring up CI/CD, or just trying to keep your tools quiet and predictable, this is your deep dive into handling WinGet install conflicts and silent installs like a pro.
Overview of the Use Case
-
What this is about: You want consistent, unattended installs and upgrades using WinGet across different Windows environments, without pop-ups, dialog boxes, or “installer not found” errors. That requires understanding how WinGet chooses installers, how to pass the correct silent switches, and how to resolve conflicts when multiple installers, sources, or versions exist.
-
Typical scenarios:
- Fresh OS build or VDI provisioning: Preload a standard toolset silently (browsers, runtime frameworks, dev tools).
- Bulk rollouts or upgrades: Push updates across many machines without user interaction.
- CI/CD pipelines: Ensure build agents have the exact tools and versions, silently and deterministically.
- Managed environments (Intune, Configuration Manager): Automate apps reliably with logs and quiet installs.
- Offline or restricted networks: Pre-download installers, verify hashes, and install from local manifests.
Quick Reference Table
| Command | Purpose | Example Output |
|---|---|---|
| winget –info | Show WinGet version and system details | Windows Package Manager v1.x.x |
| winget search |
Find package IDs and installers | Name Id Version Source |
| winget show –id |
Display manifest details, switches, installers | Installer Type: exe; Silent: /S |
| winget install –id |
Silent install with exact match | Successfully installed |
| winget install –id |
Pass custom installer arguments | Starting package install… |
| winget upgrade –all –silent | Upgrade all available packages quietly | Upgrading 5 packages |
| winget uninstall –id |
Uninstall exact package | Successfully uninstalled |
| winget export -o packages.json | Export installed packages to JSON | Exported 27 packages |
| winget import -i packages.json –silent | Bulk install from export list silently | Installing package 1/27 |
| winget source reset –force | Rebuild package index to fix source errors | Resetting sources… |
| winget pin add –id |
Pin app version to avoid unwanted upgrades | Pinned 1 package |
| winget download –id |
Download installer for offline use | Saved installer to C:\Cache |
Key Concepts and Prerequisites
WinGet CLI and version
- Install from Microsoft Store (App Installer) or via official channels.
- Check your version and environment:
- Command:
winget –info - Why it matters: Some features (like pins, import/export, or download) require newer WinGet versions. Update if you’re missing commands or flags.
- Command:
Administrator privileges
- Many installs require elevation. If a command “works” but silently does nothing, you may not be elevated.
- Run PowerShell or CMD “as Administrator” or use a scheduled task running with highest privileges.
Sources and trust
- Default sources include winget (Community) and msstore (Microsoft Store).
- Use:
- winget source list
- winget source update
- winget source reset –force
- If you run into indexing or trust errors, reset and update sources.
Installer types and silent behavior
- WinGet supports MSI, EXE (various frameworks like NSIS, Inno Setup, InstallShield), MSIX, and portable packages.
- Silent modes vary by installer type:
- MSI: Typically /qn (silent), /passive (with minimal UI).
- Inno Setup (EXE): /VERYSILENT /NORESTART.
- NSIS (EXE): /S or /SILENT (often /S).
- InstallShield (EXE): /s or /s /v”/qn”.
- MSIX: Provisioned silently by WinGet; may require user context or Store broker depending on package.
- The manifest often includes installerSwitches that WinGet uses when you pass –silent. You can override with –override to provide custom switches.
Manifests, YAML, and JSON
- Public WinGet manifests are YAML; import/export uses JSON lists.
- You can install from a local manifest (YAML) with winget install –manifest.
- Important YAML keys: PackageIdentifier, PackageVersion, InstallerType, Installers, InstallerSwitches, InstallerUrl, InstallerSha256, Architecture, InstallerLocale.
Exact matching and disambiguation
- When WinGet sees multiple matching packages or installers, use:
- –id and -e/–exact to nail the package
- –architecture (x64, x86, arm64)
- –scope (machine or user)
- –source (winget or msstore)
- –locale for language-specific installers
Accepting agreements and running non-interactively
- Use –accept-source-agreements and –accept-package-agreements to bypass prompts in scripts.
- Combine with –silent or –passive for unattended installs.
Step-by-Step Guide
- Identify the exact package and its installers
- Search and show details:
- Commands:
winget search “Visual Studio Code”
winget show –id Microsoft.VisualStudioCode -s winget - What to look for:
- InstallerType (msi, exe, msix)
- Available architectures (x64, x86)
- InstallerSwitches (Silent, SilentWithProgress, Custom)
- ProductCode (for MSI detection)
- Commands:
- Choose the correct installer variant and scope
- Narrow to the right installer before you run it:
- Example:
winget install –id Microsoft.VisualStudioCode –architecture x64 –scope machine –source winget -e
- Example:
- Use –exact to avoid matching “insider” or “portable” variants by accident.
- Plan your silent install strategy
- Try built-in silent:
- Command:
winget install –id Google.Chrome –silent –accept-package-agreements –accept-source-agreements -e
- Command:
- If the app still shows UI, check manifest switches:
- Command:
winget show –id Google.Chrome -e - Look under Installer Switches. If silent switches aren’t defined or don’t match your environment, override:
- EXE example:
winget install –id SomeVendor.SomeApp –override “/S /norestart” –accept-package-agreements -e - MSI example with transform:
winget install –id SomeVendor.SomeMsiApp –override “/qn TRANSFORMS=Custom.mst ALLUSERS=1” -e
- Command:
- Passive vs silent:
- –passive shows minimal UI (good for debugging).
- –silent suppresses UI (preferred for automation).
- Installer arguments precedence:
- If you pass –override, those arguments are used in addition to or instead of manifest defaults, depending on installer type. Always test on one machine first.
- Resolve pre-install conflicts
- Existing app installed from another source:
- List:
winget list –id-e - If a different edition or path conflicts, uninstall first:
winget uninstall –id-e
- List:
- Architecture mismatch:
- Specify –architecture x64 or x86 explicitly.
- Scope mismatch:
- If an app was installed per-user, reinstall per-machine (or vice versa):
winget install –id–scope machine -e –silent
- If an app was installed per-user, reinstall per-machine (or vice versa):
- Running processes:
- Close the app before upgrade, or use installer switches like /NORESTART and reboot later.
- Execute a reliable silent install
- Template for most installs:
- Command:
winget install –id <Publisher.App> -e –silent –accept-package-agreements –accept-source-agreements –scope machine
- Command:
- With custom arguments for EXEs:
- Command:
winget install –id <Publisher.App> -e –override “/S /v/qn” –silent –accept-package-agreements
- Command:
- Specific version pinning on install:
- Command:
winget install –id <Publisher.App> –version 1.2.3 -e –silent
- Command:
- Bulk installs with export/import
- Export current machine’s package list:
- Command:
winget export -o C:\Temp\packages.json
- Command:
- Import on a new machine silently:
- Command:
winget import -i C:\Temp\packages.json –silent –accept-package-agreements –accept-source-agreements
- Command:
- Tip: Edit packages.json to remove or pin items you don’t want.
- Use a local YAML manifest for precise control
- Create a local manifest that defines exact switches and installer:
- File: C:\Manifests\myapp.yaml
Contents showComments start with
PackageIdentifier: Contoso.MyApp
PackageVersion: 3.7.1
PackageLocale: en-US
Publisher: Contoso Ltd.
PackageName: Contoso MyApp
License: Proprietary
ShortDescription: Contoso MyApp with predefined silent switches
Installers:- Architecture: x64
InstallerType: exe
InstallerUrl: https://downloads.contoso.com/myapp-3.7.1-x64.exe
InstallerSha256: 8A6C6B35C0A53E0D…FAKEHASH…9DF8
InstallerSwitches:
Silent: /S
SilentWithProgress: /S
Custom: /norestart /log=”C:\Windows\Temp\myapp_install.log”
Scope: machine
InstallerLocale: en-US
InstallationNotes: >
Uses /S for silent and applies Custom switches for logging and no restart.
- Architecture: x64
- File: C:\Manifests\myapp.yaml
- Validate and install:
- Commands:
winget validate –manifest C:\Manifests\myapp.yaml
winget install –manifest C:\Manifests\myapp.yaml –silent –accept-package-agreements
- Commands:
- Use YAML when you need a repeatable, curated install with known switches and hashes.
- Handle upgrades and version pins
- Upgrade all silently:
- Command:
winget upgrade –all –silent –accept-package-agreements
- Command:
- Pin a package to a version range:
- Commands:
winget pin add –id–version 3.7.*
winget pin list
- Commands:
- Unpin when ready to move on:
- Command:
winget pin remove –id
- Command:
Troubleshooting
Common: Hash mismatch
- Symptoms: Error referencing installer hash mismatch.
- Why: Manifest hash doesn’t match downloaded file; stale cache or upstream vendor changed the binary.
- Fixes:
- winget source reset –force
- winget source update
- Try again:
winget install –id–silent -e - If you maintain your own manifest, recalc hash:
winget hash -f C:\Path\Installer.exe - Avoid bypassing security. Use any skip-hash option with extreme caution only when you trust the source.
Common: Multiple installers found / ambiguous input
- Symptoms: “Multiple installers found” or wrong variant installed.
- Fixes:
- Add -e/–exact and use precise –id:
winget install –id Git.Git -e –architecture x64 –scope machine –silent - Specify –architecture, –locale, or –source explicitly.
- Use:
winget show –id-e - to inspect available variants.
- Add -e/–exact and use precise –id:
Common: Source index errors or manifest not found
- Symptoms: “Source not available,” “Index corrupted.”
- Fixes:
- winget source reset –force
- winget source update
- winget list (to verify indexing works)
- Check network/proxy and retry.
Common: Installer UI pops up despite –silent
- Reasons:
- Manifest silent switches don’t match vendor’s current installer.
- EXE wrapper requires different switch syntax (/S vs /VERYSILENT).
- Fixes:
- Inspect switches:
winget show –id-e - Override:
winget install –id-e –override “/VERYSILENT /NORESTART” - Test with –passive first to confirm behavior.
- Inspect switches:
Common: UAC or elevation failures
- Symptoms: Install exits silently or writes to user scope.
- Fixes:
- Run PowerShell as Administrator.
- In automation, run Scheduled Task with “Run with highest privileges.”
Common: Reboot required or app in use
- Fixes:
- Use no-restart switches (/norestart) and reboot after the run.
- Close blocking apps. For scripts, detect and stop processes before install.
Common: Store (msstore) apps fail
- Fixes:
- Ensure user is signed into Microsoft Store (if required).
- Try the winget source instead, where applicable, or switch to MSI/EXE version.
Common: Proxy or firewall blocks
- Fixes:
- Configure system proxy:
netsh winhttp set proxy http://proxy:8080 - Ensure your security tooling allows installer downloads and code signing.
- Configure system proxy:
Automation Tips
PowerShell: resilient silent installs with overrides and logging
-
Script example that:
- Pins versions when desired
- Uses a per-app override map for silent switches
- Logs results and exits on errors you care about
Run PowerShell as Admin
$ErrorActionPreference = “Stop”
$log = “C:\Windows\Temp\wingetinstall$(Get-Date -Format yyyyMMdd_HHmmss).log”$apps = @(
@{ Id=”Git.Git”; Exact=$true; Scope=”machine”; Silent=$true },
@{ Id=”Microsoft.VisualStudioCode”; Exact=$true; Scope=”machine”; Silent=$true },
@{ Id=”VideoLAN.VLC”; Exact=$true; Scope=”machine”; Silent=$true }
)Per-app overrides when default manifest switches are insufficient
$overrides = @{
“VideoLAN.VLC” = “/S /norestart”
}foreach ($app in $apps) {
$args = @(“install”,”–id”,$app.Id,”–accept-package-agreements”,”–accept-source-agreements”)
if ($app.Exact) { $args += “-e” }
if ($app.Scope) { $args += @(“–scope”,$app.Scope) }
if ($app.Silent) { $args += “–silent” }
if ($overrides.ContainsKey($app.Id)) { $args += @(“–override”,$overrides[$app.Id]) }“Running: winget $($args -join ‘ ‘)” | Tee-Object -FilePath $log -Append
winget @args 2>&1 | Tee-Object -FilePath $log -Append
}
Schedule upgrades with Task Scheduler
- Create a scheduled task to run weekly as SYSTEM or an admin:
- Command:
schtasks /Create /TN “WinGet-Auto-Upgrade” /SC WEEKLY /D SUN /TR “powershell -NoProfile -ExecutionPolicy Bypass -Command winget upgrade –all –silent –accept-package-agreements” /RL HIGHEST /RU SYSTEM /F
- Command:
- Logs: Pipe output to a log file or Event Log for auditability.
Use in Intune (Microsoft Endpoint Manager)
- Options:
- Use the built-in WinGet app type (if available in your tenant). Search catalog, assign Required/Available, and let Intune manage install context and updates.
- Or wrap a PowerShell script using WinGet commands; run in system context; configure detection logic (e.g., display version from registry or winget list).
- For EXE apps needing custom switches, prefer a local manifest or –override.
CI/CD pipelines (GitHub Actions, Azure DevOps)
- Ensure runners have WinGet installed and are elevated (Hosted Windows runners typically are).
- Example GitHub Actions step:
- YAML:
- name: Install build tools
shell: pwsh
run: |
winget source update
winget install –id Git.Git -e –silent –accept-package-agreements
winget install –id Microsoft.VisualStudioCode -e –silent –accept-package-agreements
- name: Install build tools
- YAML:
- Pin versions for deterministic builds:
- winget install –id Git.Git –version 2.46.0 -e –silent
Offline or restricted networks
- Pre-download installers:
- Command:
winget download –id 7zip.7zip -o C:\PkgCache –accept-package-agreements
- Command:
- Create a local manifest pointing to the downloaded file with its InstallerSha256.
- Install from local manifest silently:
- Command:
winget install –manifest C:\Manifests\7zip.yaml –silent
- Command:
- Mirror a small private repository of installers and manifests to guarantee availability.
Best Practices
-
Prefer exact matches
- Always use –id with -e/–exact and specify –architecture and –scope when possible.
-
Verify silent switches before scaling
- Start with –passive to observe behavior, then switch to –silent.
- Keep a library of known-good switches per vendor.
-
Use version pinning for stability
- winget pin add –id
–version to lock critical tools. - Combine pins with scheduled winget upgrade –all to update only what’s safe.
- winget pin add –id
-
Maintain curated manifests for tricky apps
- For apps with poor or changing switches, maintain your own YAML with InstallerSwitches and known-good hashes.
- Validate with winget validate.
-
Keep sources healthy
- Periodically run winget source update.
- If behavior is odd, winget source reset –force.
-
Log everything in automation
- Redirect output to files; collect logs centrally when running at scale.
-
Respect security and integrity
- Avoid bypassing hash checks unless you fully control the source.
- Use InstallerSha256 in manifests; recalc if vendor updates files.
-
Test in a lab image
- Validate full runs (install, upgrade, uninstall) before wide rollout.
Conclusion
With the right approach, WinGet delivers consistent, unattended installs without the usual headaches. You’ve learned how to pick the correct installer, pass the right silent switches, avoid and resolve conflicts, and automate the whole workflow with PowerShell, Intune, and CI/CD. Start by testing a couple of packages using –silent and –override where needed, export your baseline, and grow a small library of curated manifests. WinGet is safe, powerful, and purpose-built for the job—once you master installer selection and silent modes, you’ll hardly need to touch a setup wizard again.
FAQ
What’s the difference between –silent and –passive?
- –silent aims for zero UI—no dialogs or progress bars—using the manifest’s Silent switches.
- –passive allows minimal UI (like a progress bar) but no prompts. It’s handy for validating behavior before going fully silent.
How do I find the correct silent switches for a package?
- First check the manifest:
- winget show –id
-e
- winget show –id
- If the manifest doesn’t list switches, check the vendor docs or test common patterns:
- MSI: /qn or /passive
- NSIS: /S
- Inno Setup: /VERYSILENT /NORESTART
- InstallShield: /s (and often /s /v”/qn”)
- Use –override to pass those switches explicitly.
Why does an install still show UI even when I use –silent?
- The vendor may have changed the installer or the manifest lacks correct switches. Inspect with:
- winget show –id
-e
- winget show –id
- Then try:
- winget install –id
-e –override “ “
- winget install –id
- Start with –passive to confirm behavior.
How can I install a specific version and prevent automatic upgrades?
- Install a specific version:
- winget install –id
–version 1.2.3 -e –silent
- winget install –id
- Pin it:
- winget pin add –id
–version 1.2.3
- winget pin add –id
What if I get a hash mismatch error?
- Update or reset sources, then retry:
- winget source update
- winget source reset –force
- If you own the manifest, recompute InstallerSha256:
- winget hash -f <installer.exe>
- Avoid disabling hash verification unless you fully trust and control the installer.
