top of page

Automating Tag Deletion in Azure DevOps Repositories

In this technical blog, we will discuss how to automate the process of deleting tags from Azure DevOps repositories that are older than 45 days. As a best practice, it is essential to clean up old tags regularly to avoid clutter and improve repository management. By automating this process, you can ensure that your Azure DevOps repositories remain organized, making it easier to find and work with the latest code versions.


  • Access to an Azure DevOps organization with appropriate permissions to manage repositories.

  • Basic knowledge of Azure DevOps REST APIs and PowerShell scripting.

Automating tag deletion-Azure DevOps Repository

Step 1: Identify Tags to Delete Before proceeding with the tag deletion process, you need to identify the tags that are older than 45 days. Azure DevOps provides a REST API that allows us to query the list of tags associated with a repository.

Step 2: Automate Tag Deletion We will use PowerShell scripting to automate the tag deletion process. Follow these steps:

1. Set up an Azure DevOps Personal Access Token (PAT):

  • Go to your Azure DevOps organization, navigate to "User Settings" and then "Personal Access Tokens."

  • Generate a new token with appropriate repository permissions.

2. Create a PowerShell Script:

  • Create a new PowerShell script, e.g., "DeleteOldTags.ps1".

  • Use the Azure DevOps REST API to query tags and delete old ones.

3. Authentication:

  • In the PowerShell script, include the PAT to authenticate API requests.

4. Get Repository Information:

  • Use the REST API to get a list of repositories in your Azure DevOps organization.

5. Loop Through Repositories:

  • For each repository, get the list of tags using the REST API.

  • Loop through the list of tags and identify those that are older than 45 days.

6. Delete Old Tags:

  • Use the REST API to delete the identified old tags from each repository.

7. Schedule the Script:

  • Schedule the PowerShell script to run automatically at regular intervals (e.g., daily or weekly) using Windows Task Scheduler or Azure Automation.

Step 3: Testing and Error Handling

  • Before running the script in production, test it on a test repository to ensure it behaves as expected.

  • Implement proper error handling in the script to handle scenarios where the API requests fail or encounter unexpected issues.

Step 4: Notify Stakeholders

  • Inform your team and stakeholders about the implementation of the tag deletion automation process. Let them know the benefits of keeping the repository organized and the schedule for the automated tag deletion.

By automating the deletion of old tags in your Azure DevOps repositories, you can maintain a clean and organized codebase, leading to improved collaboration and streamlined development processes. Regularly removing old tags ensures that your team is focused on working with the latest code versions and avoids confusion caused by a plethora of outdated tags. Implementing this automated process will help your team save time and effort while promoting best practices for repository management in Azure DevOps.

Below is the PowerShell script to automate the deletion of tags older than 45 days from Azure DevOps repositories:


[string]$AzureDevOpsOrgUrl = "", # Replace with your Azure DevOps organization URL

[string]$PersonalAccessToken = "YOUR_PERSONAL_ACCESS_TOKEN" # Replace with your Personal Access Token


# Function to authenticate API requests

function Authenticate {

$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$($PersonalAccessToken)"))

return @{Authorization=("Basic {0}" -f $base64AuthInfo)}


# Function to get repositories from Azure DevOps organization

function Get-AzureDevOpsRepositories {

$apiUrl = "$AzureDevOpsOrgUrl/_apis/git/repositories?api-version=6.0"

$headers = Authenticate

$response = Invoke-RestMethod -Uri $apiUrl -Headers $headers -Method Get

return $response.value


# Function to get tags for a repository

function Get-AzureDevOpsTags {




$apiUrl = "$AzureDevOpsOrgUrl/_apis/git/repositories/$repositoryId/refs/tags?api-version=6.0"

$headers = Authenticate

$response = Invoke-RestMethod -Uri $apiUrl -Headers $headers -Method Get

return $response.value


# Function to delete a tag from a repository

function Delete-AzureDevOpsTag {





$apiUrl = "$AzureDevOpsOrgUrl/_apis/git/repositories/$repositoryId/refs/tags/$tagId?api-version=6.0"

$headers = Authenticate

Invoke-RestMethod -Uri $apiUrl -Headers $headers -Method Delete


try {

# Get the current date and calculate the date 45 days ago

$currentDate = Get-Date

$daysToKeep = 45

$cutOffDate = $currentDate.AddDays(-$daysToKeep)

# Get all repositories in the Azure DevOps organization

$repositories = Get-AzureDevOpsRepositories

foreach ($repo in $repositories) {

$repositoryId = $

$repositoryName = $

Write-Host "Processing repository: $repositoryName"

# Get all tags for the current repository

$tags = Get-AzureDevOpsTags -repositoryId $repositoryId

foreach ($tag in $tags) {

$tagName = $

$tagDate = [DateTime]::Parse($tag.object.authoredDate)

# Check if the tag is older than the cutoff date

if ($tagDate -lt $cutOffDate) {

Write-Host "Deleting old tag: $tagName from repository: $repositoryName"

Delete-AzureDevOpsTag -repositoryId $repositoryId -tagId $tagName




Write-Host "Tag deletion process completed successfully."


catch {

Write-Host "Error occurred: $_"



  • Replace Your Organization in $AzureDevOpsOrgUrl with your actual Azure DevOps organization name.

  • Replace "YOUR_PERSONAL_ACCESS_TOKEN" in $PersonalAccessToken with your actual Personal Access Token, which should have appropriate repository permissions.

  • The script will loop through all repositories in the Azure DevOps organization and delete tags that are older than 45 days.

Please ensure that you thoroughly test the script in a test environment before running it against your production repositories. Additionally, schedule the script to run at regular intervals using Windows Task Scheduler or Azure Automation to keep your repositories clean and organized.

bottom of page