VLV AddressListPaging

Eine Fehlermeldung und ein Blick mit ADSIEDIT in die Exchange Konfiguration hat mir Einträge zu Adresslisten gezeigt, die ich viele Jahre nicht mal kannte. Was steck dahinter?

Einsatzbereich

Exchange skaliert vom kleinen Small Business Server mit weniger als 100 Postfächern bis zur XXL-Installation mit mehreren hunderttausend Benutzern. Entsprechend groß werden die Adressbücher. Die GAL enthält alle Empfänger und wer per LDAP diese Datenmenge einlesen will, muss meist nach 1000 Objekten erkennen, dass er "Page Search" nutzen sollte, um immer die nächsten 1000 Objekte zu bekommen. Aber ich kann hier immer nur ein "GetNext" machen aber nicht rückwärts gehen. Was macht aber eine Software wie Exchange, wenn ein Anwender z.B. in OWA in einem Adressbuch vor uns zurückblättern will? Alle Einträge in einen Cache oder einen Buffer zu laden kann auch nicht die Lösung sein. Gesucht wird eine Lösung, um im AD auch diese Anforderung zu erfüllen. Dafür gibt es die Funktion Virtual List View (VLV).

Eine zweite Herausforderung ist generell die Suche mit großen Ergebnissen. Jeder Exchange-Empfänger hat z.B. das Property "showInAddressbook" ist bei sehr vielen Objekten mit einer Referenz auf die jeweilige Adressliste verbunden.

Umgekehrt ist aber bei der Adressliste kein "Member"-Attribut, in der die Objekte verknüpft sind. Wenn ich nun von einem Client alle Objekte aus einer Adressliste anzeigen lassen will, dann kann ich nicht wie bei einer Gruppe einfach die Adressliste als Basis nutzen und nach den Mitgliedern suchen. Ich muss umgekehrt nach allen Objekten suchen, in denen das Feld "showInAddressBook" den DistinguishedName der Adressliste enthält und das ist ein großer Aufwand für einen Domain Controller.

Eine Beschreibung von Microsoft finden Sie in der Beschreibung zum Exchange Health Checker, welcher

A virtual list is a GUI technique that is employed when ordered lists containing a large number of entries need to be displayed. When the LDAP protocol is extended to use VLV, a window that contains a small number of visible list entries is drawn. The visible portion of the list can be relocated to different points in the list by means of scrolling, slider bars, and cursor keys as well as PAGE UP and PAGE DOWN keys. The user experience is that the full list can be browsed at will, even though it might contain millions of entries. In fact, the complete list contents are never required at any one time. Rather than retrieve the complete list from wherever it is stored (typically, from disk or a remote server), the server retrieves only the information that is required to display the part of the list that is currently in view on the client.
When you have indexed appropriate attributes to use VLV, you can use Ldp (or other VLV-enabled applications) to retrieve large lists from Active Directory without requiring the server to return the entire contents of the results set (improving response speed) and without requiring the search client to store the results set in memory (improving the speed at which results are listed).
Quelle https://learn.microsoft.com/en-us/previous-versions/office/exchange-server-analyzer/cc540446(v=exchg.80)

ADSIEDIT

Wer mit ADSIEDIT in der Exchange Konfiguration stöbert, stößt auf eine besondere OU, die etwas mit VLV = Virtual List View zu tun hat. Ich finde die hier normalen Adresslisten und die Globalen Adresslisten aber auch einen Container, der als "All System Address Lists" ausgezeichnet ist.

Ein genauerer Blick auf die Adressliste zeigt nicht nur den Adressbuchfilter sondern auch das Flag "msExchSystemAddressList=true".

dn: CN=TeamMailboxes(VLV),
      CN=All System Address Lists,
        CN=Address Lists Container,
          CN=First Organization,
            CN=Microsoft Exchange,
              CN=Services,
                CN=Configuration,
                  DC=ex2019,DC=msxfaq,DC=de
changetype: add
objectClass: top
objectClass: addressBookContainer
cn: TeamMailboxes(VLV)
instanceType: 4
displayName: TeamMailboxes(VLV)
showInAdvancedViewOnly: TRUE
name: TeamMailboxes(VLV)
systemFlags: 1610612736
objectCategory:  CN=Address-Book-Container,CN=Schema,CN=Configuration,DC=ex2019,DC=msxfaq,DC=de
purportedSearch: 
 (|(&(!(!(objectClass=user)))(objectCategory=person)(mailNickname=*)(msExchHome
 ServerName=*)(msExchRecipientTypeDetails=137438953472)))
msExchSystemAddressList: TRUE
msExchMinAdminVersion: -2147453113
msExchVersion: 4535486012416
msExchQueryFilter: ((RecipientTypeDetails -eq 'TeamMailbox'))
msExchProvisioningFlags: 0
msExchRecipientFilterFlags: 1
msExchQueryFilterMetadata: 
 Microsoft.Exchange12.8f91d340bc0c47e4b4058a479602f94c:RecipientFilterType=1

