LDAP to OPATH Conversion - Why All The Parenthesis?
I recently was working with a customer in their process to convert their legacy Address Lists from LDAP (used by Exchange 2003) to OPATH (required by Exchange 2007/2010) and ran into an interesting find.
After using the LDAP to OPATH conversion script by Bill Long to generate and review the list, we started updating the Address List filters. The first few went fine...the converted fiter was tested, set, and then verified. The verification was to check that the RecipientFilter returned from the Get-AddressList command matched what we had entered via Set-AddressList. All was going fine, until about five Address Lists into our list when we noticied that the OPATH filter we entered had been changed...there were a TON more parenthesis in the filter than we had used!!!
Filter entered:
((Alias -ne $null) -and (customAttribute1 -eq "Contoso") -and (customAttribute2 -eq "Corporate") -and (((ObjectCategory -like "person") -and (ObjectClass -eq "user") -and -not (Database -ne $null) -and -not (ServerLegacyDN -ne $null)) -or ((ObjectCategory -like "person") -and (ObjectClass -eq "user") -and (recipientType -eq "UserMailbox")) -or ((ObjectCategory -like "person") -and (ObjectClass -eq "contact")) -or (ObjectCategory -like "group") -or (ObjectCategory -like "publicFolder") -or (ObjectCategory -like "msExchDynamicDistributionList")))
Filter returned:
((((((Alias -ne $null) -and (CustomAttribute1 -eq "Contoso"))) -and (CustomAttribute2-eq "Corporate"))) -and (((((((((((((((((ObjectCategory -like "person") -and (ObjectClass -eq "user"))) -and (-not(Database -ne $null)))) -and (-not(ServerLegacyDN -ne $null)))) -or (((((ObjectCategory -like "person") -and (ObjectClass -eq "user"))) -and (RecipientType -eq "UserMailbox"))))) -or (((ObjectCategory -like "person") -and (ObjectClass -eq "contact"))))) -or (ObjectCategory -like "group"))) -or (ObjectCategory -like "publicFolder"))) -or (ObjectCategory -like "msExchDynamicDistributionList"))))
NOTICE THE DIFFERENCE IN THE NUMBER OF PARENTHESIS!!!
The resulting filter worked fine, returning the same results as the originally specified filter, but we wondered if we had run into a bug...it seemed like all those extra parenthesis were NOT needed and might even make the filter inefficient!
After doing some research and going through TechNet articles and our bug database, it turns out this conversion is by design. The issue is that we had MULTIPLE conditions all being evaluated together:
( (Condition1) -and (Condition2) -and (Condition3) )
When the above gets parsed by PowerShell, the resulting filter will be changed and become:
( ( ( Condition1 ) -and ( Condition2) ) -and ( Condition3 ) ) )
This way when evaluated, only 2 conditions are checked at a time. In this case, it validates that Condition1 and Condition2 are both true. Then it moves on and checks that the result of that test and Condition3 are true.
Again, this is NOT a bug but BY DESIGN. It just looks wrong (especially if you have several items like this) as though something just decided to add a bunch of parenthesis for no good reason.