Skip to main content

Package Management

Learn how to effectively manage software packages using WinGet, from basic installation to advanced dependency handling and batch operations.

Installing Packages

Basic Installation

Install a package using its exact identifier:
winget install --id Microsoft.PowerToys
Install a specific version:
winget install powertoys --version 0.15.2

Installation Options

Choose between user or machine-level installation:
# Install for current user only
winget install --id Git.Git --scope user

# Install for all users (requires admin)
winget install --id Git.Git --scope machine
Control installer interaction:
# Silent installation (no UI)
winget install --id Microsoft.VisualStudioCode -h

# Interactive installation
winget install --id Microsoft.VisualStudioCode -i
Specify where to install (if supported by the package):
winget install --id Contoso.App --location "C:\CustomApps"

Advanced Installation

1

Search for the Package

Find the exact package identifier:
winget search "visual studio code"
2

Review Package Details

Check available versions and metadata:
winget show --id Microsoft.VisualStudioCode
3

Install with Options

Combine multiple options for precise control:
winget install --id Microsoft.VisualStudioCode \
  --version 1.85.0 \
  --scope user \
  --architecture x64 \
  --locale en-US \
  --accept-package-agreements

Upgrading Packages

Single Package Upgrade

Upgrade a specific package to the latest version:
winget upgrade --id Microsoft.PowerToys
Upgrade to a specific version:
winget upgrade powertoys --version 0.75.0

Bulk Upgrades

List all available updates:
winget upgrade
Upgrade all packages at once:
winget upgrade --all
When using --all, packages with blocking pins will be skipped. Use --include-pinned to override non-blocking pins.

Upgrade Strategies

# Only upgrade packages with known current versions
winget upgrade --all

Managing Dependencies

Dependency Types

WinGet supports four types of dependencies as defined in package manifests:

Windows Features

System features like .NET Framework, IIS, or WSL

Windows Libraries

Runtime libraries like Visual C++ Redistributables

Package Dependencies

Other packages from the same source

External Dependencies

Dependencies from outside the package source

Handling Dependencies During Installation

By default, WinGet automatically installs package dependencies:
winget install --id Contoso.App
Dependencies are recursively resolved and installed from the same source as the parent package.

Skipping Dependencies

Skip dependency installation when needed:
winget install --id Contoso.App --skip-dependencies
Make this the default in settings.json:
{
  "installBehavior": {
    "skipDependencies": true
  }
}

Dependency Source Control

Specify a different source for dependencies:
winget install --id Contoso.App --dependency-source winget

Viewing Package Dependencies

Check what dependencies a package requires:
winget show --id Contoso.App
Look for the “Dependencies” section in the output.

Uninstalling Packages

Basic Uninstall

Remove a package by its identifier:
winget uninstall --id Microsoft.PowerToys
Uninstall using exact name matching:
winget uninstall "PowerToys" -e

Uninstall Options

For portable packages, control file removal:
# Remove only the executable
winget uninstall --id Contoso.PortableApp

# Remove all files and directories (purge)
winget uninstall --id Contoso.PortableApp --purge
Configure default behavior in settings:
{
  "uninstallBehavior": {
    "purgePortablePackage": true
  }
}
winget uninstall --id Contoso.App -h

Batch Operations

Export Installed Packages

Create a JSON file of all installed packages:
winget export -o packages.json
Export with specific versions:
winget export -o packages.json --include-versions
Export from a specific source only:
winget export -o packages.json --source winget

Import Package Lists

Install packages from an exported JSON file:
winget import -i packages.json
1

Prepare Import File

Edit the JSON file to include only desired packages:
{
  "$schema": "https://aka.ms/winget-packages.schema.2.0.json",
  "CreationDate": "2024-03-04T12:00:00.000-00:00",
  "Sources": [
    {
      "SourceDetails": {
        "Name": "winget",
        "Identifier": "Microsoft.Winget.Source_8wekyb3d8bbwe",
        "Argument": "https://cdn.winget.microsoft.com/cache",
        "Type": "Microsoft.PreIndexed.Package"
      },
      "Packages": [
        {
          "PackageIdentifier": "Microsoft.PowerToys",
          "Version": "0.75.0"
        },
        {
          "PackageIdentifier": "Microsoft.VisualStudioCode"
        }
      ]
    }
  ]
}
2

Run Import with Options

# Install latest versions, ignore versions in file
winget import -i packages.json --ignore-versions

