Skip to content
Latchkey

winget install: Windows Package Manager in CI

winget install adds a package from the Windows Package Manager; for CI you pass --silent plus the two --accept agreement flags so it never blocks on a prompt.

winget is Microsoft's built-in package manager. It is reliable on interactive Windows but needs explicit agreement and silent flags to behave unattended in a pipeline.

What it does

winget install resolves a package by name or id and runs its installer. By default it can prompt to accept a package or source license agreement; CI must pre-accept both. Use -e --id to match an exact package id and avoid ambiguous-name failures.

Common usage

PowerShell
winget install -e --id Git.Git \
  --silent \
  --accept-package-agreements \
  --accept-source-agreements

# pin a version
winget install -e --id Microsoft.PowerShell --version 7.4.1 \
  --silent --accept-package-agreements --accept-source-agreements

Options

FlagWhat it does
-e, --exactMatch the id/name exactly (no fuzzy match)
--id <id>Select the package by its winget id
--silent / -hRun the installer with no UI
--accept-package-agreementsPre-accept the package license
--accept-source-agreementsPre-accept the source (msstore) terms
--version <v>Install a specific version

In CI

winget is not always available on hosted runners or in non-interactive Windows Server sessions because it ships with the App Installer; verify it exists or fall back to choco. Always pass -e --id; a bare name can match multiple packages and fail.

Common errors in CI

"No package found matching input criteria" means the id is wrong or -e rejected a fuzzy match; check winget search. The installer hanging usually means a missing --silent or one of the --accept-* flags, so winget waited on a prompt. "winget is not recognized" means App Installer is absent (common in containers and Server Core); install it or use another package manager.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →