Directory Programming .NET

Active Directory and ADAM programming support for .NET developers
Welcome to Directory Programming .NET Sign in | Join | Help
in Search

"The server is not operational" Error -2147016646

Last post 04-22-2008, 6:17 PM by dunnry. 4 replies.
Sort Posts: Previous Next
  •  04-21-2008, 5:10 PM 3258

    "The server is not operational" Error -2147016646

    Hello,

    I was requested to create an ASP.NET 2.0 web page which looks up a particular group on a production server and returns the list of users.  First I thought I'd design the web page to look up a group on AD called Team-DS and return its users.

    No worries there, everything works fine and I get my list of users.  However when I change the server name in the LDAP connection string and the group name I want to look up I get the error "The server is not operational" with an error code of -2147016646. 

    I'm not 100% what I want to do is possible, I mean I can query AD and see users in a group well enough but can I query the AD users in a group on another machine which is connected to AD?  Below is the code I'm using and before you ask I've just started out in ASP.NET so this might not conform to all the recommended standards.

    Essentially the code below does the following...


    1.  Sets up a data table control and adds some columns to it.

    2.  Creates a new directory entry looking at the server on the AD domain which has the local group I want.

    3.  Creates a new directory searcher which specifies I want to return a group called DS_AS_Measures.

    4.  Starts looping through the groups found (this originally returned many groups but I've restricted it to one group) and gets the name of the members in the group.

    5.  Creates a new directory entry looking at all of the AD users in the Staff Accounts OU.

    6.  Creates a new directory searcher on that directory entry where the name of the member is the same as the name of the AD user.  This is so I can get the AD values for that user, i.e. display name and department.

    7.  Inserts values to the new row in my data table.

    8.  Creates a new data view based off the data table and sorts it by the user name column.

    9.  Returns the results.


    Again this works when I query any group in our AD domain but for some reason it can't see this server that I want the local group members from.


    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

          GridView1.DataSource = GetDSASMeasuresUsers()
          GridView1.DataBind()

    End Sub

    Public Function GetDSASMeasuresUsers() As DataView

          Dim objGroupEntry As DirectoryEntry
          Dim userName As String
          Dim table As New DataTable
          Dim column As DataColumn
          Dim row As DataRow

          column = New DataColumn
          column.DataType = System.Type.GetType("System.String")
          column.ColumnName = "User Name"
          table.Columns.Add(column)

          column = New DataColumn
          column.DataType = System.Type.GetType("System.String")
          column.ColumnName = "Display Name"
          table.Columns.Add(column)

          column = New DataColumn
          column.DataType = System.Type.GetType("System.String")
          column.ColumnName = "Department"
          table.Columns.Add(column)

          Dim entry_primary As DirectoryEntry = New DirectoryEntry("LDAP://MSCHCDWP1.cdhb.local/DC=cdhb,DC=local")
          entry_primary.Username = "CN=CDHB\<my user name>"
          entry_primary.Password = "<my password>"
          entry_primary.AuthenticationType = AuthenticationTypes.Secure
          entry_primary.RefreshCache()

          Dim mySearcher_Primary As DirectorySearcher = New DirectorySearcher(entry_primary)
          mySearcher_Primary.Filter = "(&(objectClass=group)(Name=DS_AS_Measures))"
          mySearcher_Primary.SearchScope = SearchScope.Subtree
          Dim mySearcher_Primary_Search_Results As SearchResultCollection = mySearcher_Primary.FindAll()

          Try

             If mySearcher_Primary_Search_Results.Count <> 0 Then
             Dim objResult As SearchResult
             For Each objResult In mySearcher_Primary_Search_Results

                objGroupEntry = objResult.GetDirectoryEntry()
                Dim objMember As Object
                For Each objMember In objGroupEntry.Properties("member")

                   userName = Replace(Left(objMember.ToString(), InStr(objMember.ToString(), ",") - 1), "CN=", "")
                   Dim entry As DirectoryEntry = New DirectoryEntry("LDAP://MSPMHDCP01.cdhb.local/OU=Staff Accounts,DC=cdhb,DC=local")
                   entry.Username = "CN=CDHB\<my user name>"
                   entry.Password = "<my password>"
                   entry.AuthenticationType = AuthenticationTypes.Secure
                   entry.RefreshCache()

                   Dim mySearcher As DirectorySearcher = New DirectorySearcher(entry)
                   mySearcher.Filter = "(&(objectCategory=person)(name=" + userName + "))"
                   row = table.NewRow

                   For Each resEnt As SearchResult In mySearcher.FindAll()

                   Try

                      Dim de As DirectoryEntry = resEnt.GetDirectoryEntry()
                      row("User Name") = de.Properties("sAMAccountName").Value.ToString()
                      row("Display Name") = de.Properties("DisplayName").Value.ToString()
                      row("Department") = de.Properties("department").Value.ToString()

                   Catch ex As Exception
                   End Try

                Next

                table.Rows.Add(row)

                mySearcher.Dispose()
                entry.Dispose()
                entry.Close()

             Next objMember
             Next objResult

          End If
          Catch ex As Exception

       End Try

       mySearcher_Primary.Dispose()
       entry_primary.Dispose()
       entry_primary.Close()

       Dim DataView As New DataView(table)
       DataView.Sort = "User Name"

       Return DataView

    End Function

    Kind regards,

    Chris

  •  04-21-2008, 8:56 PM 3262 in reply to 3258

    Re: "The server is not operational" Error -2147016646

    Hi there,

    I've gone through this and found the solution and posted the code below just in case anyone else had this issue.  Again I'm a notive ASP.NET developer and I know next to nothing about AD however this worked for me.

    Essentially I didn't know about the WinNT DirectoryEntry call.  So I'm using that to connect to the server that has the local group I want members from.  Then with that list of members I'm linking that to the AD domain user list to get details like display name and department.

    Code below.

    Cheers,

    Chris

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

     

         GridView1.DataSource = ListUsersOnPROD_DS_AS_Measures()

         GridView1.DataBind()

     

    End Sub

     

        Public Function ListUsersOnPROD_DS_AS_Measures() As DataView

     

            Dim table As New DataTable

            Dim column As DataColumn

            Dim row As DataRow

     

            column = New DataColumn

            column.DataType = System.Type.GetType("System.String")

            column.ColumnName = "User Name"

            table.Columns.Add(column)

     

            column = New DataColumn

            column.DataType = System.Type.GetType("System.String")

            column.ColumnName = "Display Name"

            table.Columns.Add(column)

     

            column = New DataColumn

            column.DataType = System.Type.GetType("System.String")

            column.ColumnName = "Department"

            table.Columns.Add(column)

     

            Dim localGroup As DirectoryEntry = New DirectoryEntry("WinNT://MSCHCDWP1/DS_AS_Measures, group")

            localGroup.Username = "CDHB\<user name>"

            localGroup.Password = "<password>"

            localGroup.AuthenticationType = AuthenticationTypes.Secure

            Dim allMembers As Object = localGroup.Invoke("Members")

     

            For Each groupMember As Object In DirectCast(allMembers, IEnumerable)

     

                Dim memberEntry As New DirectoryEntry(groupMember)

     

                Dim entry As DirectoryEntry = New DirectoryEntry("LDAP://MSPMHDCP01.cdhb.local/OU=Staff Accounts,DC=cdhb,DC=local")

                entry.Username = "CN=CDHB\<user name>"

                entry.Password = "<password>"

                entry.AuthenticationType = AuthenticationTypes.Secure

                entry.RefreshCache()

     

                Dim mySearcher As DirectorySearcher = New DirectorySearcher(entry)

                mySearcher.Filter = "(&(objectCategory=person)(sAMAccountName=" + memberEntry.Name + "))"

     

                row = table.NewRow

     

                For Each resEnt As SearchResult In mySearcher.FindAll()

                    Try

                        Dim de As DirectoryEntry = resEnt.GetDirectoryEntry()

                        row("User Name") = de.Properties("sAMAccountName").Value.ToString()

                        row("Display Name") = de.Properties("DisplayName").Value.ToString()

                        row("Department") = de.Properties("department").Value.ToString()

                    Catch ex As Exception

                    End Try

     

                Next

     

                table.Rows.Add(row)

     

                mySearcher.Dispose()

                entry.Dispose()

                entry.Close()

     

            Next

     

            localGroup.Dispose()

            localGroup.Close()

     

            Dim DataView As New DataView(table)

            DataView.Sort = "User Name"

     

            Return DataView

     

        End Function

  •  04-21-2008, 10:33 PM 3266 in reply to 3262

    Re: "The server is not operational" Error -2147016646

    I'm glad you figured that out as I wasn't clear on what you meant by a local group.  You might consider using the new S.DS.AccountManagement namespace in .NET 3.5 as it makes this group lookup and enumeration stuff easier and makes the code the same between local and AD.

    Also, don't call GetDirectoryEntry to read the attributes on the group.  That kills your perf.  Read the values from the SearchResult.Properties.  The data is already in memory.  Calling GetDirectoryEntry causes more lookups to the server to be done.

  •  04-22-2008, 6:03 PM 3292 in reply to 3266

    Re: "The server is not operational" Error -2147016646

    Hi Joe,

    Thanks for the reply.  I'm not sure I totally understand your meaning or in my case how to make it work.  I understand you say that the following line is bad for performance when I search the members of the group on the server...

    Dim memberEntry As New DirectoryEntry(groupMember)

    When I type in "SearchResult." the options I have are only Equals or ReferenceEquals so I'm not sure how to make what you advise to work. 

    Also thanks for the suggestion of ASP.NET 3.0 or 3.5.  I understand that our web servers are only configured for the .Net framework 2.0 with no plans to change this on the horizon so this will have to be something I keep in the back of my mind for when they do upgrade.

    Kind regards,

    Chris

  •  04-22-2008, 6:17 PM 3294 in reply to 3292

    Re: "The server is not operational" Error -2147016646

    If you have the SearchResult, you will notice it has a Properties collection that looks just like the DirectoryEntry Properties collection.  You use it the same way:

    SearchResult sr = ds.FindOne();

    if (sr != null)
    {
        if (sr.Properties.Contains("sn"))
        {
           string lastname = sr.Properties["sn"][0].ToString();
        }
    }

    Ryan Dunn
    Extemporaneous Mumblings
    The .NET Developer's Guide to Directory Services Programming
View as RSS news feed in XML