public/Set-AzureResourceTags.ps1
function Set-AzureResourceTags { <# .SYNOPSIS Set standard tags for a given Azure resource, or multiple Azure resources .DESCRIPTION Set-AzureResourceTags cmdlet sets standard tags for a given Azure resource, or multiple Azure resources. Input is a json data, which can be built manually or converted form a csv file. .PARAMETERS jsonObject Use following data structure (only 'Resource Name' and 'Resource Type' are mandatory for Azure resource correlation, the rest are entirely custom tag key/value pairs): [ { "Resource Name": "", "Resource Role": "", "Resource Type": "", "Resource Class": "", "Primary Contact": "", "Cost Center": "", "Business Value": "", "Notes": "" } ] .EXAMPLE $<VariableName> = Import-Csv <CSVfilepath> $<VariableName1> = $<VariableName> | ConvertTo-Json Set-AzureResourceTags -jsonobject $<VariableName1> -subscriptionname <SubscriptionName> -Verbose #> [cmdletbinding()] Param ( [parameter(Mandatory=$true, ValueFromPipeline=$true)] [string]$jsonobject, [parameter(Mandatory=$false)] [bool]$replace = $false ) Process { # check to see if local token exists (ran Login-AzureRMAccount) if (($null -eq (Get-AzureRmContext).Account)) { Write-Warning "Please run < Login-AzureRMAccount > first to create a session token...exiting." break } # convert json literal string to system.object Try { $targetresources = $jsonobject | ConvertFrom-Json -ErrorAction Stop -Verbose } Catch { $error[0].Exception break } $currentsubscription = (Get-AzureRmContext).subscription.Name if (($null -eq $currentsubscription)) { Write-Warning "No subscription selected. Run Select-AzureRMSubscription to target a specific subscription, before running this tool again." break } else { Write-Verbose "Current subscription is '$currentsubscription'. " } # get resources in current subscription and reconcile with input data Try { $resources = Get-AzureRmResource -ErrorAction Stop -Verbose } Catch { $error[0].Exception break } $resourcesnotfound = @() $foundresources = @() $targetresources | ForEach-Object { Write-Debug "validating resource name $($_.'resource name')" if ("$($_.'Resource Name')" -in $resources.name) { Write-Verbose "Found $($_.'Resource Name') in current subscription's resources" $foundresources += $_ } elseif ($_."resource name" -notin $resources.name) { Write-Warning "$($_.'Resource Name') not found in current subscription's resource list" $resourcesnotfound += $_ } else { Write-Warning "resource reconciliation condition failed" break } } # end foreach jsonobject loop # replace exiting values if (($replace -eq $true)) { foreach ($resource in $foundresources) { $totag = $resources | Where-Object {($_.name -eq "$($resource.'Resource Name')" -and ($_.resourcetype -eq "$($resource.'resource type')"))} if (($totag).count -ge 2) { Write-Warning "Multiple resources found using resource name of $($resource.'Resource Name') and type of $($resource.'Resource Type'). Remediate the resource below manually." $totag break } # convert pscustomobject to hashtable to enumerate keys/values $tags = Convert-JsonToHash -json $resource Try { $parameters = @{ ResourceGroupName = "$($totag.resourcegroupname)"; ResourceName = "$($totag.resourcename)"; ResourceType = "$($totag.resourcetype)"; Tags = $tags } $tagoperation = Set-AzureRmResource @parameters -ErrorAction Stop -Verbose -Force } Catch { $error[0].Exception continue } } } elseif (($replace -eq $false)) { foreach ($resource in $foundresources) { $totag = $resources | Where-Object {($_.name -eq "$($resource.'Resource Name')" -and ($_.resourcetype -eq "$($resource.'resource type')"))} if (($totag).count -ge 2) { Write-Warning "Multiple resources found using resource name of $($resource.'Resource Name') and type of $($resource.'Resource Type'). Remediate the resource below manually." $totag break } # convert pscustomobject to hashtable to enumerate keys/values $tags = Convert-JsonToHash -json $resource Try { $ErrorActionPreference = 'Stop' $tags += ($totag).tags } Catch [System.ArgumentException] { Write-Warning $error[0].Exception.Message } Finally { $ErrorActionPreference = 'Continue' } Try { $parameters = @{ ResourceGroupName = "$($totag.resourcegroupname)"; ResourceName = "$($totag.resourcename)"; ResourceType = "$($totag.resourcetype)"; Tags = $tags } $tagoperation = Set-AzureRmResource @parameters -ErrorAction Stop -Verbose -Force } Catch { $error[0].Exception continue } } } else { Write-Warning "Failed to evaluate whether or not to replace tags." break } if (($resourcesnotfound.Count -ne 0)) { Write-Warning "Some resources were not found in the current subscription..." return $resourcesnotfound } else { Write-Verbose "All resources accounted for in current subscription." } } # end process block } # end Set-AzureResourceTags function |