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:

TrackLatestReleasedNotes
Stable (v2.x)2.7.22026-05-12log4net 3.3.1, 7-Zip 26.01 bundled
Support (v1.4.x)1.4.62026-05-127-Zip 26.01 bundled — patch-only branch

Highlights from the v2.7 series:

  • choco list accepts --ignore-pinned to skip pinned packages — handy when scripting bulk upgrades.
  • New choco license and choco support commands expose licensed-extension state and produce a support bundle.
  • choco info now 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-cache flag 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:

powershell
# 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.

powershell
# 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:

text
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:

powershell
choco --version

Output:

text
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.

powershell
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.

CommandMeaning
choco install <pkg>Install one or more packages
choco upgrade <pkg> / upgrade allUpdate packages to latest
choco uninstall <pkg>Remove a package
choco listList 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 / removeManage repositories
choco config list / setManage global config (cache dir, timeout)
choco apikeySet API keys for private feeds
choco pack <nuspec>Build a .nupkg from a nuspec
choco push <nupkg>Upload to a feed
choco outdatedList packages with available updates
choco featureToggle 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.

powershell
choco install git -y

Output:

text
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:

powershell
choco install git vscode 7zip nodejs-lts python -y

Output:

text
Chocolatey installed 5/5 packages.

Pin to a specific version (use --version; quote anything with dots and hyphens):

powershell
choco install nodejs-lts --version=20.12.2 -y

Output:

text
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.

powershell
# 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:

text
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.

powershell
choco upgrade git -y

Output:

text
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:

powershell
choco upgrade all -y --no-progress

Output:

text
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):

powershell
choco outdated

Output:

text
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.

powershell
choco search firefox

Output:

text
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.
powershell
choco info nodejs-lts

Output:

text
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.

powershell
choco list

Output:

text
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.
powershell
choco list --include-programs | Select-String -Pattern "^[A-Za-z]" -CaseSensitive | Select-Object -First 12

Output:

text
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).

powershell
choco pin add --name="nodejs-lts" --version=20.12.2
choco pin list

Output:

text
Chocolatey v2.3.0
nodejs-lts|20.12.2

Chocolatey has pinned 1 package.

Remove a pin:

powershell
choco pin remove --name="nodejs-lts"

Output:

text
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.

powershell
choco uninstall vscode -y

Output:

text
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.

powershell
choco source list

Output:

text
chocolatey - https://community.chocolatey.org/api/v2/ | Priority 0|Bypass Proxy - False|Self-Service - False|Admin Only - False.
powershell
# 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:

text
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.

powershell
choco config list

Output:

text
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
powershell
# 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:

text
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
<?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:

powershell
choco install packages.config -y

Output:

text
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.

powershell
# 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:

text
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.

powershell
choco new mytool

Output:

text
Chocolatey v2.3.0
Creating new package specification files at .\mytool
Successfully generated mytool package specification files at '.\mytool'.

mytool.nuspec:

xml
<?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:

powershell
$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:

powershell
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:

text
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.

Questionwingetchocoscoop
First-party?Yes (Microsoft)No (community)No (community)
Bundled with Windows?Yes (11)NoNo
Admin required?SometimesYes (default)No
Install locationPer-app installers (Program Files)Per-app installers + C:\ProgramData\chocolatey%USERPROFILE%\scoop\ (per-user)
Custom install dirs / paramsLimitedYes (--params, --install-arguments)Limited
Self-host a feedDifficultEasy (any NuGet feed)Easy (a bucket is just a Git repo)
Package countLarger but narrowerLargest (10k+)Smallest, dev-focused
Strongest forConsumer appsEnterprise / scripted setupCLI dev tools

Common pitfalls

  1. Not running elevatedchoco install needs administrator unless every package has PortablePackage install logic. Open Terminal as Administrator.
  2. Missing -y — without it, every package prompts "Do you want to run the install script?". Scripts hang forever in CI.
  3. upgrade all upgrades pinned packages — only if you forgot the pin. Always choco pin list before scheduled upgrades.
  4. Community feed rate limiting — anonymous downloads are throttled. Add an API key or self-host the packages you care about.
  5. Two packages for one app — packages often come in pairs (vscode is the meta-package, vscode.install is the real installer). Remove only the meta-package, not both, or you'll uninstall reinstall the underlying app.
  6. --params not being applied — only certain packages support params; check choco info <pkg> first. If unsupported, the param is silently ignored.
  7. Locked configuration on managed machines — corporate Group Policy often locks C:\ProgramData\chocolatey to admins, breaking the chocolatey-licensed self-update path; use a private feed instead.
  8. 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.

powershell
# 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:

text
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.

powershell
$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:

text
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.

powershell
# 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:

text
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.

text
dotwin/
├── bootstrap.ps1
├── packages.config
└── README.md
powershell
# 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:

text
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.

powershell
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:

text
[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.

powershell
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:

text
PSComputerName                  : localhost
Status                          : Success
PSDscRunAsCredential            :
DependsOn                       : {[cChocoInstaller]installChoco}
ConfigurationName               : DevMachine

Sources