The complete winget command reference, organised by what you're trying to do. Bookmark this — you'll come back.
Quick reference
winget search <query> # find packages
winget install <id> -e # install one
winget upgrade --all # update everything
winget uninstall <id> # remove
winget list # show what's installed
winget export file.json # save your setup
winget import file.json # restore on new machine
winget show <id> # see package details
winget settings # open user config
Search
Find packages in the catalog.
winget search firefox
winget search "visual studio"
winget search --tag editor
winget search --command python # apps that expose this CLI
winget search --moniker chrome # by short moniker
Useful flags:
| Flag | What it does |
|---|---|
-n, --name <text> |
Match name only |
--id <text> |
Match exact ID prefix |
--tag <text> |
Filter by tag |
--source <name> |
Restrict to one source (default: winget) |
--count <n> |
Limit results |
The CLI search is fine but slow for browsing. winget.tech/browse is faster, shows icons, and supports
publisher:,tag:,license:filters.
Install
winget install --id Microsoft.VisualStudioCode -e
Always use --id + -e (exact match) for scripts. Without -e, winget may interactively prompt to disambiguate.
| Flag | What it does |
|---|---|
-i, --interactive |
Show installer UI (no silent) |
-h, --silent |
Force silent (default for most) |
--scope user | machine |
Install per-user vs system-wide |
--architecture x64 | x86 | arm64 |
Pick installer arch |
--version <ver> |
Pin a specific version |
--locale en-US |
Pick locale |
--override "<args>" |
Pass raw args to underlying installer |
--location <path> |
Install into custom folder (rarely supported) |
--accept-package-agreements |
Skip EULAs |
--accept-source-agreements |
Skip source EULAs |
--force |
Bypass installer hash check (use with care) |
Example: pin a version
winget install --id OpenJS.NodeJS --version 20.18.0 -e
Example: install for current user only
winget install --id Microsoft.VisualStudioCode -e --scope user
Example: pass args to underlying installer
winget install --id Git.Git -e --override "/VERYSILENT /COMPONENTS=icons,assoc,gitlfs"
Upgrade
winget upgrade # list outdated
winget upgrade --all # upgrade everything
winget upgrade --id Git.Git -e # upgrade one
winget upgrade --include-unknown # include apps whose installed version is unknown
--include-unknown is important for apps where winget can't detect the installed version (often Microsoft Store apps or weird installers).
List
Show installed apps that winget knows about.
winget list
winget list --id Microsoft. # filter by ID prefix
winget list --tag editor
winget list --upgrade-available
Output includes a "Source" column. Apps installed outside winget show source as blank — winget can still uninstall many of them.
Uninstall
winget uninstall --id Mozilla.Firefox -e
winget uninstall --name "Old App"
winget uninstall --all-versions --id <id> -e # remove all versions if multiple
Show package details
winget show --id Microsoft.VisualStudioCode -e
winget show --id Python.Python.3.13 --versions # list available versions
Returns publisher, homepage, license, installer URL, dependencies, and supported architectures.
Export & import
The setup-saving superpower.
winget export -o my-apps.json
winget export -o my-apps.json --include-versions # pin exact versions
winget import -i my-apps.json
winget import -i my-apps.json --ignore-unavailable # skip missing apps
winget import -i my-apps.json --ignore-versions # latest instead of pinned
Tip: You don't need to install anything to generate an import file. Build one visually on winget.tech/script, pick "Winget Import (.json)", download.
Sources
Sources are where winget pulls manifests from. By default there are two:
winget— community + Microsoft catalogmsstore— Microsoft Store apps
winget source list
winget source update # refresh indexes
winget source reset # nuclear option if broken
winget source add <name> <url> # add a custom source (advanced)
source reset is the first thing to try when search starts misbehaving.
Settings
winget settings # opens settings.json in default editor
winget settings export # print to console
Useful tweaks for settings.json:
{
"$schema": "https://aka.ms/winget-settings.schema.json",
"source": {
"autoUpdateIntervalInMinutes": 5
},
"visual": {
"progressBar": "rainbow"
},
"experimentalFeatures": {
"configuration": true
},
"installBehavior": {
"preferences": {
"scope": "user",
"locale": ["en-US"]
}
}
}
installBehavior.preferences.scope = "user" is great — winget will prefer per-user installs when available, avoiding admin prompts.
Hidden / power flags
These exist but most guides don't mention them:
| Flag | Why you care |
|---|---|
--accept-package-agreements --accept-source-agreements |
Always pass these in scripts; otherwise winget hangs on EULAs |
--disable-interactivity |
Force non-interactive across the board |
--no-upgrade |
install will fail instead of upgrading if app is present |
--ignore-security-hash |
Bypass installer SHA mismatch (only if you trust the publisher) |
winget pin add <id>, winget pin list, winget pin remove |
Block a package from upgrade |
Pinning a version
winget pin add --id Docker.DockerDesktop --version "4.30.*"
Useful when a newer version breaks something and you don't want upgrade --all to bite you.
Scripting tips
When running winget in CI / scripts, always include:
--accept-package-agreements
--accept-source-agreements
--disable-interactivity
-e
…and run as administrator unless every package supports --scope user.
For idempotent installs (install if missing, no-op if present), use:
winget install --id <ID> -e --accept-package-agreements --accept-source-agreements --disable-interactivity
Winget will exit 0 if already installed at the same version.
Common gotchas
- Exit codes: a successful install returns
0. An "already installed" returns-1978335189(yes, really). Treat both as success in scripts. - No-network mode: catalog index lives in
%LOCALAPPDATA%\Packages\Microsoft.Winget.Source_*. Air-gapped installs require manually transferring this. - Concurrent installs: don't run multiple
winget installat once — they'll trip over the same installer engine. - Long IDs with dots: always quote in scripts:
--id "Microsoft.VisualStudio.2022.Community".
