If you've been using winget for a while, you know the basics: install, search, upgrade. Here are 10 less-known tricks that turn winget from a downloader into a real productivity tool.
1. Use winget show --versions to find old versions
winget show --id Microsoft.VisualStudioCode --versions
Lists every version winget can install. Then:
winget install --id Microsoft.VisualStudioCode --version 1.118.0
Pins to the exact build. Great for reproducing bugs or downgrading after a bad release.
2. Pipe winget list through PowerShell
The output of winget list is regular text, but you can filter it programmatically:
winget list --source winget | Select-String -Pattern "^Microsoft\." -SimpleMatch:$false
Or with Select-Object after a custom parse:
function Get-WingetApps {
winget list --source winget --output table | Select-Object -Skip 2 | ForEach-Object {
$cols = $_ -split '\s{2,}'
[PSCustomObject]@{ Name = $cols[0]; Id = $cols[1]; Version = $cols[2] }
}
}
Get-WingetApps | Where-Object Id -like "Microsoft.*"
3. Disable msstore for cleaner search
Default search returns hits from both winget and msstore sources, often duplicated. Drop msstore if you don't use Store apps:
winget source remove --name msstore
Now winget search only returns the cleaner winget catalog.
4. Set a custom downloader for proxy / corporate networks
The default downloader ignores Windows proxy settings. Switch to wininet (respects system proxy):
winget settings
In the JSON that opens, add:
{
"network": {
"downloader": "wininet"
}
}
Save. Now winget install honours your HTTP/HTTPS proxy from Windows settings.
5. Auto-accept ALL agreements globally
Tired of --accept-package-agreements --accept-source-agreements on every command? Set it once:
In settings.json:
{
"installBehavior": {
"preferences": {
"scope": "user"
}
},
"experimentalFeatures": {
"directMSI": true
}
}
Then wrap winget in a PowerShell function:
function wg { winget @args --accept-package-agreements --accept-source-agreements }
Now wg install firefox -e skips every agreement prompt.
6. Use winget configure for declarative setup
Instead of running 20 install commands, write a YAML spec:
# setup.dsc.yaml
$schema: https://aka.ms/configuration-dsc-schema/0.2
properties:
resources:
- resource: Microsoft.WinGet.DSC/WinGetPackage
directives:
description: Install VS Code
settings:
id: Microsoft.VisualStudioCode
source: winget
- resource: Microsoft.WinGet.DSC/WinGetPackage
settings:
id: Git.Git
source: winget
Apply:
winget configure -f setup.dsc.yaml
Idempotent: re-running won't reinstall already-present apps. Perfect for "set up new machine" scripts in source control.
7. Use --dependency-source for offline install
If you've mirrored a winget index locally (LAN catalog), force winget to use it for dependency resolution:
winget install --id Some.App --dependency-source internal
8. Tab completion in PowerShell
winget has built-in tab completion for PowerShell. Add this to your $PROFILE:
Register-ArgumentCompleter -Native -CommandName winget -ScriptBlock {
param($wordToComplete, $commandAst, $cursorPosition)
$Local:word = $wordToComplete.Replace('"', '""')
$Local:ast = $commandAst.ToString().Replace('"', '""')
winget complete --word "$Local:word" --commandline "$Local:ast" --position $cursorPosition |
ForEach-Object { [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_) }
}
Now winget install --id <Tab> autocompletes package IDs.
9. Use winget hash for manifest authoring
If you're submitting a new package to the winget catalog:
winget hash C:\Downloads\new-installer.exe
Outputs the SHA-256 needed in the manifest's InstallerSha256 field. Saves a trip to PowerShell's Get-FileHash.
10. Combine with winget pin for version-locked LTS setup
The killer combo for stable dev environments:
# Install LTS Node
winget install --id OpenJS.NodeJS.LTS --version "20.*"
# Pin so upgrade --all won't bump to 22.x
winget pin add --id OpenJS.NodeJS.LTS --version "20.*"
Now your Node stays in the 20.x line forever — patch updates apply, major bumps don't. See winget pin guide.
Bonus: a PowerShell function library
Add these to your $PROFILE for daily wins:
# Update everything weekly
function up { winget upgrade --all --include-unknown --accept-package-agreements --accept-source-agreements }
# Quick search
function wgs { winget search @args }
# Quick install
function wgi { param($id) winget install --id $id -e --accept-package-agreements --accept-source-agreements }
# Quick uninstall
function wgr { param($id) winget uninstall --id $id -e --silent }
# Show what's outdated
function wgo { winget upgrade }
# Export current setup
function wge { winget export -o "$env:OneDrive\winget-$(Get-Date -Format yyyy-MM-dd).json" --include-versions }
Then wgi firefox is faster than typing the full command.
What's next?
- 30 essential winget commands → — full reference
- How to use winget pin → — version locking
- Best winget GUI clients → — graphical front-ends
- Fresh Windows 11 setup → — putting it all together