# Skip packages that are unavailable
winget import -i packages.json --ignore-unavailable

# Don't upgrade existing packages
winget import -i packages.json --no-upgrade
3

Accept Agreements

Auto-accept all license agreements:
winget import -i packages.json \
  --accept-package-agreements \
  --accept-source-agreements

Common Batch Scenarios

# Export from reference machine
winget export -o dev-environment.json --include-versions

# Import on new machine
winget import -i dev-environment.json --accept-package-agreements

Portable Applications

Understanding Portable Packages

Portable packages are standalone executables without traditional installers. WinGet manages them by:
  • Copying the executable to a managed directory
  • Creating symlinks in PATH for command-line access
  • Registering in Windows Apps & Features

Installing Portable Apps

winget install --id Contoso.PortableApp
Customize the executable name:
winget install --id Contoso.PortableApp --rename myapp

Default Locations

%LOCALAPPDATA%\Microsoft\WinGet\Packages\<PackageId>\

Symlinks:
%LOCALAPPDATA%\Microsoft\WinGet\Links\

Customizing Portable Package Locations

Set custom root directories in settings.json:
{
  "installBehavior": {
    "portablePackageUserRoot": "C:/Users/YourName/Packages",
    "portablePackageMachineRoot": "C:/Program Files/Packages/Portable"
  }
}
Paths must be absolute. The package identifier is automatically appended as a subdirectory.

Package Pinning

Preventing Unwanted Upgrades

Pin a package to its current version:
winget pin add --id Microsoft.PowerToys
Pin to a specific version:
winget pin add --id Microsoft.PowerToys --version 0.70.0

Pin Types

Completely prevents upgrades:
winget pin add --id Contoso.App --blocking
Even winget upgrade --all will skip this package.
Allows manual override:
winget pin add --id Contoso.App
Can be upgraded with --include-pinned flag:
winget upgrade --all --include-pinned

Managing Pins

List all pinned packages:
winget pin list
Remove a pin:
winget pin remove --id Microsoft.PowerToys
Reset all pins:
winget pin reset --all

Advanced Workflows

Local Manifest Installation

Install from a local YAML manifest file:
winget install --manifest ./path/to/manifest.yaml
Local manifest installation must be enabled via Group Policy or settings. See Group Policy Guide for details.

Override Installer Behavior

Pass custom arguments to the installer:
winget install --id Contoso.App --override "/SILENT /DIR=C:\Custom"
Add arguments to defaults (don’t replace):
winget install --id Contoso.App --custom "/LOG=C:\install.log"

Architecture Selection

Force a specific architecture:
# Install ARM64 version on compatible systems
winget install --id Contoso.App --architecture arm64

# Force x86 on x64 system
winget install --id Contoso.App --architecture x86

Locale Preferences

Install specific language version:
winget install --id Contoso.App --locale fr-FR
Set default locale preferences in settings:
{
  "installBehavior": {
    "preferences": {
      "locale": ["en-US", "fr-FR"]
    }
  }
}

Troubleshooting

Hash Validation Failures

If installer hash doesn’t match:
# Force installation (use with caution)
winget install --id Contoso.App --force

# Or ignore security hash check
winget install --id Contoso.App --ignore-security-hash
Bypassing hash validation reduces security. Only use for trusted sources.

Archive Malware Scan Issues

For local archive installations:
winget install --manifest ./package.yaml \
  --ignore-local-archive-malware-scan

Installation Logs

View detailed logs for troubleshooting:
# Enable verbose logging
winget install --id Contoso.App --verbose-logs

# Open log directory
winget install --id Contoso.App --logs
Logs are stored in: %TEMP%\AICLI\*.log

Resume Failed Installations

Enable resume experimental feature in settings:
{
  "experimentalFeatures": {
    "resume": true
  },
  "installBehavior": {
    "maxResumes": 3
  }
}

Best Practices

Use Exact Matching

Always use --id with -e flag to avoid ambiguity:
winget install --id Git.Git -e

Accept Agreements Explicitly

Use flags instead of interactive prompts for automation:
winget install --id Contoso.App \
  --accept-package-agreements \
  --accept-source-agreements

Version Control Your Environment

Regularly export your package list:
winget export -o backup.json --include-versions

Test Before Production

Test package installations in non-production environments first, especially with --all upgrades.

Configuration Files

Customize WinGet behavior with settings.json

Private Sources

Set up enterprise package repositories

Group Policy

Manage WinGet in enterprise environments

Build docs developers (and LLMs) love