Export Azure Resource Groups with Tags to csv Export Azure Resource Groups with Tags to csv powershell powershell

Export Azure Resource Groups with Tags to csv


The main thing to understand here is how to work with hashtables as that is what the Tags property contains. The other thing we need to account for is that tags are not consistent, no matter how hard we try as administrators, this will lead to inconsistent properties in our array of PSObjects if we just add properties for the tags from each individual Resource Group. So in advance of starting any sorting of the data for the CSV file, we need a unique list of tags across all groups. Resource Groups that don't have that tag, will need the property just so we have a complete set of data for the resulting CSV file. Anyway, less talking, more code.

# Initialise output array$Output = @()# Collect all the groups from the current subscription$ResourceGroups = Get-AzResourceGroup# Obtain a unique list of tags for these groups collectively# Use Sort-Object as per - https://github.com/PowerShell/PowerShell/issues/12059$UniqueTags = $ResourceGroups.Tags.GetEnumerator().Keys | Sort-Object -Unique# Loop through the resource groupsforeach ($ResourceGroup in $ResourceGroups) {    # Create a new ordered hashtable and add the normal properties first.    $RGHashtable = [ordered] @{}    $RGHashtable.Add("Name",$ResourceGroup.ResourceGroupName)    $RGHashtable.Add("Location",$ResourceGroup.Location)    $RGHashtable.Add("Id",$ResourceGroup.ResourceId)    $RGHashtable.Add("ProvisioningState",$ResourceGroup.ProvisioningState)    # Loop through possible tags adding the property if there is one, adding it with a hyphen as it's value if it doesn't.    if ($ResourceGroup.Tags.Count -ne 0) {        $UniqueTags | Foreach-Object {            if ($ResourceGroup.Tags[$_]) {                $RGHashtable.Add("$_ (Tag)",$ResourceGroup.Tags[$_])            }            else {                $RGHashtable.Add("$_ (Tag)","-")            }        }    }    else {        $UniqueTags | Foreach-Object { $RGHashtable.Add("$_ (Tag)","-") }    }    # Update the output array, adding the ordered hashtable we have created for the ResourceGroup details.    $Output += New-Object psobject -Property $RGHashtable}# Sent the final output to CSV$Output | Export-Csv -Path test.csv -NoClobber -NoTypeInformation -Encoding UTF8 -Force

I ran a test with just some basic data in a similar structure, because I'm not on my work machine currently.

$eur = "" | select ResourceGroupName,Location,Tags,ResourceId,ProvisioningState$asia = "" | select ResourceGroupName,Location,Tags,ResourceId,ProvisioningState$na = "" | select ResourceGroupName,Location,Tags,ResourceId,ProvisioningState$sa = "" | select ResourceGroupName,Location,Tags,ResourceId,ProvisioningState$eur.ResourceGroupName = "ParisDC"$eur.Location = "westeurope"$eur.ResourceId = 1$eur.ProvisioningState = "Succeeded"$tags = @{    Computer = "FRDC01"    IP = "10.11.10.10"    Datacenter = "West Europe"    CostCode = 54321}$eur.Tags = $tags$asia.ResourceGroupName = "TokyoDC"$asia.Location = "eastasia"$asia.ResourceId = 2$asia.ProvisioningState = "Succeeded"$tags = @{    Server = "TODC01"    IP = "10.12.10.10"    CostCode = 98765}$asia.Tags = $tags$na.ResourceGroupName = "NewYorkDC"$na.Location = "eastus"$na.ResourceId = 3$na.ProvisioningState = "Failed"$tags = @{    Computer = "USDC01"    IP = "10.10.10.10"    Owner = "John Smith"    CostCode = 12345}$na.Tags = $tags$sa.ResourceGroupName = "RioDC"$sa.Location = "brazilsouth"$sa.ResourceId = 4$sa.ProvisioningState = "Succeeded"$tags = @{}$sa.Tags = $tags$ResourceGroups += $sa,$na,$eur,$asia

If you want to see the sample, just copy and paste the data, and then omit the line $ResourceGroups = Get-AzResourceGroup in the code I provided.

Resulting output:

Name      Location    Id ProvisioningState IP (Tag)    Computer (Tag) Owner (Tag) CostCode (Tag) Datacenter (Tag) Server (Tag)----      --------    -- ----------------- --------    -------------- ----------- -------------- ---------------- ------------RioDC     brazilsouth  4 Succeeded         -           -              -           -              -                -NewYorkDC eastus       3 Failed            10.10.10.10 USDC01         John Smith  12345          -                -ParisDC   westeurope   1 Succeeded         10.11.10.10 FRDC01         -           54321          West Europe      -TokyoDC   eastasia     2 Succeeded         10.12.10.10 -              -           98765          -                TODC01


I've updated your script a bit and added additional functionality.

  • You can now pull tags for resource groups as well as resources
  • Selecting multiple subscriptions and pulling all required information at same time
  • Fixed issue when there were two similar tags like "testname" and "testname " (extra space at the end - don't even ask :P hehe). To make it more visible it's exporting tags with extra square brackets e.g (testname )
  • Changed hashtable type (if I remember correctly as that was a few days ago it was to account for lower case and upper case tags).
Login-AzAccount$Subscription = Get-AzSubscription | Out-GridView -Title 'Select subscription' -OutputMode 'Multiple'# Initialise output array$Output = @()if($Subscription){    foreach ($item in $Subscription)    {        $item | Select-AzSubscription        # Collect all the resources or resource groups (comment one of below)        #$Resource = Get-AzResource        $Resource = Get-AzResourceGroup        # Obtain a unique list of tags for these groups collectively        $UniqueTags = $Resource.Tags.GetEnumerator().Keys | Get-Unique �AsString | Sort-Object | Select-Object -Unique | Where-Object {$_ -notlike "hidden-*" }        # Loop through the resource groups        foreach ($ResourceGroup in $Resource) {            # Create a new ordered hashtable and add the normal properties first.            $RGHashtable = New-Object System.Collections.Specialized.OrderedDictionary            $RGHashtable.Add("Name",$ResourceGroup.ResourceGroupName)            $RGHashtable.Add("Location",$ResourceGroup.Location)            $RGHashtable.Add("Id",$ResourceGroup.ResourceId)            $RGHashtable.Add("ResourceType",$ResourceGroup.ResourceType)            # Loop through possible tags adding the property if there is one, adding it with a hyphen as it's value if it doesn't.            if ($ResourceGroup.Tags.Count -ne 0) {                $UniqueTags | Foreach-Object {                    if ($ResourceGroup.Tags[$_]) {                        $RGHashtable.Add("($_) tag",$ResourceGroup.Tags[$_])                    }                    else {                        $RGHashtable.Add("($_) tag","-")                    }                }            }            else {                $UniqueTags | Foreach-Object { $RGHashtable.Add("($_) tag","-") }            }                        # Update the output array, adding the ordered hashtable we have created for the ResourceGroup details.            $Output += New-Object psobject -Property $RGHashtable        }        # Sent the final output to CSV        $Output | Export-Csv -Path c:\temp\1a.csv -append -NoClobber -NoTypeInformation -Encoding UTF8 -Force    }}$Output | Out-GridView