cheat sheet
Chocolatey
Install, upgrade, pin, and script software installs on Windows with the choco CLI, packages.config files, and custom sources.
Chocolatey — Windows Package Manager
What it is
Chocolatey (choco) is a community-driven Windows package manager built on NuGet and PowerShell, maintained by Chocolatey Software, Inc. and the community via the chocolatey/choco repository. It wraps almost every Windows installer — MSI, EXE, ZIP, MSIX, even silent PowerShell scripts — so a single choco install produces the same result on a developer laptop, a CI runner, and a freshly provisioned VM. Reach for choco when you need broader coverage and packaging hooks than winget (a Chocolatey package is just a .nupkg you can self-host), or when you need a managed package for software that isn't on the Microsoft community repo; the main alternatives are winget (first-party, narrower but bundled) and scoop (user-scope, dev-tools-focused, no admin).
What's new in 2026
Chocolatey is on a v2.x / v1.x dual track — v2 is the modern .NET-based line, v1.4.x is the legacy support branch for older Windows. As of May 2026 the current versions are:
| Track | Latest | Released | Notes |
|---|---|---|---|
| Stable (v2.x) | 2.7.2 | 2026-05-12 | log4net 3.3.1, 7-Zip 26.01 bundled |
| Support (v1.4.x) | 1.4.6 | 2026-05-12 | 7-Zip 26.01 bundled — patch-only branch |
Highlights from the v2.7 series:
choco listaccepts--ignore-pinnedto skip pinned packages — handy when scripting bulk upgrades.- New
choco licenseandchoco supportcommands expose licensed-extension state and produce a support bundle. choco infonow displays the install path and the source location that was used when the package was installed.- Hash calculation is now reliable for packages >2 GB.
- A new
--ignore-http-cacheflag forces a network round-trip and bypasses the local HTTP request cache (useful when a CDN serves stale package metadata). - Authenticating sources now accept passwords with non-ASCII characters (a long-standing pain point in Asian and European locales).
- The Chocolatey GUI also got a major bump to v3.1.0 (May 2026); the licensed extension is at v8.1.0.
Upgrade:
# Run as Administrator
choco upgrade chocolatey -y
Install
Chocolatey installs itself with a one-shot bootstrap script that must be run in an elevated PowerShell session. The installer writes to C:\ProgramData\chocolatey\ and adds that directory to $env:Path for all users.
# Run as Administrator
Set-ExecutionPolicy Bypass -Scope Process -Force
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072
iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
Output:
Downloading https://community.chocolatey.org/api/v2/package/chocolatey
Getting Chocolatey from https://community.chocolatey.org/...
Extracting C:\Users\Alice\AppData\Local\Temp\chocolatey\chocInstall\chocolatey.zip to C:\Users\Alice\AppData\Local\Temp\chocolatey\chocInstall...
Installing Chocolatey on the local machine
Creating ChocolateyInstall as an environment variable
Restricting write permissions to Administrators
We are setting up the Chocolatey package repository.
Chocolatey (choco.exe) is now ready.
You can call choco from anywhere, command line or powershell by typing choco.
Run choco /? for a list of functions.
Verify the install:
choco --version
Output:
2.3.0
Syntax
choco follows a verb noun args pattern with consistent flags across commands. -y (or --yes) auto-accepts every prompt, which is essential for scripted installs; without it, Chocolatey asks before running any PowerShell script bundled with a package.
choco <command> [<arg>...] [--<option>=<value>] [-y]
Output: (none — exits 0 on success)
Essential commands
These are the verbs you'll use 95% of the time. The full list is choco -?; every command has its own -? help.
| Command | Meaning |
|---|---|
choco install <pkg> | Install one or more packages |
choco upgrade <pkg> / upgrade all | Update packages to latest |
choco uninstall <pkg> | Remove a package |
choco list | List installed packages on this machine |
choco search <term> | Search the configured sources |
choco info <pkg> | Show full metadata for a package |
choco pin add --name <pkg> | Prevent a package from being upgraded |
choco source list / add / remove | Manage repositories |
choco config list / set | Manage global config (cache dir, timeout) |
choco apikey | Set API keys for private feeds |
choco pack <nuspec> | Build a .nupkg from a nuspec |
choco push <nupkg> | Upload to a feed |
choco outdated | List packages with available updates |
choco feature | Toggle Chocolatey features (autoUninstaller, etc.) |
Install
choco install resolves a package from the configured sources (Chocolatey Community by default), downloads the bundled installer or script, and runs it silently. Add -y for unattended runs and --no-progress in CI to suppress the progress bar that pollutes logs.
choco install git -y
Output:
Chocolatey v2.3.0
Installing the following packages:
git
By installing, you accept licenses for the packages.
Progress: Downloading git.install 2.44.0... 100%
Progress: Downloading git 2.44.0... 100%
git.install v2.44.0 [Approved]
git.install package files install completed. Performing other installation steps.
The package git.install wants to run 'chocolateyInstall.ps1'.
Note: If you don't run this script, the installation will fail.
Installing 64-bit git...
git has been installed.
The install of git.install was successful.
Software installed to 'C:\Program Files\Git\'
Chocolatey installed 2/2 packages.
See the log for details (C:\ProgramData\chocolatey\logs\chocolatey.log).
Install multiple packages at once:
choco install git vscode 7zip nodejs-lts python -y
Output:
Chocolatey installed 5/5 packages.
Pin to a specific version (use --version; quote anything with dots and hyphens):
choco install nodejs-lts --version=20.12.2 -y
Output:
Chocolatey v2.3.0
Installing the following packages:
nodejs-lts
nodejs-lts v20.12.2 [Approved]
The install of nodejs-lts was successful.
Chocolatey installed 1/1 packages.
Package parameters and install arguments
Some packages accept custom switches at install time — for example, the git package supports an editor choice and credential helper via --params. Anything in --install-arguments is passed verbatim to the underlying MSI/EXE; --params is parsed by the package's chocolateyInstall.ps1.
# Git with custom params parsed by the package script
choco install git -y --params="/GitOnlyOnPath /NoShellIntegration /NoCredentialManager"
# 7-Zip installed to a custom location via install-arguments passed to the MSI
choco install 7zip -y --install-arguments="INSTALLDIR=D:\Tools\7zip" --override-arguments
# Both at once
choco install vscode -y --params="/NoDesktopIcon /NoQuicklaunchIcon" --install-arguments="/SILENT"
Output:
git v2.44.0 [Approved]
git package files install completed. Performing other installation steps.
Successfully installed git to 'C:\Program Files\Git' with custom params: /GitOnlyOnPath /NoShellIntegration /NoCredentialManager
Upgrade
choco upgrade updates a single package to the latest version that satisfies version pins. choco upgrade all is the workhorse for keeping a machine in shape — run it on a schedule.
choco upgrade git -y
Output:
Chocolatey v2.3.0
Upgrading the following packages:
git
By upgrading, you accept licenses for the packages.
git v2.44.0 is the latest version available based on your source(s).
Chocolatey upgraded 0/1 packages.
Upgrade everything except pinned packages:
choco upgrade all -y --no-progress
Output:
Chocolatey v2.3.0
Upgrading the following packages:
all
git v2.44.0 is the latest version available based on your source(s).
nodejs-lts v20.12.2 → 20.13.1
7zip v23.01 is the latest version available based on your source(s).
vscode v1.88.1 → 1.89.0
Chocolatey upgraded 2/4 packages.
List packages with available upgrades (without installing):
choco outdated
Output:
Outdated Packages
Output is package name | current version | available version | pinned?
nodejs-lts|20.12.2|20.13.1|false
vscode|1.88.1|1.89.0|false
Chocolatey has determined 2 package(s) are outdated.
Search and info
choco search queries every configured source and returns matching package IDs and versions. Add --exact for an ID lookup; without it, Chocolatey returns partial-match results sorted by relevance.
choco search firefox
Output:
Chocolatey v2.3.0
Firefox 125.0.1 [Approved]
Firefox-LANGUAGE 125.0.1 [Approved]
FirefoxESR 115.10.0esr [Approved]
firefox-ja 125.0.1 [Approved]
...
27 packages found.
choco info nodejs-lts
Output:
Chocolatey v2.3.0
nodejs-lts 20.12.2 [Approved]
Title: Node.js (LTS) | Published: 4/15/2026
Package approved as a trusted package on 4/15/2026.
Package tested status: Passing on 4/15/2026.
Number of Downloads: 27,481,920 | Downloads for this version: 142,012
Package Checksum: '9b1c…'
Description: Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine.
Tags: node nodejs javascript runtime lts
Software Site: https://nodejs.org/
Software License: https://nodejs.org/static/legal/
List installed
choco list shows only what is installed on the local machine. Add --local-only --include-programs (legacy --lo --ip) to also surface non-Chocolatey installs detected from Add/Remove Programs.
choco list
Output:
Chocolatey v2.3.0
7zip.install 23.01.0
chocolatey 2.3.0
git 2.44.0
git.install 2.44.0
nodejs-lts 20.12.2
python 3.12.3
vscode 1.88.1
vscode.install 1.88.1
8 packages installed.
choco list --include-programs | Select-String -Pattern "^[A-Za-z]" -CaseSensitive | Select-Object -First 12
Output:
7zip.install 23.01.0
git.install 2.44.0
nodejs-lts 20.12.2
python 3.12.3
vscode.install 1.88.1
Programs and features:
Microsoft Edge|125.0.2535.51|Microsoft Corporation
Microsoft Edge Update|1.3.185.31|Microsoft Corporation
Microsoft Edge WebView2 Runtime|125.0.2535.51|Microsoft Corporation
Microsoft Visual Studio Installer|3.10.2154.59760|Microsoft Corporation
Pin
Pinning prevents choco upgrade all from touching a package — useful when you've manually installed a specific version (e.g. a Node.js LTS that matches a project's .nvmrc).
choco pin add --name="nodejs-lts" --version=20.12.2
choco pin list
Output:
Chocolatey v2.3.0
nodejs-lts|20.12.2
Chocolatey has pinned 1 package.
Remove a pin:
choco pin remove --name="nodejs-lts"
Output:
Chocolatey v2.3.0
Chocolatey has removed pin for nodejs-lts.
Uninstall
choco uninstall runs the package's chocolateyUninstall.ps1 (or, if autoUninstaller is enabled, infers the silent uninstall from Add/Remove Programs). -x (--force-dependencies) also removes any unused dependencies.
choco uninstall vscode -y
Output:
Chocolatey v2.3.0
Uninstalling the following packages:
vscode
vscode v1.88.1
Removed from programs and features
vscode has been successfully uninstalled.
Chocolatey uninstalled 1/1 packages.
Sources (package feeds)
A source is a NuGet-compatible URL that hosts .nupkg files. The default chocolatey source is the community feed at https://community.chocolatey.org/api/v2/. Add private feeds for internal-only packages — Azure Artifacts, ProGet, JFrog Artifactory, Sonatype Nexus, or just a folder share.
choco source list
Output:
chocolatey - https://community.chocolatey.org/api/v2/ | Priority 0|Bypass Proxy - False|Self-Service - False|Admin Only - False.
# Add a private feed (with API key)
choco source add --name="myfeed" --source="https://proget.example.com/nuget/chocolatey/" --priority=1 --user="alice" --password="secret"
# Disable / enable a source
choco source disable --name="chocolatey"
choco source enable --name="chocolatey"
# Remove
choco source remove --name="myfeed"
Output:
Chocolatey v2.3.0
Added myfeed - https://proget.example.com/nuget/chocolatey/ (Priority 1)
Configuration
choco config exposes Chocolatey's global settings — cache directory, web request timeout, proxy server. Tweak these once per machine; values are persisted in C:\ProgramData\chocolatey\config\chocolatey.config.
choco config list
Output:
Settings
- cacheLocation = 'C:\ProgramData\chocolatey\cache' | The location of the cache used by Chocolatey.
- commandExecutionTimeoutSeconds = '2700' | Default timeout for command execution.
- webRequestTimeoutSeconds = '30'
- proxy = '' | Proxy server URL
- proxyUser = ''
- proxyPassword = ''
Features
- allowGlobalConfirmation = Disabled | Prompt for confirmation in scripts or use --yes.
- autoUninstaller = Enabled | Uninstall via Add/Remove Programs when no uninstall script.
- checksumFiles = Enabled
- usePackageExitCodes = Enabled
# Auto-confirm every install for the current shell (avoids needing -y)
choco feature enable --name="allowGlobalConfirmation"
# Use a corporate proxy
choco config set proxy "http://proxy.example.com:8080"
choco config set proxyUser "alice"
choco config set proxyPassword "secret"
Output:
Chocolatey v2.3.0
Enabled allowGlobalConfirmation
Updated proxy = http://proxy.example.com:8080
Scripted installs with packages.config
packages.config is a NuGet-style XML manifest listing the exact packages and versions to install. Drop one in a Git repo, commit it next to your provisioning script, and a fresh machine is set up with a single choco install.
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="git" version="2.44.0" />
<package id="vscode" />
<package id="nodejs-lts" version="20.12.2" />
<package id="python" />
<package id="7zip" />
<package id="microsoft-windows-terminal" />
<package id="powershell-core" />
<package id="gh" />
<package id="docker-desktop" />
</packages>
Output: (config file only — no shell output)
Install everything in one shot:
choco install packages.config -y
Output:
Chocolatey v2.3.0
Installing the following packages:
git;vscode;nodejs-lts;python;7zip;microsoft-windows-terminal;powershell-core;gh;docker-desktop
Chocolatey installed 9/9 packages.
Local-only and folder feeds
A "feed" can be just a folder full of .nupkg files. Useful for air-gapped networks: build packages on a machine with internet, copy them to an offline share, and point Chocolatey at the share.
# Add a folder as a source
choco source add --name="offline" --source="\\fileserver\choco-packages"
# Install only from the offline source
choco install git -y --source="offline"
# Install bypassing the community feed entirely
choco install git -y --source="\\fileserver\choco-packages"
Output:
Chocolatey v2.3.0
git v2.44.0 [Approved]
The install of git was successful.
Chocolatey installed 1/1 packages.
Authoring a package
A Chocolatey package is a NuGet .nupkg containing one .nuspec (metadata) and a tools\chocolateyInstall.ps1 (the actual install logic). Useful when you need to wrap an internal tool, vendored binary, or a script.
choco new mytool
Output:
Chocolatey v2.3.0
Creating new package specification files at .\mytool
Successfully generated mytool package specification files at '.\mytool'.
mytool.nuspec:
<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2015/06/nuspec.xsd">
<metadata>
<id>mytool</id>
<version>1.0.0</version>
<title>mytool</title>
<authors>Alice Dev</authors>
<projectUrl>https://example.com/mytool</projectUrl>
<licenseUrl>https://example.com/license</licenseUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>Internal utility for the Alice team.</description>
<tags>internal cli</tags>
</metadata>
<files>
<file src="tools\**" target="tools" />
</files>
</package>
Output: (nuspec file only — no shell output)
tools\chocolateyInstall.ps1:
$ErrorActionPreference = "Stop"
$packageName = "mytool"
$url = "https://example.com/releases/mytool-1.0.0-x64.zip"
$checksum = "9B1C0DA63A4B…"
$toolsDir = "$(Split-Path -parent $MyInvocation.MyCommand.Definition)"
Install-ChocolateyZipPackage `
-PackageName $packageName `
-Url $url `
-Checksum $checksum `
-ChecksumType "sha256" `
-UnzipLocation $toolsDir
Output: (script file only — runs on choco install)
Build and publish:
choco pack .\mytool.nuspec
choco apikey --key="abcdef123" --source="https://proget.example.com/nuget/chocolatey/"
choco push mytool.1.0.0.nupkg --source="https://proget.example.com/nuget/chocolatey/"
Output:
Successfully created package 'mytool.1.0.0.nupkg'
Attempting to push mytool.1.0.0.nupkg to https://proget.example.com/nuget/chocolatey/
mytool was pushed successfully to https://proget.example.com/nuget/chocolatey/
choco vs winget vs scoop
A practical rule of thumb for picking a Windows package manager — all three coexist on the same machine without conflict.
| Question | winget | choco | scoop |
|---|---|---|---|
| First-party? | Yes (Microsoft) | No (community) | No (community) |
| Bundled with Windows? | Yes (11) | No | No |
| Admin required? | Sometimes | Yes (default) | No |
| Install location | Per-app installers (Program Files) | Per-app installers + C:\ProgramData\chocolatey | %USERPROFILE%\scoop\ (per-user) |
| Custom install dirs / params | Limited | Yes (--params, --install-arguments) | Limited |
| Self-host a feed | Difficult | Easy (any NuGet feed) | Easy (a bucket is just a Git repo) |
| Package count | Larger but narrower | Largest (10k+) | Smallest, dev-focused |
| Strongest for | Consumer apps | Enterprise / scripted setup | CLI dev tools |
Common pitfalls
- Not running elevated —
choco installneeds administrator unless every package hasPortablePackageinstall logic. Open Terminal as Administrator. - Missing
-y— without it, every package prompts "Do you want to run the install script?". Scripts hang forever in CI. upgrade allupgrades pinned packages — only if you forgot the pin. Alwayschoco pin listbefore scheduled upgrades.- Community feed rate limiting — anonymous downloads are throttled. Add an API key or self-host the packages you care about.
- Two packages for one app — packages often come in pairs (
vscodeis the meta-package,vscode.installis the real installer). Remove only the meta-package, not both, or you'll uninstall reinstall the underlying app. --paramsnot being applied — only certain packages support params; checkchoco info <pkg>first. If unsupported, the param is silently ignored.- Locked configuration on managed machines — corporate Group Policy often locks
C:\ProgramData\chocolateyto admins, breaking thechocolatey-licensedself-update path; use a private feed instead. - Wrong source priority — a private feed at priority 0 with no version of a package will block the community feed at priority 1 from supplying it; lower numbers win.
Real-world recipes
Self-bootstrapping setup script for a new dev machine
A single PowerShell script that installs Chocolatey if missing, then installs the team's standard toolset. Run it once on every new machine.
# bootstrap.ps1 — run elevated
$ErrorActionPreference = "Stop"
if (-not (Get-Command choco -ErrorAction SilentlyContinue)) {
Set-ExecutionPolicy Bypass -Scope Process -Force
[Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor 3072
iex ((New-Object Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
}
choco feature enable --name="allowGlobalConfirmation"
@(
"git"
"gh"
"vscode"
"microsoft-windows-terminal"
"powershell-core"
"nodejs-lts"
"python"
"docker-desktop"
"7zip"
"firefox"
) | ForEach-Object {
choco install $_ --no-progress
}
choco upgrade all -y --no-progress
Output:
Chocolatey installed 10/10 packages.
Chocolatey upgraded 0/10 packages.
Scheduled task that keeps the machine up to date weekly
A simple schtasks definition that runs choco upgrade all -y every Sunday at 03:00 and writes a transcript.
$action = New-ScheduledTaskAction -Execute "pwsh.exe" -Argument '-NoProfile -Command "Start-Transcript -Path C:\logs\choco-update.log -Append; choco upgrade all -y --no-progress; Stop-Transcript"'
$trigger = New-ScheduledTaskTrigger -Weekly -DaysOfWeek Sunday -At 3am
$prin = New-ScheduledTaskPrincipal -UserId "SYSTEM" -LogonType ServiceAccount -RunLevel Highest
Register-ScheduledTask `
-TaskName "Choco Weekly Upgrade" `
-Action $action `
-Trigger $trigger `
-Principal $prin `
-Description "Runs choco upgrade all weekly"
Output:
TaskPath TaskName State
-------- -------- -----
\ Choco Weekly Upgrade Ready
Air-gapped mirror — download once, install on N machines
Build a portable cache on a machine with internet, sync the cache to a file share, then point all offline machines at it. Each machine installs from \\fileserver\choco-packages and never reaches the internet.
# On the internet-connected machine:
choco install package-internalizer -y # licensed feature in choco Pro, or use:
choco download git vscode 7zip nodejs-lts python --internalize --output-directory C:\offline-packages
# Copy to the offline share
robocopy C:\offline-packages \\fileserver\choco-packages /MIR
# On every offline machine:
choco source add --name="offline" --source="\\fileserver\choco-packages" --priority=1
choco source disable --name="chocolatey"
choco install git vscode 7zip nodejs-lts python -y --source="offline"
Output:
Chocolatey installed 5/5 packages.
Reproducible setup as code — packages.config checked into Git
Treat the dev toolset like infrastructure: commit packages.config and bootstrap.ps1 to a Git repo named dotwin. Onboarding a new engineer is git clone + pwsh bootstrap.ps1.
dotwin/
├── bootstrap.ps1
├── packages.config
└── README.md
# bootstrap.ps1 — install Chocolatey, then everything in packages.config
if (-not (Get-Command choco -ErrorAction SilentlyContinue)) {
iex ((New-Object Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
}
choco install packages.config -y --no-progress
Output:
Chocolatey installed 12/12 packages.
Diagnose a misbehaving package
-d (debug) and -v (verbose) print every PowerShell line executed and the full HTTP traffic. Combined with the per-run log under C:\ProgramData\chocolatey\logs\, this is enough to triage almost any failure.
choco install some-flaky-package -y -dv 2>&1 | Tee-Object -FilePath C:\Users\Alice\flaky-install.log
# Or just inspect the log of the most recent run
Get-Content C:\ProgramData\chocolatey\logs\chocolatey.log -Tail 200
Output:
[DEBUG] - Running 'Get-PowerShellExitCode' from 'C:\ProgramData\chocolatey\helpers\functions\Get-ExitCode.ps1'
[VERBOSE] Performing the operation "Install" on target "some-flaky-package 1.0.0".
[ERROR] Could not find a part of the path 'C:\ProgramData\chocolatey\lib\some-flaky-package\tools\config.ini'.
Chocolatey installed 0/1 packages. 1 packages failed.
Combine choco with PowerShell Desired State Configuration
For full-fledged config management, DSC's cChoco module wraps choco so you can describe the package set declaratively and have DSC enforce it.
Configuration DevMachine {
Import-DscResource -ModuleName cChoco
Node "localhost" {
cChocoInstaller installChoco {
InstallDir = "C:\ProgramData\chocolatey"
}
cChocoPackageInstaller installGit {
Name = "git"
DependsOn = "[cChocoInstaller]installChoco"
}
cChocoPackageInstaller installNode {
Name = "nodejs-lts"
Version = "20.12.2"
DependsOn = "[cChocoInstaller]installChoco"
}
}
}
DevMachine -OutputPath C:\dsc
Start-DscConfiguration -Path C:\dsc -Wait -Verbose
Output:
PSComputerName : localhost
Status : Success
PSDscRunAsCredential :
DependsOn : {[cChocoInstaller]installChoco}
ConfigurationName : DevMachine