Use Event1644Reader.ps1 to analyze LDAP query performance in Windows Server
This article describes a script that helps analyze Active Directory event ID 1644 in Windows Server. Review the steps to use the script and then analyze your problems.
Original KB number: 3060643
About the Event1644Reader.ps1 script
Active Directory event ID 1644 is logged in the Directory Service event log. This event identifies expensive, inefficient, or slow Lightweight Directory Access Protocol (LDAP) searches that are serviced by Active Directory domain controllers. NTDS General event ID 1644 can be filtered to record LDAP searches in the Directory Services event log based on the number of objects in the Active Directory database that were visited, the number of objects that were returned, or the LDAP search execution time on the domain controller. For more information about event ID 1644, see Hotfix 2800945 adds performance data to Active Directory event log.
Event1644Reader.ps1 is a Windows PowerShell script that extracts data from 1644 events that are hosted in saved Directory Service event logs. Then, it imports that data into a series of pivot tables in a Microsoft Excel spreadsheet to help administrators gain insights about the LDAP workloads that are being serviced by the domain controllers and clients that are generating those queries.
How to obtain the script
You can obtain the script from the Core Infrastructure and Security Blog post How to find expensive, inefficient and long running LDAP queries in Active Directory.
Note
The script is attached on the blog post with file name Event1644Reader.zip
Script Center disclaimer
The sample scripts are not supported under any Microsoft standard support program or service. The sample scripts are provided AS IS without warranty of any kind. Microsoft further disclaims all implied warranties including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose. The entire risk arising out of the use or performance of the sample scripts and documentation remains with you. In no event shall Microsoft, its authors, or anyone else involved in the creation, production, or delivery of the scripts be liable for any damages whatsoever (including, without limitation, damages for loss of business profits, business interruption, loss of business information, or other pecuniary loss) arising out of the use of or inability to use the sample scripts or documentation, even if Microsoft has been advised of the possibility of such damages.
Online peer support
For online peer support, join The Official Scripting Guys Forum! To provide feedback or report bugs in sample scripts, start a new discussion on the Discussions tab for this script.
How to use the script
To better analyze the LDAP queries that are captured in event ID 1644, follow these steps:
Make sure that the domain controllers that you are troubleshooting capture enhanced ** 1644 event metadata.
Note
Windows Server 2012 R2 added enhanced 1644 event logging by recording the duration of LDAP queries and other metadata. The enhanced 1644 event logging was backported to Windows Server 2012, Windows Server 2008 R2, and Windows Server 2008 by hotfix 2800945.
Set the value of the following Field Engineering registry entry to 5:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NTDS\Diagnostics\Field Engineering
Note
Setting field engineering log verbosity to 5 will cause other events to be logged in the directory service event log. Reset field engineering back to its default value of 0 when you are not actively collecting 1644 events. (This action does not require a restart.)
If the following registry entries exist, change the values to the desired threshold in milliseconds. If a particular registry entry does not exist, create a new entry with that name, and then set its value to the desired threshold in milliseconds.
Registry path Data type Default value HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NTDS\Parameters\Search Time Threshold (msecs) DWORD 30,000 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NTDS\Parameters\Expensive Search Results Threshold DWORD 10,000 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NTDS\Parameters\Inefficient Search Results Threshold DWORD 1,000 Note
- When the Field Engineering logging level is enabled and the Search Time Threshold (msecs) registry entry is not used or is set to 0, the default value of the time threshold is 30,000 milliseconds. (This action does not require a restart.)
- One strategy would be to set the registry value for both the Inefficient Search Results Threshold and Expensive Search Results Threshold registry settings, and then focus on events that are identified by Search Time hold (msecs). Start with a larger value like 100 milliseconds and then incrementally decrease the value as you optimize the queries that are occurring in your environment.
- Event1644Reader.ps1 can parse events from multiple domain controllers. Configure the field engineering, search time, expensive, and inefficient registry key settings on all domain controllers on which you want to review LDAP searches.
Download the Event1644Reader.ps1 file from You can obtain the script from the Core Infrastructure and Security Blog post How to find expensive, inefficient and long running LDAP queries in Active Directory to the computer that will analyze saved Active Directory Service EVTX files that contain 1644 events.
This computer should have Microsoft Excel 2010 or a later version installed and should have sufficient disk space to host the directory service event logs that the script will parse.
Copy saved Directory Service event logs that contain 1644 events from the domain controllers where you enabled 1644 event logging to the 1644 analysis computer.
In Windows Explorer, right-click the Event1644Reader.ps1 file, and then select Run with PowerShell.
The following is the screenshot for this step:
Press Y to bypass PowerShell Execution Policy as required.
Specify the path of the EVTX files to be parsed.
When you see the prompt as the following screenshot, take the following actions:
- Press Enter to parse all EVTX files that are located in the same directory as the Enent1644Reader.ps1 file.
- Type the
drive:\path
path that contains the EVTX files to be parsed.
Note
Event1644Reader.ps1 parses 1644 events in all up-level directory service event logs that are located in the targeted path every time that the script runs.
Open the worksheet to review data and walk through the series of tabs, and then save the Excel spreadsheet as required. For more information about the tabs in the worksheet, see the Walkthrough of the Excel spreadsheet created by 1644Reder.ps1 section.
Note
*.csv files that are built by the tool are not automatically removed. Consider purging *.csv files after your investigation is complete.
More information
Walkthrough of the Excel spreadsheet that is created by Event1644Reader.ps1
Event1644Reader.ps1 extracts metadata from 1644 events in saved Directory Service event logs and imports that data into a series of tabbed worksheets in a Microsoft Excel spreadsheet.
The following table summarizes the data that is contained in each tab:
Tab | Description |
---|---|
RawData | Each data field that is captured by event ID 1644 is imported into discrete columns. Data Filtering is auto-enabled so that you can sort or filter on any column header. If 1644 event logs from multiple domain controllers resided in the same directory as the PowerShell script or the admin-specified directory, use filters to view LDAP queries that are targeting specific domain controllers. |
Top_StartingNode | Provides a sorted list of the directory partitions that are targeted by LDAP queries in a given sample. If most of the queries are occurring in a single partition (schema, configuration, or domain), consider adding that partition as a filter in the remaining pivot tables. Drillthrough detail exposes the top filters (such as the LDAP query), the client IPs that issued those queries, and the date and time stamps for those queries. |
Top_Callers | Lists client IP addresses that issued LDAP queries in descending search count order with percentage of grand total. Percentage of running total helps you identify top callers. (That is, the top 10 or 20 callers may be generating 80 percent of the query volume, assuming that too many calls are your problem). Drillthrough detail exposes filters and date and time steps that each client-issued LDAP queries in a given sample. |
Top_Filters | Lists most frequently issued LDAP queries in descending volume order. This includes average search time. Drillthrough detail exposes the LDAP client's IP address and the date and time when each query was submitted. |
TotalSearchTime by Callers | Lists client IP addresses in descending order of total search time across all LDAP queries in the sample. Drillthrough detail identifies the LDAP queries and the date and time when each query was issued. |
TotalSearchTime by Filters | Lists LDAP queries in descending order of total search time. Drillthrough detail exposes the LDAP client's IP address and the date and time when each matching query was submitted. |
Search time ranks | Displays the number of LDAP queries that occurred in time-based quartiles. Slower queries are bad. Faster queries are good if they aren't issued too often. Microsoft Exchange wants LDAP queries that are issued by Exchange servers to be resolved in 50 milliseconds or less. So, the first quartile group focuses on that time "bucket." |
Blank Pivot | This is a blank pivot table that you can change as required to show the specific data for your scenario. |
Scenario analysis
If LDAP queries are slow, or if CPU usage is high on domain controllers, this may be caused by excessively issued queries, inefficient queries, some combination of these queries, Asynchronous Thread Queue (ATQ) pool exhaustion, or lots of change notifications.
If clients issue expensive, inefficient, or lots of LDAP queries, use Event1644Reader.ps1 to collect data on the domain controllers to identify the IP addresses of the clients. Then, map such queries to the process ID, the process name, or the calling application on the client computers.
The following table lists the possible optimizations for this issue.
Optimization/mitigation | Synopsis |
---|---|
Stop the excessive workload. | If lots or LDAP queries cause service stops, focus on top calling clients, and work to identify and eliminate the source of the excessive workload. Possible options to identify applications include using PROCMON, ETL/ETW tracing, and debug analysis to identify the application that generates LDAP queries on the client. Another strategy is to use a divide-by-two approach of either topping services or removing applications that are generating LDAP queries. The issued queries may implicate the calling application or process. |
Install an updated LDAP query optimizer. | Windows Server 2012 R2 contains an updated LDAP query optimizer that improves performance for most queries. Subsets of the Windows Server 2012 R2 are backported to Windows Server 2008 R2 and Windows Server 2012 in hotfix 2862304. |
Make sure that clients are submitting queries to site-optimal domain controllers. | Sending LDAP queries across the WAN introduces network latency into the delivery of the LDAP query to the domain controller and its reply to the client. Make sure that Active Directory sites and subnet definitions exist for client and server computers in Active Directory. Make sure that applications do not have hard-coded references to remote-site domain controllers or to read-writable domain controllers only when site-optimal domain controllers exist. |
Work with software developers to reduce the frequency at which queries are issued. This includes the use of caching. | Even efficiently issued queries can beat down an appropriately sized and configured domain controller if queries are issued too often. Applications may have to throttle their query volume or cache query results to reduce network, LDAP, and CPU load. |
Optimize the LDAP query to execute more quickly. | Query syntax may have to be restructured to execute more quickly. Moving query elements to the left or right within the filter can improve performance. Adding a double "not" may improve query performance. Consider reducing the number of objects that are visited by starting queries lower in the tree. Reduce the number of attributes that are being returned by queries. |
Add indexes to Active Directory attributes as required. | Adding indexes can improve query performance. This has the side effect of increasing database size and may temporarily delay Active Directory replication during index build. |
Determine whether a code defect exists in the query optimizer and other components. | Defects in the LDAP query optimizer and other components can reduce throughput. |
Known issue
The values in the Excel spreadsheet are not displayed or rendered appropriately on computers that use non-English languages.
For example, this occurs on a computer when the Get-Culture Windows PowerShell cmdlet indicates the regional setting as follows:
PS C:\Windows\System32\WindowsPowerShell\v1.0> Get-Culture
LCID Name DisplayName
---- ---- -----------
1031 de-DE German (Germany)
PS C:\Windows\System32\WindowsPowerShell\v1.0> Get-UICulture
LCID Name DisplayName
---- ---- -----------
1033 en-US English (United States)
In this situation, numbers in the Excel spreadsheet are rendered as in the following screenshot:
To resolve this issue, change the Decimal symbol to a period (.) in the Region settings item in Control Panel.
For more information about LDAP queries, see the following blog: How to find expensive, inefficient, and long running LDAP queries in Active Directory