The Partner Catalyst Team at Microsoft has grown exponentially over the last year; at present, we have over 70 folks worldwide sharing one Azure subscription. The team has been organizing their Azure resources into resource groups and have been following a naming pattern that includes the project name and/or the owner. Naturally, however, resources will be forgotten, and as our subscription begins to near the subscription limits for cores and storage accounts, we need to take more immediate action in identifying and removing unused resources in our subscription.

Inspired by Max Knor, we used a PowerShell script to ascertain the owner of a resource group and apply a Created-By tag to the resource group. The PowerShell script is very similar to Max's with a couple of minor changes such as identifying the owner based on the creator of the resource group or deployment and appending tags (instead of doing a replace-all):

$allRGs = (Get-AzureRmResourceGroup).ResourceGroupName
Write-Warning "Found $($allRGs | measure | Select -ExpandProperty Count) total RGs"

$aliasedRGs = (Find-AzureRmResourceGroup -Tag @{ "CREATED-BY" = $null }).Name
Write-Warning "Found $($aliasedRGs | measure | Select -ExpandProperty Count) aliased RGs"
$notAliasedRGs = $allRGs | ?{-not ($aliasedRGs -contains $_)}
Write-Warning "Found $($notAliasedRGs | measure | Select -ExpandProperty Count) un-tagged RGs"

foreach ($rg in $notAliasedRGs)
    $currentTime = Get-Date

    $endTime = $currentTime.AddDays(-7 * $cnt)
    $startTime = $endTime.AddDays(-7)
    $callers = Get-AzureRmLog -ResourceGroup $rg -StartTime $startTime -EndTime $endTime -WarningAction SilentlyContinue |
        Where {$_.Authorization.Action -eq "Microsoft.Resources/deployments/write" -or $_.Authorization.Action -eq "Microsoft.Resources/subscriptions/resourcegroups/write" } | 
        Select -ExpandProperty Caller | 
        Group-Object | 
        Sort-Object  | 
        Select -ExpandProperty Name

    if ($callers)
        $owner = $callers | Select-Object -First 1
        $alias = $owner -replace "",""
        $tags = (Get-AzureRmResourceGroup -Name $rg).Tags
        $tags += @{ "CREATED-BY"=$alias }

        $rg + ", " + $alias
        if (-not $dryRun) 
            Set-AzureRmResourceGroup -Name $rg -Tag $tags
        $rg + ", Unknown"

At a glance, we can now see who owns a particular resource group: