Further Testing with S.DS.P (~1 sec slower)
I have to say I am in awe. I never expected to get so close to ADFind.exe in performance, but if you look below you will notice how close s.ds.p really got.
Before I show the results I want to respond to some of joe’s comments on his blog entry here: PowerShell + S.DS.Protocols Versus AdFind…
btw… I STRONGLY recommend reading this entry… actually subscribing to his blog. While he does spout off random quotes… he provides some incredibly useful info from time to time.
note: References to joe as joe (case intentional) is not ment as disrespect, but simply the way joe refers to himself. If you have the pleasure of getting to know him… you will understand this.
[1] I understand fully that joe really wants .NET and Powershell to succeed, but finds it unlikely.
[2] My testing (although possibly not perfect) was much more precise and I assume his testing had to be skewed by something. Its just not possible. I tried this on 4 completely different systems. Different OS’s, x64 and x86, Hyper-v and ESX, and different domain sizes. By the end of the testing.. I ran approximately 600 test (although I only documented 240.)
[3] While I can appreciate his lack of faith in measure-command. It was the only way I could remove human error and maintain an unbiased count for each test. Measure-command’s overhead is maintained completely outside of the measured expression.
[4] MOST IMPORTANTLY: Perhaps the reason joe questions my purpose of doing these tests is because I did not make it clear. My purpose in these test was to determine if it is feasible to reach the same performance of adfind.exe in Powershell. Why? adfind.exe works great, why not just that. Simply put, if I can achieve close to the same performance, I’m able to get the speed while maintaining the benefit of dealing with objects. While this concept may escape people, once you grasp it… it is key to easy and fast scripts or commands. Nothing more, nothing less. While I will not argue I like a good debate, that is not my soul reason for being.
To be clear, this is only the first step. I now need to process some properties and see if s.ds.p/powershell can compete in that area. As I was with the count I am skeptical about achieving performance even close to adfind, but perhaps that will surprise me as the search did.
[5] My count was NOT off
The logic of using userclass=* vs userclass=user was.
For those inclined to do so… Here is the COMPLETE output of the results without the average
Prod700kResults
Results Prod 400k VM
Small 200k Domain on Local Hardware
Small 200k Domain on VM
This first test was done in a LARGE environment with 700k+ userclass objects.

This test was done on a production quality VM with approx 400k users.

This test was on my Home Win2k8 DC. I only have about 200k userclass objects at home, but it is a beefy box.

This is on my laptop that has about 200k userclass objects as well.

Here are the scripts I ran for the testing
This is the actual worker code
-
-
$domainDN = ([ADSI]"").distinguishedName
-
$domain = $domainDN -replace ",","." -replace "dc=",""
-
-
-
$filter = "(objectclass=*)"
-
-
$searchRequest = New-Object System.DirectoryServices.Protocols.SearchRequest($DomainDN,$filter,$subtree,"1.1")
-
$searchRequest.Controls.add($pagedRequest) | out-null
-
$searchRequest.Controls.Add($searchOptions) | out-null
-
-
while ($True)
-
{
-
# Increment the pageCount by 1
-
$pageCount++
-
-
# Cast the directory response into a SearchResponse object
-
$searchResponse = $connection.SendRequest($searchRequest)
-
-
# Display the retrieved page number and the number of directory entries in the retrieved page
-
# "Page:{0} Contains {1} response entries" -f $pageCount,$searchResponse.entries.count
-
$count += ($searchResponse.entries).count
-
-
# Display the entries within this page
-
$searchResponse.Entries | select distinguishedName
-
# if this is true, there are no more pages to request
-
if ($searchResponse.Controls[0].Cookie.Length -eq 0){write-Output $count;break}
-
-
# Set the cookie of the pageRequest equal to the cookie of the pageResponse to request the next
-
# page of data in the send request and cast the directory control into a PageResultResponseControl object
-
$pagedRequest.Cookie = $searchResponse.Controls[0].Cookie
-
}
Script I used to automate the 60 test per Environment.
-
Param($count=30)
-
-
$dn = ([ADSI]"").distinguishedName
-
-
function TestOne {
-
Write-Host " + Test ${i}.1"
-
Write-Host " + Running ADFind Test"
-
$joeTime = Measure-Command { D:\Scripts\adfind -b "$dn" -c -f "(objectclass=user)" 2>&1 | out-Null }
-
Write-Host " - $($joetime.TotalSeconds)"
-
Write-Host " + Running DSP Test"
-
$DSPTime11 = Measure-command { D:\Scripts\Test-DSProtocalsSP.ps1 }
-
Write-Host " - $($DSPTime11.TotalSeconds)"
-
$myresults = "" | select @{n="ADFind" ;e={$joeTime.TotalSeconds}},
-
@{n="DSP Using 1.1" ;e={$DSPTime11.TotalSeconds}}
-
$myresults
-
}
-
function TestTwo {
-
Write-Host " + Test ${i}.2"
-
Write-Host " + Running DSP Test"
-
$DSPTime11 = Measure-command { D:\Scripts\Test-DSProtocalsSP.ps1 }
-
Write-Host " - $($DSPTime11.TotalSeconds)"
-
Write-Host " + Running ADFind Test"
-
$joeTime = Measure-Command { D:\Scripts\adfind -b "$dn" -c -f "(objectclass=user)" 2>&1 | out-Null }
-
Write-Host " - $($joetime.TotalSeconds)"
-
$myresults = "" | select @{n="ADFind" ;e={$joeTime.TotalSeconds}},
-
@{n="DSP Using 1.1" ;e={$DSPTime11.TotalSeconds}}
-
$myresults
-
}
-
-
Write-Host
-
for($i = 0 ; $i -le $count ; $i++)
-
{
-
Write-Host "+ Test $i"
-
TestOne
-
TestTwo
-
}
-
Write-Host
tshell :: Jun.09.2008 :: All :: 3 Comments »

