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.

$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


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
                $tags = @()
                $_.Tags.GetEnumerator() |ForEach-Object {
                    [string]$tags += $_.key+ "=" + $_.value+ ";"
                $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:

Here is the sample tag csv file

Here is the script we have used to apply the tags provided in the csv to the discovered resoruces from earlier script.

# This can be modified based on your requirement.

#You can modify the path here based on your requirements.
function convertCsvToHashTable($csvFile){
    $csv=import-csv $csvFile
    $hashTable = @{}
    $csv | % {$hashTable[$_."$key"] = $_."$value"}
    return $hashTable
$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

Here is how it looks when you applied the tags into the resource.

Hope this helps.


  1. Hi Rajaniesh. Thanks for this. This has saved me heaps of time.
    It seems to work about 95% of the time. Certain resources like Application Insights seem to throw this error:
    “Update-AzTag : Cannot convert ‘System.Object[]’ to the type ‘System.String’ required by parameter ‘ResourceId’. Specified method is not supported.
    At line:26 char:29
    + Update-AzTag -ResourceId $resource.id -Tag $TagsHashTable -Operati …
    + ~~~~~~~~~~~~
    + CategoryInfo : InvalidArgument: (:) [Update-AzTag], ParameterBindingException
    + FullyQualifiedErrorId : CannotConvertArgument,Microsoft.Azure.Commands.Tags.Tag.UpdateAzureTagCommand”
    Did you run into this issue?


  2. Hi rajaniesh, Thank you so much for your article and script. I have been tasked to tag many resources! Trying to get this working but bit confused. I have success exporting the existing tag csv file but not sure how to create tags.csv file and what should I modify the exported csv. please help. if possible please share a sample file in the email. Thank you in advance _/\_


  3. Hi, Thank you so much for the script and the article. I have managed to get this working to export csv file but not sure how to create tags.csv and how to get the tag updated. if you have any sample csv file please share. Thank you so much in advance. Tx


  4. Excellent. Thank you so much for your help. you are a savior! It worked!! I owe you a drink. please send me your paypal id (you can email it to me). I will sponsor you a drink! Thank you bro again.


  5. Hi Rajaniesh.

    I think I found the issue. It looks to be when you have resources that were badly named, 2 resources being of different types but having the same name. It seems to occur when it attempts the calling of “Update-AzTag…” on line 26. The root cause seems to be that “$resource = Get-AzResource…” on line 26 seems to pick up multiple resources as an array if there is more than 1 resource of different types but with the same name. When it then tries to pass the array object into “Update-AzTag…” on line 26 it blows up.

    I assume a way to handle this in the script would probably be to output the Resource id’s and then when calling “$resource = Get-AzResource…” on line 26 looking up via resource Id instead of Name.

    Thanks for this post. It was extremely helpful.


    1. Hii Rajneesh, thank you for the article, i was able to export the csv with associated tags, some tag field were blank, so i modified the file with only blank filled tags, then i create tags.csv with key value pair, and instead of Update-AzTag i used New-AzTag unfortunately i end up having an error.
      I also tried to use -ResourceName but of no use.
      Update-AzTag : The term ‘Update-AzTag’ is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of
      the name, or if a path was included, verify that the path is correct and try again.
      New-AzTag : A parameter cannot be found that matches parameter name ‘ResourceName’.
      New-AzTag : A parameter cannot be found that matches parameter name ‘Tag’.
      New-AzTag : A parameter cannot be found that matches parameter name ‘ResourceId’.


  6. Hi Rajneesh, Thanks for the script & article, I have exported the List_Of_All_Azure_Resources_01-25-2022.csv with associated tags, i found that many resources were not tagged, in order to apply missing tags i filtered resouces with blank or missing tags, then i created tags.csv file with tags to apply, unfortunately i end up in having error term update-AzTag not found, i also tried to use New-AzTag as shown in line 26
    Update-AzTag -ResourceId $resource.id
    Uate-AzTag -Name $resource.name
    New-AzTag -ResourceId $resource.id
    New-AzTag -Name $resource.name nothing worked for me, any help here much appreciated


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 )

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.