Trimming stale branches from Azure DevOps

Jul 28, 2023

So, basically, this script is your cleanup crew for your Azure DevOps repo. Giving everyone force-push rights to delete branches can be a bit risky. Over time, old branches pile up, and without a built-in Azure tool to handle the mess, your repo can start looking like a digital hoarder’s paradise.

This script is your broom, letting admins sweep up old branches safely and regularly, keeping things tidy without handing out keys to everyone. It’s a tidy-up hack for your repo, making everyone’s life a bit easier and your repo a lot neater.


$Bytes = [System.Text.Encoding]::ASCII.GetBytes(":$($Pat)")
$EncodedPAT = [System.Convert]::ToBase64String($Bytes)
$OrgUrl = "$OrgName"
$BaseUrl = "$OrgUrl/$Project/_apis"
$Repos = az repos list  --project $Project --query "[].{name:name, id:id}" | ConvertFrom-Json
foreach($Repo in $Repos){
    $Branches = az rest `
                    --method get `
                    --uri "$BaseUrl/git/repositories/$($" `
                    --headers "Authorization=Basic $EncodedPAT" `
                    --query "value[].{name:name,, id:commit.commitId}" `
                    | ConvertFrom-Json

    $CutOffDate = (Get-Date).AddDays($CutoffDays)

    # Filter the items
    $StaleBranches = $Branches | Where-Object { (Get-Date $_.lastPush) -lt $CutOffDate }

    foreach($Branch in $StaleBranches){
        # Skip branches in the blacklist
        if ($Blacklist -contains $ {
            Write-Output "Skipping $($ as it is in the blacklist"

        Write-Warning "Deleting $($ from  $($ Last commit was $($Branch.lastPush) ($(((Get-Date)-(Get-Date $Branch.lastPush)).Days) days ago)"
        az repos ref delete --org $OrgUrl -p $Project -r $ --name "heads/$($" --object-id $ 

Thanks to colleague for keeping standards high over here.


Yasen Dinkov

Blender Sprite Renderer

The 10 Circles of Magic in Production