Cleaning up the Visual Studio 2017 package cache

With the ability to disable or move the package cache for Visual Studio 2017 and other products installed with the new installer, packages are removed for whatever instance(s) you are installing, modifying, or repairing.

If you have a lot of instances and want to clean all of them up easily from the command line – perhaps scripting it for users in an organization – you can combine tools such as vswhere or the VSSetup PowerShell module with the installer at %ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vs_installer.exe.

Batch script with vswhere

You can get the installation path for all instances and call the installer for each to disable the cache (only necessary once, but for simplicity of the script we’ll pass it for each instance) and modify – which will basically just remove package payloads – or re-enable the cache and repair the packages to re-download packages.

Note that the following sample is intended for use within a batch script. If typing on the command line only use one “%”. Run this within an elevated command prompt to avoid being prompted to elevate each time vs_installer.exe is launched.

@echo off
setlocal enabledelayedexpansion
for /f "usebackq delims=" %%i in (`vswhere -all -property installationPath`) do (
  if /i "%1"=="cache" (
    set args=repair --cache
  ) else (
    set args=modify --nocache
  )
  start /wait /d "%ProgramFiles(x86)%\Microsoft Visual Studio\Installer" vs_installer.exe !args! --installPath "%%i" --passive --norestart
  if "%ERRORLEVEL%"=="3010" set REBOOTREQUIRED=1
)
if "%REBOOTREQUIRED%"=="1" (
  echo Please restart your machine
  exit /b 3010
)

PowerShell script with VSSetup

While you can also use vswhere within PowerShell easily (e.g. vswhere -format json | convertfrom-json), this example uses the VSSetup PowerShell module you can easily obtain in Windows 10 with: install-module -scope currentuser VSSetup.

Put the following example into a script and run it from an elevated PowerShell host to avoid being prompted to elevate each time vs_installer.exre is launched.

param (
  [switch] $Cache
)
$start_args = if ($Cache) {
  'repair', '--cache'
} else {
  'modify', '--nocache'
}
get-vssetupinstance -all | foreach-object {
  $args = $start_args + '--installPath', "`"$($_.InstallationPath)`"", '--passive', '--norestart'
  start-process -wait -filePath "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vs_installer.exe" -args $args
  if ($LASTEXITCODE -eq 3010) {
    $REBOOTREQUIRED = 1
  }
}
if ($REBOOTREQUIRED) {
  "Please restart your machine"
  exit 3010
}

Both of these examples will remove all instances’ packages or put them pack depending on your command line arguments you would pass to the scripts.