Search code examples
azurepowershelltagstagging

loop through azure objects and filter them on tags


I have a question , recently we started using Tagging in Azure and needed to list specific object by thier Tags. Below is the script used to find the resources. in both cases we find a specific object in the results when using match and notmatch. This is strange behaviour when searching Tagged resources. what other ways do you use to complete the task?

PS C:\WINDOWS\system32> $KeyName = 'Department'
PS C:\WINDOWS\system32> $NewKeyValue = "PROD, Data"
PS C:\WINDOWS\system32> $AzSqlServer = Get-AzSqlServer
PS C:\WINDOWS\system32>          if($AzSqlServer)
>>     {
>> foreach ($server in $AzSqlServer )
>> {
>> $SQLDatabase = Get-AzSqlDatabase -ServerName $server.ServerName -ResourceGroupName $server.ResourceGroupName| Where-Object {$_.tags.Values -notmatch "PROD, Data"}
>> write-output $SQLDatabase.DatabaseName
>> }
>> }
DBname1
DBname2
DBname3
DBname4
master
master
master
**DBname5**
PS C:\WINDOWS\system32>
PS C:\WINDOWS\system32> $KeyName = 'Department'
PS C:\WINDOWS\system32> $NewKeyValue = "PROD, Data"
PS C:\WINDOWS\system32> $AzSqlServer = Get-AzSqlServer
PS C:\WINDOWS\system32>          if($AzSqlServer)
>>     {
>> foreach ($server in $AzSqlServer )
>> {
>> $SQLDatabase = Get-AzSqlDatabase -ServerName $server.ServerName -ResourceGroupName $server.ResourceGroupName| Where-Object {$_.tags.Values -match "PROD, Data"}
>> write-output $SQLDatabase.DatabaseName
>> }
>> }
**DBname5**

Solution

  • The problem here is with unexpected results of using -notmatch and -match operators against a list. Switching to -notcontains and -contains for exact matches will produce the desired result.

    $AzSqlServer = Get-AzSqlServer
    if ($AzSqlServer) {
        foreach ($server in $AzSqlServer) {
            $SQLDatabase = Get-AzSqlDatabase -ServerName $server.ServerName -ResourceGroupName $server.ResourceGroupName |
                Where-Object {$_.tags.Values -notcontains "PROD, Data"}
            $SQLDatabase.Databasename
        }
    }
    

    When using -notcontains, a list's items are compared in their entirety. The list will only return true if there are no items that match the target item. When using -notmatch against a list, the list's items that do not match the target item are returned. Any returned item results in a True result in a boolean statement. Below is a simplified example of your experience:

    # Notice how both boolean statements return True
    PS> 1,2,3 -notmatch 2
    1
    3
    PS> [bool](1,2,3 -notmatch 2)
    True
    PS> 1,2,3 -match 2
    2
    PS> [bool](1,2,3 -match 2)
    True
    
    # Now using -notcontains and -contains
    PS> 1,2,3 -notcontains 2
    False
    PS> 1,2,3 -contains 2
    True