If you’ve ever wished you could rebuild a Windows PC exactly the way you like it—from apps to settings to environment variables—using one file, this guide is for you. Microsoft’s Windows Package Manager, better known as winget, now includes a powerful configuration engine that lets you describe an entire machine in a single YAML file and apply it with one command. This article explains winget configure in depth, with practical, ready-to-use examples, commands, and scripts you can copy and adapt to your environment.
Overview of the Use Case
In plain language, winget configure lets you declare how a PC should be set up using a YAML file. You specify which applications to install (from the winget repository and beyond), what settings to apply, and other machine state items (like environment variables and optional packages). Then you run one command and Windows Package Manager orchestrates everything: downloads, installations, settings, and validations.
Common scenarios where winget configure shines:
- Fresh OS installs or device reimaging: Stand up a complete development or productivity environment from scratch.
- Bulk provisioning: Apply the same configuration to dozens or thousands of devices (IT, MSPs, classrooms, labs).
- Dev onboarding: Give new hires a single file that configures everything they need automatically.
- CI/CD runners and build agents: Ensure predictable, reproducible builds by pinning exact toolchain versions.
- Recovery and migration: Move to a new PC without missing a beat.
- Role-based setups: Maintain different YAMLs for developers, designers, support, etc., and apply the correct one as needed.
Quick Reference Table
| Command | Purpose | Example Output |
|---|---|---|
| winget –info | Check winget version and environment details | Windows Package Manager v1.x.x, Path: …, Logs: … |
| winget source list | List package sources | Name Arg Type Enabled; msstore https://… Microsoft.Rest… Yes |
| winget source update | Refresh package indexes | Updated source: winget; Updated source: msstore |
| winget source reset –force | Reset sources to defaults (fixes index corruption) | Successfully reset the sources |
| winget list | List installed apps known to winget | Name Id Version Source |
| winget upgrade –all –include-unknown | Upgrade everything possible | No applicable updates or Upgraded: 12 packages |
| winget configure –help | Show help for configuration | Usage: winget configure [options] |
| winget configure –file .\pc.yaml | Apply a configuration file | Applied 14/14 resources successfully |
| winget configure –file .\pc.yaml –silent –disable-interactivity –accept-package-agreements –accept-source-agreements | Apply unattended in automation | Applied 14/14 resources successfully (no prompts) |
| winget settings –open | Open the winget settings JSON | Opens settings in default editor |
Key Concepts and Prerequisites
- What is winget?
- winget is the Windows Package Manager CLI that installs, upgrades, and removes applications from trusted sources (like Microsoft’s Community repository and Microsoft Store) using simple commands and manifests.
- What is winget configure?
- A higher-level capability that applies a YAML configuration describing the desired state of a PC. It can install packages, run scripts/resources, and adjust settings in a repeatable way.
- Do you need admin rights?
- Some resources (e.g., machine-wide installs, system settings) require elevation. Run an elevated PowerShell or Command Prompt for best results when applying full-device configs.
- Required tools:
- Windows 10 1809+ or Windows 11
- Windows Package Manager (winget) 1.6+ included with the Microsoft Store “App Installer” app. Keep App Installer up-to-date.
- PowerShell is recommended for scripting and automation. Windows PowerShell 5.1 is built-in; PowerShell 7+ is great for cross-platform scripts and modern modules.
Check your version:
winget –info
Look for “Windows Package Manager” and ensure the version is recent. If it’s old, update the “App Installer” app from the Microsoft Store.
Step-by-Step Guide
1) Update sources and confirm winget is healthy
Run these first to make sure your system is in good shape:
winget –info
winget source list
winget source update
If you get errors about the source index, see Troubleshooting below for a quick reset.
2) Plan what you want to configure
Make a list of:
- Applications (by winget Ids, like Git.Git, Microsoft.VisualStudioCode, Python.Python.3.12)
- Whether you want user-scope or machine-scope installs
- Versions to pin (or allow latest)
- Extra installers you need (e.g., archive downloads)
- Environment changes (e.g., PATH additions)
- Any scripts to run (e.g., configuration after install)
Tip: You can discover package IDs via:
winget search git
winget show Git.Git
3) Create a configuration YAML
Below is a realistic example you can adapt. It installs a developer toolset, configures Node and Python, sets environment variables, and applies a few post-install steps.
Note: Comments begin with #. The schema URL helps editors validate the structure.
yaml-language-server: $schema=https://aka.ms/winget-configuration.schema.json
Purpose: Rebuild a Windows developer workstation from a single file.
Optional metadata for humans and pipelines
metadata:
name: Dev Workstation Base
version: 1.0.0
owner: YourTeam
description: Core apps, runtimes, and environment setup for devs.
Variables you can reuse across resources
variables:
VsCodeExtensions:
- ms-python.python
- ms-toolsai.jupyter
- ms-vscode.powershell
DevBin: C:\Dev\bin
PythonVersion: 3.12.
NodeVersion: 20.
Resources declare the desired state. The WinGetPackage resource installs apps by Id.
resources:
Git (machine scope, pinned to latest major with automatic upgrades later)
- resource: Microsoft.WinGet.DSC/WinGetPackage
id: Git.Git
ensure: Present
source: winget
scope: machine
installedCheck: Default
Visual Studio Code (user scope)
- resource: Microsoft.WinGet.DSC/WinGetPackage
id: Microsoft.VisualStudioCode
ensure: Present
source: winget
scope: user
Python pinned to a compatible version range
- resource: Microsoft.WinGet.DSC/WinGetPackage
id: Python.Python.3.12
ensure: Present
source: winget
version: ${{ variables.PythonVersion }}
scope: machine
Node.js LTS pinned to major version 20
- resource: Microsoft.WinGet.DSC/WinGetPackage
id: OpenJS.NodeJS.LTS
ensure: Present
source: winget
version: ${{ variables.NodeVersion }}
scope: machine
7-Zip to handle archives
- resource: Microsoft.WinGet.DSC/WinGetPackage
id: 7zip.7zip
ensure: Present
source: winget
scope: machine
Create a tools directory
- resource: Microsoft.WinGet.DSC/Directory
path: ${{ variables.DevBin }}
ensure: Present
Add DevBin to PATH for the current machine
- resource: Microsoft.WinGet.DSC/Environment
name: PATH
ensure: Present
value: ${{ variables.DevBin }}
scope: machine
operation: Add # Add, Remove, or Set (depending on resource implementation)
Download and extract a CLI tool archive into DevBin
- resource: Microsoft.WinGet.DSC/Archive
ensure: Present
source: https://example.com/tools/awesome-cli-1.2.3-win64.zip
destination: ${{ variables.DevBin }}
checksum: sha256:DEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF
Configure VS Code extensions after installation
- resource: Microsoft.WinGet.DSC/PowerShellScript
description: Install VS Code extensions
script: |
$extensions = @(${{ variables.VsCodeExtensions | toJson }})
foreach ($ext in $extensions) {
code –install-extension $ext –force | Out-Null
}
Post-setup: verify versions (non-blocking)
- resource: Microsoft.WinGet.DSC/PowerShellScript
description: Verify tool versions
continueOnError: true
script: |
git –version
python –version
node –version
code –version
What this file demonstrates:
- Using variables once and referencing them multiple times
- Pinning versions (Python 3.12., Node 20.)
- Machine vs user scope installs
- Creating directories and managing environment variables
- Downloading archives when something isn’t in winget
- Running post-install PowerShell scripts (e.g., to add VS Code extensions)
Tip: Keep secure download checksums whenever you reference external archives. This guards against tampering.
4) Validate your configuration (recommended)
Before applying, validate structure and preview what will happen. Use:
winget configure –help
Then run a validation step supported by your winget version. If your version includes a validate/show option, it typically looks like:
winget configure –file .\pc.yaml –show
or
winget configure –file .\pc.yaml –validate
If your version doesn’t recognize those options, proceed to apply and review the plan output. Always test in a VM first.
5) Apply the configuration
Run from an elevated PowerShell or Command Prompt when changing system settings or installing for all users:
winget configure –file .\pc.yaml
For unattended application (CI/CD, Intune, scripts), add flags to avoid prompts:
winget configure –file .\pc.yaml --silent
–disable-interactivity --accept-package-agreements
–accept-source-agreements
6) Verify and iterate
- Check the console summary (e.g., “Applied 14/14 resources successfully”).
- Confirm apps:
winget list
- Run your key tools to ensure they’re on PATH and working.
- If something didn’t apply, see Troubleshooting and rerun after addressing the issue.
Keep your configuration in a Git repository (private or organization). Use branches for experiments and pull requests for changes. Store sensitive secrets in your pipeline’s secret store, not in the YAML.
Troubleshooting
Here are the most common issues and how to fix them fast.
- Hash mismatch / Installer hash does not match
- Cause: The manifest’s expected hash doesn’t match the downloaded file (changed upstream or corrupted cache).
- Fix:
- Refresh sources:
winget source update
- Clear and reset sources if needed:
winget source reset –force
winget source update - Try again. If it persists for a specific package, install a pinned version known to be consistent or wait for the manifest to be updated.
- Refresh sources:
- Multiple installers found / Ambiguous installer
- Cause: The package has multiple installers (x86/x64/ARM, user/machine).
- Fix: In your YAML, specify scope (user/machine) and architecture if supported by your winget/DSC resource. For ad-hoc installs:
winget install –scope machine –architecture x64
- Source index errors (e.g., “index corrupted”)
- Fix:
winget source reset –force
winget source update
- Fix:
- Access denied / Elevation required
- Cause: You’re changing machine-level state (e.g., PATH at machine scope, system installs) without admin rights.
- Fix: Close the console and re-open as Administrator, then rerun the command.
- Application installer prompts break automation
- Fix: Use –silent and –disable-interactivity when applying the configuration. Also include:
–accept-package-agreements –accept-source-agreements
- Fix: Use –silent and –disable-interactivity when applying the configuration. Also include:
- Package not found / Not available in your region
- Fix:
- Confirm the Id:
winget search
- Check sources:
winget source list
winget source update - If the app isn’t in winget, use an Archive resource, a local MSI/MSIX with a manifest, or host your own winget source.
- Confirm the Id:
- Fix:
- Timeouts or network interruptions
- Fix: Retry on a stable connection. In automation, implement retries. Consider pre-downloading installers for offline scenarios (see Automation Tips).
- Post-install commands not found (e.g., “code is not recognized”)
- Fix: Ensure the app added itself to PATH or a restart of the shell is performed. Consider installing in machine scope or explicitly append directories to PATH via the Environment resource in YAML.
Automation Tips
PowerShell bootstrapper script
Use a single script to prepare any machine, fetch your YAML from Git, and apply it unattended.
Bootstrap-WinGetConfig.ps1
Run as Administrator for full-machine setups.
$ErrorActionPreference = ‘Stop’
Ensure winget is present (App Installer). If missing, prompt or install from Store/manual package.
try {
winget –info | Out-Null
} catch {
Write-Error “winget not found. Install ‘App Installer’ from Microsoft Store, then re-run.”
exit 1
}
Update sources
winget source update
Pull the config (GitHub raw URL or your internal Git server)
$ConfigUrl = “https://raw.githubusercontent.com/YourOrg/pc-configs/main/dev-workstation.yaml”
$ConfigPath = “$env:TEMP\dev-workstation.yaml”
Invoke-WebRequest -Uri $ConfigUrl -OutFile $ConfigPath
Optional: Validate or show plan if supported
winget configure –file $ConfigPath –show
Apply silently for automation
winget configure –file $ConfigPath --silent
–disable-interactivity --accept-package-agreements
–accept-source-agreements
Run it with:
powershell -ExecutionPolicy Bypass -File .\Bootstrap-WinGetConfig.ps1
Task Scheduler
- Create a task that runs the bootstrapper at user sign-in or on a schedule.
- Set “Run with highest privileges.”
- Use a service account or SYSTEM for fleet provisioning.
Microsoft Intune (Endpoint Manager)
- Package the YAML and a small PowerShell wrapper as a Win32 app, or deploy the script as a device-level PowerShell script.
- Ensure the device can reach winget sources or provide a private repository for restricted networks.
- Include flags: –silent, –disable-interactivity, –accept-package-agreements, –accept-source-agreements.
- Use detection rules (e.g., verify an app or a registry value) to mark the deployment as successful.
CI/CD (GitHub Actions, Azure DevOps)
- On windows-latest runners, winget is present. Add steps to apply your configuration before builds:
- Download the YAML from your repo.
- Apply with winget configure (consider pinning versions to keep builds reproducible).
- Cache heavy toolchains if jobs are short-lived to reduce setup time.
Offline or low-connectivity scenarios
- Pre-download installers with winget or via vendor links and cache them on a local share or artifact store.
- For packages in winget, a “download” command may be available in your version. Otherwise, download vendor installers and reference them with a local Archive or local manifest.
- Add a local or enterprise winget source:
winget source add –name CorpRepo –arg https://your-internal-source/winget –type Microsoft.PreIndexed.Package
winget source update - Your YAML can target the internal source for predictable access behind firewalls.
Best Practices
- Treat your YAML like code
- Store in Git, use branches/PRs, review changes, and tag releases when you change key components.
- Version pinning and ranges
- Pin critical tools (e.g., “3.12.*” or exact “3.12.3”). Use ranges to balance stability and security updates.
- Split configurations into layers
- Base (OS-agnostic common tools), role-based (Developer, Designer, Support), and team/project-specific overlays. Apply them sequentially.
- Keep manifests clean and minimal
- Prefer official winget packages where possible. Use Archive or script resources sparingly for edge cases.
- Idempotency and clarity
- Aim for a config you can re-apply repeatedly without adverse effects. Avoid steps that require manual cleanup.
- Security
- Validate checksums for external downloads. Don’t embed secrets in YAML; use secure variables in your pipelines.
- Test in a VM
- Validate changes on a fresh VM before rolling out widely. Capture logs for auditing:
- Winget logs path is shown by:
winget –info
- Winget logs path is shown by:
- Validate changes on a fresh VM before rolling out widely. Capture logs for auditing:
- Document your configuration
- Use metadata fields and comments in YAML. Maintain a README that explains each resource and how to extend it.
Conclusion
With winget configure, rebuilding any PC from a single YAML file becomes practical and reliable. You describe the desired state once, then apply it anywhere—new devices, VMs, CI/CD runners, or entire fleets—with one command. Keep your configuration under version control, pin versions where it matters, and automate with PowerShell or Intune for scale. The Windows Package Manager is safe, powerful, and well-suited to repeatable, auditable setups. Try the sample YAML and commands in this guide to experience the difference on your next machine build.
FAQ
What’s the difference between winget configure and winget import/export?
- winget export/import focuses on apps only (exporting a list of installed packages and importing them elsewhere). It’s great for app parity but doesn’t cover environment variables, scripts, or arbitrary configuration.
- winget configure is a broader desired-state engine driven by YAML, letting you install apps plus set system state, run scripts, and more—all in one apply step.
Do I need admin rights to use winget configure?
Not always. User-scope installs and user environment changes don’t need elevation. However, machine-scope installs, system PATH changes, and system-level settings typically require running the console “as Administrator.”
Can I pin exact versions with winget configure?
Yes. Specify the version in your YAML (e.g., “3.12.3” or a range like “3.12.*”). Pin critical tooling to keep builds reproducible and avoid unexpected breaking changes.
How do I safely run this unattended?
Use:
- –silent
- –disable-interactivity
- –accept-package-agreements
- –accept-source-agreements
Combine these with a PowerShell bootstrap script and run it in Task Scheduler, Intune, or CI/CD.
What if a package isn’t available in winget?
Use an Archive or script resource to download from a trusted vendor source, include a checksum, or host a private winget source internally. You can also install from a local manifest if needed.
Copy the sample YAML, adjust package Ids and versions to your needs, and apply with:
winget configure –file .\pc.yaml
In minutes, you’ll have a predictable, repeatable PC build you can run anywhere.
