PowerShell LDAP response time monitor

I recently had some issues with a system not getting very response times to LDAP queries sent to various Active Directory domain controllers.

These were resolved via a combination of Windows Server 2003 Server Performance Advisor and the built in, better, equivalent in 2008 R2 (found via Performance Monitor/Server Manager – Diagnostics – Performance – Data Collector Sets – System – Active Directory Diagnostics). It turned out that a new system was running an expensive full directory tree query against a non-indexed attribute and this was using all the CPU. I have now got the attribute indexed, the query optimised to only look in certain OUs, and given the DC VM an extra CPU.

Anyway, in order to try and notice this kind of thing in the future I have written a script that tests all my DCs by running a simple (if non-optimal) query every ten seconds, and log the results to a CSV file for easy graphing/analysis in Excel. It also sends me an email if any of the DCs take longer than a specified number of milliseconds to return the results of the query. And it rolls the log file over when it reaches a specified size. The script can be run on multiple machines simultaneously so that you can test response times form different parts of your network and/or different PCs/servers. Create the log file folder before running the script for the first time.

Script is as follows:

# Specify DCs manually, or get all of them automatically
#$DCs = "dc03","dc04","dc05","dc06","dc07","dc08"
$DCs = (Get-ADDomainController -Filter *).Name
$LDAPUserToQuery = "tstd68"
$Logfile = "C:\Logs\LDAPTimes.csv"
$LogRollSize = 1024000 # size is in bytes
$SMTPServer = "smtp.rcmtech.co.uk"
$MailTo = "my.user@rcmtech.co.uk"

function Test-LDAPQuery($User,$DC){
    # assume that the DC is in the same domain as the user running the test
    $Root = [ADSI] ("LDAP://"+$DC+"."+$env:USERDNSDOMAIN)
	$Searcher = New-Object System.DirectoryServices.DirectorySearcher $Root
	$Searcher.Filter = "(cn=$User)"
    # run the query and time how long it takes in milliseconds
	$Milliseconds = (Measure-Command {$Container = $Searcher.FindAll()}).TotalMilliseconds
    # this script doesn't do anything with the results of the query
    return $Milliseconds
}

while($true){
    $ThisResult = New-Object System.Object
    $ThisResult | Add-Member -Type Noteproperty -Name DateTime -Value (Get-Date -Format G)
    foreach($DC in $DCs){
        $Milliseconds = Test-LDAPQuery -User $LDAPUserToQuery -DC $DC
        if($Milliseconds -gt 600){
            Send-MailMessage -From ("LDAPPerfTest@"+$env:COMPUTERNAME+"."+$env:USERDNSDOMAIN) -Subject ($DC+" took "+$Milliseconds+"ms") -Body "The log file can be found at $Logfile on the machine that sent this email" -To $MailTo -SmtpServer $SMTPServer
        }
        $ThisResult | Add-Member -Type Noteproperty -Name $DC -Value $Milliseconds
    }
    $ThisResult
    $ThisResult | Export-Csv -Path $Logfile -Append -NoTypeInformation
    $Log = Get-ChildItem -Path $Logfile
    if($Log.Length -ge $LogRollSize){
        Rename-Item -Path $Logfile -NewName ($Logfile.Replace($Log.Extension,"")+"_"+(Get-Date -Format s).Replace(":","-")+$Log.Extension)
    }
    Write-Host "Waiting..."
    Start-Sleep -Seconds 10
}
This entry was posted in Performance, PowerShell, Windows and tagged , , , , , , , , , , , , , . Bookmark the permalink.

One Response to PowerShell LDAP response time monitor

  1. rikkard says:

    thank you, works great!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s