Solved

How can I make my Active Directory Queries faster?

Posted on 2004-08-14
4
419 Views
Last Modified: 2008-01-09
Pretty self explanatory, but there is alot of code here because its my first time picking up VB.NET Active Directory functions... Basically I have the same kind of code base that was done in PERL and it runs about 10 times faster, so want to see what I am doing wrong in .NET.  Basically, here is what all this code below is doing step by step:

1.  Taking a manually entered computer object (example: adnrfk000342) and querying it for its 'members of'.
2.  Then it takes those 'members of' and goes down into those 'members of'... basically until it has all the members all the way down to where there is no more, and it dumps them into an array,
3.  Then it takes that members array and then queries to look at a schema extended attribute called 'edmpolicy' which can contain multiple values.  All values either start with a + or - which it takes and puts in a positive or negative listbox (basically splits them up).
4.  Then it compares that + and - values and removes them if there is a negative value that matches the + (for example: if there was +test and -test, it would remove the -test and put the +test into a 3rd listbox).
5.  It does this until its gone through every 'members of' and pulled every 'edmpolicy' value...

A little involved, but hopefully someone can see something that is causing delays..... biggest thing I would like answers on is the LDAP / AD query functions...can any of them be changed to make it faster?

Any help is appreciated....



Private Sub Execute_PolicyCheck_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Execute_PolicyCheck.Click
        '''''''''''''Execute Active Directory Tab - Policy Check ''''''''''''''

        Plus_Policy_Listbox.Items.Clear()
        Neg_Policy_Listbox.Items.Clear()
        Software_Catalog_Listbox.Items.Clear()

        Policy_Infinite_Progress_PB.Enabled = True
        Policy_Infinite_Progress_PB.Show()
        AD_Policy_Progress_Label.Text = "Policy Check In Progress...."

        AD_Policy_Tab.PerformClick()

        '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
        AD_Host_Combobox.Items.Add(AD_Host_Combobox.Text)

        varX = varX + 1

        If varX = 10 Then
            AD_Host_Combobox.Items.RemoveAt(0)
            varX = varX - 1
        End If

        Soft_Cat_CurrentHost.Text = UCase(AD_Host_Combobox.Text)

        ''''''''''''''''''''''''''''''''''''''''''''
        On Error Resume Next
        ''''''''''''''''''''''''''''''''''''''''''''
        AD_Computer_Button.Checked = True

        Dim PolicyCheck_Thread As New ThreadStart(AddressOf Me.ADTab_Policy_Check)
        Dim PolicyCheck_Instance As New Thread(PolicyCheck_Thread)

        PolicyCheck_Instance.Start()

    End Sub

    Public Sub ADTab_Policy_Check()
        ''''''''''''''''''' Thread  - Execute Software Delivery Tab - Policy Check ''''''''''''''
        On Error Resume Next

        Dim StrObject As String = AD_Host_Combobox.Text
        If StrObject = "" Then
            Exit Sub
        End If

        Dim trustRes As String = AD_DomainList_Combobox.Text
        OC = "computer"

        If AD_DomainList_Combobox.Text = "" Then
            MsgBox("Please Enter a Valid LDAP Distinguished Path to Query.", MsgBoxStyle.Exclamation, "ESDC-Exception")
            Exit Sub
        End If

        Dim entry As New DirectoryEntry("LDAP://" & trustRes & "")
        Dim mySearcher As New DirectorySearcher(entry)
        mySearcher.Filter = "(&(objectClass=" & OC & ")(|(cn=" & StrObject & ")(dn=" & StrObject & ")))"

        Dim ResEnt As SearchResultCollection = mySearcher.FindAll()
        Dim resEnt1 As SearchResult

        For Each resEnt1 In ResEnt ' Start Loop 1 '

            Dim MemberOf As String
            Dim valcol As ResultPropertyValueCollection = resEnt1.Properties("MemberOf")

            For Each Mem In valcol ' Start Loop 2 '
                Member_Array.Add(Mem)
                Deeper()
            Next Mem ' Stop Loop 2 '

        Next resEnt1 ' Stop Loop 1 '

        '''''''''''''Call EDMPolicy'''''''''''
        EdmPolicy()

    End Sub

    Public Sub Deeper()
        '''''''''''''''''''''''Dig Subroutine to get all Members of out of the host '''''''''''''''''''''
        On Error Resume Next

        Dim ent As New DirectoryEntry("LDAP://" & DC_Selection_Combobox.Text & "/" & Mem & "")
        For Each Mem In ent.Properties("MemberOf") ' Start Loop '
            Member_Array.Add(Mem)

            If Mem <> Nothing Then
                Deeper()
            End If
        Next Mem  ' Stop Loop '
        ent = Nothing
    End Sub

    Sub EdmPolicy()
        ''''''''''''''   EDM Policy Resolution Subroutine (AD Tab)   ''''''''''''''

        On Error Resume Next

        Dim CaM
        Dim pstrFields()

        For Each CaM In Member_Array

            Dim StrObject As String = CaM
            Dim Delimiter() As Char = {System.Convert.ToChar(",")}
            pstrFields = StrObject.Split(Delimiter)

            '''''Removes the CN= from the entry''''''
            StrObject = pstrFields.GetValue(0)
            StrObject = StrObject.Remove(0, 3)

            'Plus_Policy_Listbox.Items.Add(StrObject)

            If StrObject = "" Then
                MsgBox("Please Enter a Valid Common Name (CN).  Current Entry value is Null.  Exiting Policy Check Routine.")
                Exit Sub
            End If

            Dim trustRes As String = AD_DomainList_Combobox.Text
            If AD_DomainList_Combobox.Text = "" Then
                MsgBox("Please Enter a Valid LDAP Distinguished Path to Query.", MsgBoxStyle.Exclamation, "ESDC-Exception")
                Exit Sub
            End If
            Dim entry As New DirectoryEntry("LDAP://" & trustRes & "")
            Dim mySearcher As New DirectorySearcher(entry)

            mySearcher.Filter = "(&(objectClass=group)(cn=" & StrObject & "))"

            Dim ResEnt As SearchResultCollection = mySearcher.FindAll()
            Dim resEnt1 As SearchResult

            For Each resEnt1 In ResEnt
                Dim valcol2 As ResultPropertyValueCollection = resEnt1.Properties("edmPolicy")
                Dim Mem2 As String
                For Each Mem2 In valcol2
                    'If Mem2 <> Nothing Then
                    ''''''''''''Split out Negative Policy and Positive Policy and 'Add' values to Listboxes'''''''''''''''
                    If InStr(Mem2, "-") > 0 Or InStr(Mem2, "--") > 0 Then
                        'Policy_Array.Add(Mem2)
                        Neg_Policy_Listbox.Items.Add(Mem2)
                    Else
                        Plus_Policy_Listbox.Items.Add(Mem2)
                    End If
                    Mem2 = Nothing
                    ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
                    ' End If
                Next Mem2
            Next resEnt1

            '''''''''''''''Dispose all Query/Filters'''''''''''''''
            entry.Close()
            mySearcher.Dispose()
            ResEnt.Dispose()

        Next

        Determine_Catalog()
    End Sub


    Public Sub Determine_Catalog()
        Dim L As New Hashtable()
        Dim Cat_entry As String
        Dim Cat_value As String
        Dim Soft_Cat_Array As ArrayList
        Dim Soft_Cat_Instance

        Software_Catalog_Listbox.Items.Clear()

        ' Add all the negative values to our hashtable as keys
        For Each Cat_entry In Neg_Policy_Listbox.Items
            Cat_value = Cat_entry.Replace("-", "")
            Try
                L.Add(Cat_value, Nothing)
            Catch ex As Exception
            End Try
        Next

        ' Iterate thru all the positive values, if no corresponding negative key in the hashtable
        ' add it to ListBox3
        For Each Cat_entry In Plus_Policy_Listbox.Items
            Cat_value = Cat_entry.Replace("+", "")
            If Not L.ContainsKey(Cat_value) Then
                Software_Catalog_Listbox.Items.Add(Cat_value)
            End If
        Next

        L = Nothing

        Policy_Infinite_Progress_PB.Enabled = False
        Policy_Infinite_Progress_PB.Hide()
        AD_Policy_Progress_Label.Text = "Policy Check Completed"
    End Sub
0
Comment
Question by:phesser
  • 2
  • 2
4 Comments
 
LVL 96

Expert Comment

by:Bob Learned
ID: 11812930
Where is the critical section that takes the most time?

Bob
0
 

Author Comment

by:phesser
ID: 11813098

The 2nd Sub and 3rd [Public Sub ADTab_Policy_Check() and Deeper()] takes alot of time (but not the most).  Usually the 3rd sub [Sub EdmPolicy()] takes the longest as I think it probably takes alot of time to look through all the attributes to find the NVDUSER attribute... and in a large number of cases there may not be any value on those entries... some may have multiple values...

Effecitively just want to clean up my queries in case some of them are timing out, looking through data that doesnt need to be found, etc...

Thanks for the help.
0
 
LVL 96

Accepted Solution

by:
Bob Learned earned 500 total points
ID: 11814811
I have VB.NET 2003, so you can dimension a variable within the For Each definition.

It's tough to see any other way to improve the speed of EdmPolicy.  I would time how long it takes to do something like this, by itself:

 Dim entry As New DirectoryEntry("LDAP://" & trustRes & "")
 Dim mySearcher As New DirectorySearcher(entry)

 mySearcher.Filter = "(&(objectClass=group)(cn=" & StrObject & "))"

 For Each resEnt1  As SearchResult In mySearcher.FindAll()

    For Each Mem2 As String In resEnt1.Properties("edmPolicy")

    Next Mem2

Next resEnt1

I don't think that you can get it to work much faster than that.

Bob
0
 

Author Comment

by:phesser
ID: 11815094
Thanks I will try to simple timing and try to figure out if it is network performance, or if i can squeeze some more efficiency out of the code...

Before I accept the answer, let me wait and see if any other people chime in, thanks
0

Featured Post

Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

This tutorial demonstrates one way to create an application that runs without any Forms but still has a GUI presence via an Icon in the System Tray. The magic lies in Inheriting from the ApplicationContext Class and passing that to Application.Ru…
Introduction As chip makers focus on adding processor cores over increasing clock speed, developers need to utilize the features of modern CPUs.  One of the ways we can do this is by implementing parallel algorithms in our software.   One recent…
This video shows how to remove a single email address from the Outlook 2010 Auto Suggestion memory. NOTE: For Outlook 2016 and 2013 perform the exact same steps. Open a new email: Click the New email button in Outlook. Start typing the address: …
This tutorial demonstrates a quick way of adding group price to multiple Magento products.

706 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now