Bulk delete stored npm packages from Azure Artifacts
Matthew Dailey
Posted on April 9, 2022
At my work we used to store our npm packages in an Azure Artifacts feed. We realized this was no longer necessary since we didn't publish our own custom packages anymore. Plus, over time all the different versions of the stored npm packages were taking up a large amount of space, close to 3GB in our cloud instance.
Using the Azure DevOps REST API, I came up with a Powershell script that will bulk delete all npm packages from an Azure Artifacts feed. You will need to generate a PAT (Personal Access Token) with full privileges regarding packages and paste it into the script code. The organization name and feed id also needs to be added.
If there is a large amount of packages with accompanying versions, the script will need to run multiple times. There is a limit to the number of stored package versions that can be retrieved at one time.
The way the script works is it retrieves all the versions of the stored npm packages, loops through the versions and deletes them. In order to delete any package in Azure Artifacts, be it npm or NuGet, you have to delete the specific package version. The script can be modified in case you want to only delete certain versions of packages by changing the url that retrieves the package versions.
Here is the script. Run it on your local machine.
<# Azure DevOps REST API #>
$url1 = 'https://feeds.dev.azure.com/{organization}/_apis/packaging/Feeds/{feed_id}/packages?protocolType=npm&includeAllVersions=true&api-version=7.1-preview.1'
$Token = '{Personal_Access_Token}'
if ($Token -eq "") {
Write-Host 'PAT not set'
exit 1
}
$AzureAuthHeader1 = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f "", $Token)))
$headers1 = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers1.Add("Authorization", ("Basic {0}" -f $AzureAuthHeader1))
$headers1.Add("Content-Type", "application/json")
$response1 = Invoke-RestMethod -Uri $url1 -Method GET -Headers $headers1
$packages = $response1.value
<# Loops through returned npm package versions and deletes them #>
Foreach ($i in $packages)
{
$packageName = $i.name
Write-Host $i.name -BackgroundColor cyan
$allversions = $i.versions
Foreach ($v in $allversions) {
$packageVersion = $v.version
$url2 = 'https://pkgs.dev.azure.com/{organization}/_apis/packaging/feeds/{feed_id}/npm/{0}/versions/{1}?api-version=7.1-preview.1' -f $packageName, $packageVersion
$AzureAuthHeader2 = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f "", $Token)))
$headers2 = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers2.Add("Authorization", ("Basic {0}" -f $AzureAuthHeader2))
$headers2.Add("Content-Type", "application/json")
$response2 = Invoke-RestMethod -Uri $url2 -Method DELETE -Headers $headers2
Write-Host 'deleted' + $response2.value
}
}
The GitHub Gist link.
Posted on April 9, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.