Sie finden hier auch kein Backlink-Attribut auf die Objekte, die in dieser Adressliste enthalten sind.

Wenn ein Client nun so eine Adressbuch aufklappt, dann nutzt er nicht das Feld "purportedSearch" oder "msExchQueryFilter" zur Suche nach den Personen sondern bei den Objekten gibt es das "showinAddressBook"-Feld, welches auf die Adressliste verweist.

Exchange: Enable/Disable

In Verbindung mit diesen Adresslisten gibt es auch zwei Exchange PowerShell Commandlets, mit denen ich etwas Ein- und Ausschalten kann.

Es gibt allerdings kein "Get-Addresslistpaging", um die aktuelle Konfiguration zu ermitteln. Beim Enable-AddressListPaging kommt keine Rückfrage und keine Info und beim Disable-AddressListPaging kommt nur de Rückfrage, ob es wirklich deaktiviert werden soll aber auch keine Information über die Änderungen. Also habe ich mit LDIFDE einen Export der Configuration-Partition meiner Lab-Umgebung gemacht, den Status geändert und wieder einen Export zum Vergleich gezogen. Die einzige Änderung war ein Feld im Organisations-Container von Exchange

CN=<Orgname>,CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=<domain>,DC=<tld>
msExchAddressListPagingEnabled: True

Das Feld können Sie ebenfalls in ADSIEDIT sehen:

Die Frage ist natürlich, wozu diese Befehle vorhanden sind. Aber auch hier finden Sie entsprechende Quellen, wenn wir nur lange genug suchen:

Exchange 2010 now creates system address lists in a new container. Recipients created or modified using Exchange 2003 or Exchange 2007 management tools won’t be stamped with these system address lists. As a result, they won’t be seen by the Exchange 2010 Get-Recipient cmdlet.
To fix this issue, you must enable Active Directory virtual list view (VLV). After you have completed the upgrade of an existing Exchange 2003 organization to Exchange 2010 and have decommissioned your Exchange 2003 servers, you must enable Active Directory VLV.
To enable VLV for Exchange 2010, run the Enable-AddressListPaging cmdlet. For more information, see Enable-AddressListPaging.
Quelle https://learn.microsoft.com/en-us/previous-versions/office/exchange-server-2010/dd638130(v=exchg.141)

Ich bin ziemlich sicher, dass die meisten Migrationen diesen Schritt damals nicht durchgeführt haben.
Interessanterweise scheint der "Exchange Health Analyzer" diesen Mangel aber nicht zu melden.

AD: DisableVLVSupport

Bei der Recherche bin ich noch auf das Feld "DisableVLVSupport" unter "CN=Directory Services" gestoßen.

Die Einstellung von "DisableVLVSupport" ist erst ab Windows 2003 SP1 oder Windows 2003R2, ADAM SP1 und neuer vorhanden. Nur Windows 2003 RTM und ADAM RTM haben diese Funktion noch nicht aber sollten heute keine Rolle mehr spielen.

Achtung: Deaktivieren sie VLV bitte nicht, denn Exchange benötigt diese Funktion und der Exchange Health Checker prüft auch diese Einstellung:

Schema

Für die schnelle Suche muss das Active Directory natürlich den passenden Index vorhalten. Ähnlich der Steuerung, welche Felder in den "Global Catalog" aufgenommen werden, wird im Schema auch hinterlegt, welche Felder in dem Index für die VLV-Suche aufgenommen wird.

Relevant ist dabei die Checkbox bei "Index this attribute for containerized searches".

LDAP-Query

Eine Software muss natürlich auch die "richtige LDAP-Frage" stellen, damit die neuen Möglichkeiten auch genutzt werden. Einen Beispielcode habe ich dazu bislang nicht entwickelt, denn meine Skripte suchen meist nur ein Objekt oder brauchen sowieso die gesamte Liste. Aber Microsoft hat die VLV-Funktion mit einem Beispielcode dokumentiert.

Einschätzung

Vor ein paar Tagen habe ich mit Exchange Intern/Extern eine Funktion von Exchange beim Mailrouting beschrieben, auf die ich erst im Rahmen eines Support Case gestoßen bin. Ich kann mich beim Besten willen nicht daran erinnern, bei den damaligen Updates von Exchange 200/2003 auf 2007 nach der Deinstallation des letzten Exchange 2000/2003-Servers ein "Enable-AddressListPaging" gemacht zu haben.

Allerdings ist auch bei einem neuen Exchange 2016-Setup, bei dem es nie eine Exchange 2000/2003 Vorgeschichte gab, das Feld "msExchAddressListPagingEnabled" in der Exchange Organisation nicht gesetzt.

Ich vermute mal, dass Exchange nach dem Ende von 2003 spätestens mit Exchange 2013 den DefaultWert nun geändert hat und immer VLV nutzt, es sei denn Sie schalten es manuell ab.

Sobald ich hierzu weitere Erkenntnisse habe, erweiterte ich diese Seite.

Weitere Links