Bulk tagging of Azure resources with PowerShell

Recently I came across a situation wherein we need to apply tags (multiple tags) to many resoruces. When I say many resoruces it means multiple subscription (25 Azure subscritpions) and in each of these subscription we have at least 500+ resources. The requirement becomes complex when we add multiple tags simultaneously. I want to achieve it in such a way that this becomes configurable and extensible solution which avoids any code change. It should work by updating the configuration.

I wrote two scripts for it. First one is Discovery script which discovers all the resoruces from all the subscriptions. Now once you have discovered all the resources from Azure you can tweaked the spreadsheet by adding or deleting the resources and this spreadhsheet will become the input for the second script which actually tags the resources. Now let’s understand these scripts:

Azure Resource Discovery script

Discovery script discovers all the resoruces from all the subscriptions and dump the info into a spreadhsheet. The name of the spreadsheet contains the current date. Here is the script.

connect-azAccount
$date = Get-Date -UFormat("%m-%d-%y")
$currentDir = $(Get-Location).Path
$oFile = "$($currentDir)\List_Of_All_Azure_Resources_$($date).csv"

if(Test-Path $oFile){
    Remove-Item $oFile -Force
}

"SUBSCRIPTION_NAME,SUBSCRIPTION_ID, RESOURCE_GROUP_NAME,RESOURCE_NAME,RESOURCE_TYPE,TAGS" | Out-File $oFile -Append -Encoding ascii

Get-AzSubscription | ForEach-Object{
    $subscriptionId = $_.Id
    $subscriptionName = $_.Name
    
    Set-AzContext -SubscriptionId $subscriptionId
    Get-AzResourceGroup | ForEach-Object{
        $resourceGroupName = $_.ResourceGroupName
        Get-AzResource -ResourceGroupName $resourceGroupName | ForEach-Object{
            $resourceName = $_.Name
             
            $resourceType = $_.ResourceType
            
            if(!([string]::IsNullOrEmpty($_.Tags))){
                $tags = @()
                $_.Tags.GetEnumerator() |ForEach-Object {
                    [string]$tags += $_.key+ "=" + $_.value+ ";"
                }
            }
            else{
                $tags = ""
            }
            
            "$subscriptionName,$subscriptionId,$resourceGroupName,$resourceName,$resourceType,$tags" | Out-File $oFile -Append -Encoding ascii
        }
    }
}

This script will create the csv file containing the list of all the resources. Here is the sample:

Azure Resource Tagging script

This script takes the inputs from csv file generated by the discovery script and you can add /delete or update the values in the spreadsheet based on your requirement. Once the spreadsheet it ready, you can create csv file which contains comma separated list of tags. This script will take this csv file as another input. Here is the tag csv file:

Comma separated list of tags

Here is the script we have used.

Connect-AzAccount 
# This can be modified based on your requirement.
$TagFilePath="C:\tags\inventory\tags.csv"

#You can modify the path here based on your requirements.
$ResourceToTagFilePath="C:\tags\inventory\List_Of_All_Azure_Resources_05-25-21.csv"
 
function convertCsvToHashTable($csvFile){
    $csv=import-csv $csvFile
    $headers=$csv[0].psobject.properties.name
    $key=$headers[0]
    $value=$headers[1]
    $hashTable = @{}
    $csv | % {$hashTable[$_."$key"] = $_."$value"}
    return $hashTable
}
 $TagsHashTable=@{}
$TagsHashTable=convertCsvToHashTable $TagFilePath
  $csv = import-csv $ResourceToTagFilePath

$csv | ForEach-Object {
    Write-Host " $($_.RESOURCE_NAME), $($_. RESOURCE_GROUP_NAME), $($_.SUBSCRIPTION_ID ) "
   Set-AzContext $_.SUBSCRIPTION_ID

   $resource = Get-AzResource -Name $_.RESOURCE_NAME -ResourceGroup $_.RESOURCE_GROUP_NAME
   Update-AzTag -ResourceId $resource.id -Tag $TagsHashTable -Operation Merge
 }

Hope this helps.

1 Comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.