DEV Community

Matthew Dailey
Matthew Dailey

Posted on

4 2

Bulk delete stored npm packages from Azure Artifacts

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
    }
}
Enter fullscreen mode Exit fullscreen mode

The GitHub Gist link.

Speedy emails, satisfied customers

Postmark Image

Are delayed transactional emails costing you user satisfaction? Postmark delivers your emails almost instantly, keeping your customers happy and connected.

Sign up

Top comments (0)

Some comments may only be visible to logged-in visitors. Sign in to view all comments.

Billboard image

Try REST API Generation for Snowflake

DevOps for Private APIs. Automate the building, securing, and documenting of internal/private REST APIs with built-in enterprise security on bare-metal, VMs, or containers.

  • Auto-generated live APIs mapped from Snowflake database schema
  • Interactive Swagger API documentation
  • Scripting engine to customize your API
  • Built-in role-based access control

Learn more