Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save luizen/7541e73c7a478c656f17c3301a27c267 to your computer and use it in GitHub Desktop.
Save luizen/7541e73c7a478c656f17c3301a27c267 to your computer and use it in GitHub Desktop.
Powershell script to delete left overs (folders) of unused (uninstalled) VS Code extensions
# Requires System.Data.SQLite assembly and VS Code to be installed
# Check if the assembly is already loaded
if (-not ([System.Reflection.Assembly]::LoadWithPartialName("System.Data.SQLite"))) {
# Attempt to load the assembly from the specified path
$assemblyPath = "C:\Program Files (x86)\Common Files\Red Gate\SQLite\System.Data.SQLite.DLL"
if (Test-Path $assemblyPath) {
Add-Type -Path $assemblyPath
} else {
Write-Error "System.Data.SQLite assembly not found at the specified path: $assemblyPath"
exit
}
}
$dbPath = Join-Path $env:APPDATA "Code\User\globalStorage\state.vscdb"
$connectionString = "Data Source=$dbPath;Version=3;Read Only=True;"
$connection = New-Object System.Data.SQLite.SQLiteConnection($connectionString)
try {
$connection.Open()
$command = New-Object System.Data.SQLite.SQLiteCommand("SELECT value FROM ItemTable WHERE key = 'extensionsIdentifiers/disabled';", $connection)
$result = $command.ExecuteScalar()
if ($result) {
$jsonString = ""
if ($result -is [System.Byte[]]) {
# Convert byte array to string (assuming UTF-8 encoding)
$jsonString = [System.Text.Encoding]::UTF8.GetString($result)
} elseif ($result -is [string]) {
$jsonString = $result
}
if ($jsonString) {
try {
$disabledExtensionsArray = ConvertFrom-Json $jsonString
Write-Host "--- Currently Disabled Extensions (from state.vscdb): ---"
if ($disabledExtensionsArray -is [System.Array] -and $disabledExtensionsArray.Count -gt 0) {
foreach ($extension in $disabledExtensionsArray) {
Write-Host "Disabled extension ID: $($extension.id)"
# Optional: Add logic here to remove the folders of these disabled extensions
# Remove-Item -Path "$env:USERPROFILE\.vscode\extensions\$($extension.id)*" -Force -Recurse
}
} else {
Write-Host "No extensions are currently listed as disabled in the database."
}
} catch {
Write-Warning "Error parsing the JSON value for disabled extensions: $($_.Exception.Message)"
Write-Host "Raw value (as string): $jsonString"
}
} else {
Write-Warning "Could not retrieve or convert the value for disabled extensions."
}
} else {
Write-Host "Key 'extensionsIdentifiers/disabled' not found in the database."
}
# --- Logic to find UNUSED (Uninstalled) Extensions ---
$installedExtensions = code --list-extensions | ForEach-Object { $_.Trim() }
$extensionFolders = Get-ChildItem -Path "$env:USERPROFILE\.vscode\extensions" -Directory | Select-Object -ExpandProperty Name
Write-Host ""
Write-Host "--- Installed extensions: ---"
foreach ($ext in $installedExtensions) {
Write-Host $ext
}
Write-Host ""
Write-Host "--- Unused (Uninstalled) Extension Folders: ---"
foreach ($folder in $extensionFolders) {
$isInstalled = $false
foreach ($installedExtension in $installedExtensions) {
if ($folder -like "$installedExtension*") {
$isInstalled = $true
break
}
}
if (-not $isInstalled) {
Write-Host "Unused folder found: $folder"
$prompt = "Do you want to delete the folder '$folder' for unused (uninstalled) extension? (y/N)"
$response = Read-Host $prompt
if ($response -ceq "y") {
Remove-Item -Path "$env:USERPROFILE\.vscode\extensions\$folder" -Force -Recurse
Write-Host "Unused folder '$folder' deleted."
Write-Host ""
}
}
}
}
finally {
if ($connection.State -eq [System.Data.ConnectionState]::Open) {
$connection.Close()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment