System.DirectoryServices - Retrieving Manager's email and stripping path information

Hi experts,

I am designing a web-based ASP.NET 2.0 (VB.NET) holiday request form for the office which grabs the current logged on user's username and searches Active Directory for this user, then echoes specific information into text labels where I require them. This almost all works well, but I have hit a snag.

As you can see in the snippet, I call a function called GetUserInfo, and then use the results in text labels (at the bottom).

But the text label "lblManager" displays not just the user's manager's name, but the whole path to it (i.e: CN=John Smith,OU=MYOU,DC=MYDOMAIN,DC=co,DC=uk).

How can I do the following:

1. Remove all the path information so only "John Smith" is displayed.
2. Retrieve said manager's email address.

Thanks

Jon
Public Function GetUserInfo(ByVal inSAM As String, ByVal inType As String) As String
        Try
 
            Dim sPath As String = "LDAP://MYDOMAIN.co.uk/OU=Staff,DC=MYDOMAIN,DC=co,DC=uk"
            Dim SamAccount As String = Right(inSAM, Len(inSAM) - InStr(inSAM, "\"))
            Dim myDirectory As New DirectoryEntry(sPath, "MYACC", "MYPASS")
            Dim mySearcher As New DirectorySearcher(myDirectory)
            Dim mySearchResultColl As SearchResultCollection
            Dim mySearchResult As SearchResult
            Dim myResultPropColl As ResultPropertyCollection
            Dim myResultPropValueColl As ResultPropertyValueCollection
 
            mySearcher.Filter = ("(&(objectClass=user)(samaccountname=" & SamAccount & "))")
            mySearchResultColl = mySearcher.FindAll()
 
            Select Case mySearchResultColl.Count
                Case 0
                    Return "Null"
                    Exit Function
                Case Is > 1
                    Return "Null"
                    Exit Function
            End Select
 
            mySearchResult = mySearchResultColl.Item(0)
            myResultPropColl = mySearchResult.Properties
            myResultPropValueColl = myResultPropColl.Item(inType)
            Return CStr(myResultPropValueColl.Item(0))
 
        Catch ex As System.Exception
            pnlNonUser.Visible = True
            pnldisplay.Visible = False
            pnlsubmitted.Visible = False
        End Try
    End Function
 
Dim sManager As String = GetUserInfo(UserId, "manager")
lblManager.Text = sManager

Open in new window

LVL 11
Jon WinterburnAsked:
Who is Participating?
 
Chris DentConnect With a Mentor PowerShell DeveloperCommented:

Hi Jon,

Because of requirement 2 you probably want to create a DirectoryEntry for the manager to pull the name and mail attributes.

e.g.

Dim sManager As String = GetUserInfo(UserId, "manager")
Dim oManager As New DirectoryEntry("LDAP://" & sManager, "MYACC", "MYPASS")
lblManager.Text = oManager.Properties("name").Value.ToString()
lblManagerMail.Text = oManager.Properties("mail").Value.ToString()

That will be very inefficient if you have to do it for a large number of managers at the same time, but for a one-off it should work well.

Chris
0
 
Jon WinterburnAuthor Commented:
Thanks - that makes sense. However, when I add that to my code, although it builds fine, I get an error on the page "Unknown error (0x80005000)", and it refers to the line:

lblManager1.Text = oManager.Properties("name").Value.ToString()
0
 
Chris DentPowerShell DeveloperCommented:

Hmm Null, didn't expect that for "name" since it's a mandatory field. Can you have it echo out the value for sManager so we can check it's going to be able to connect?

Chris
0
Problems using Powershell and Active Directory?

Managing Active Directory does not always have to be complicated.  If you are spending more time trying instead of doing, then it's time to look at something else. For nearly 20 years, AD admins around the world have used one tool for day-to-day AD management: Hyena. Discover why

 
Jon WinterburnAuthor Commented:
Echoing sManager results in:

CN=John Smith,OU=MYOU,DC=MYDOMAIN,DC=co,DC=uk

...which is the other issue I'm having - how to strip out the unnecessary stuff.
0
 
Chris DentPowerShell DeveloperCommented:

That's why we were requesting "Name" from the attribute set. It would just be "John Smith". It is, of course, possible to parse the string for that, but since you needed mail as well it was cleaner to retrieve both from the directory.

Ignoring "name" for a moment, does "mail" return the same error message when requested?

Chris
0
 
Jon WinterburnAuthor Commented:
Indeed it does.
0
 
Chris DentPowerShell DeveloperCommented:

Okay, so our connection isn't working. I think I see why.

It's likely to be because I didn't include the domain name in the string, which suggests it cannot find the servers.

Could you try this version? Just added on the "mydomain.co.uk" so it can hopefully find the LDAP servers. Once it has that successfully it should be able to return the two attributes we're requesting.

Chris
Dim sManager As String = GetUserInfo(UserId, "manager")
Dim oManager As New DirectoryEntry("LDAP://MYDOMAIN.CO.UK/" & sManager, "MYACC", "MYPASS")
lblManager.Text = oManager.Properties("name").Value.ToString()
lblManagerMail.Text = oManager.Properties("mail").Value.ToString()

Open in new window

0
 
Jon WinterburnAuthor Commented:
I'm afraid I already thought of that and had amended the ldap string to match that of my domain, but still no joy.
0
 
Chris DentPowerShell DeveloperCommented:

Well that's annoying, it works fine for me (of course) :)

There are possibilities that we should consider. If the string sManager has any reserved characters in it we can get unexpected behaviour when trying to connect to the account with a Directory Entry.

Here's my sample code, just runs as a console application (just in case).

Chris
Dim oUser As New DirectoryEntry("CN=test,CN=Users,DC=domain,DC=net")
Dim sManager As String = domainUser.Properties("manager").Value.ToString()
 
Dim oManager As New DirectoryEntry("LDAP://" & sManager)
Console.WriteLine(oManager.Properties("name").Value.ToString())
Console.WriteLine(oManager.Properties("mail").Value.ToString())

Open in new window

0
 
Jon WinterburnAuthor Commented:
Okay, I gave up on that direction and read a VB.NET forum article and used their example. It works perfectly, and gives me the manager name and email as expected.

But...if I visit the page from another computer in the domain, as any logged on user (admin or not) - none of the fields show up!

So I copied the files to the Intranet server (Windows Server 2003) and accessed it locally, and all fields show up fine - but if I visit it from my workstation, all fields except the manager and manager email fields show up. Why is this??? I have posted the code, if you could take a look please.

(yes, integrated Windows auth is switched on in IIS and web.config)
'first I set the user as logged on user:
Dim User As System.Security.Principal.IPrincipal
User = System.Web.HttpContext.Current.User
 
'this function I use to remove the domain part of the logged on username:
Private Shared Function StripDomain(ByVal username As String) As String
        Return username.Remove(0, username.IndexOf("\") + 1)
    End Function
 
'this function I use to get the user's info from AD:
Private Function GetUserInfo(ByVal Results As System.DirectoryServices.SearchResult, ByVal PropName As String) As String
        Try
            If Results.Properties(PropName).Count > 0 Then
                Return Results.Properties(PropName)(0).ToString.Trim
            End If
        Catch
            Return String.Empty
        End Try
    End Function
 
'and this is the sub that calls the above functions:
   Public Sub getADuser()
        Try
            Dim entry As New DirectoryEntry("LDAP://mydomain.co.uk/DC=mydom,DC=co,DC=uk", "admin", "password")
 
            Dim mySearcher As New System.DirectoryServices.DirectorySearcher(entry)
            mySearcher.SearchScope = SearchScope.Subtree
            Dim results As System.DirectoryServices.SearchResult
            Dim UserId As String = StripDomain(User.Identity.Name)
 
            mySearcher.Filter = ("(&(objectCategory=person)(objectClass=user)(samaccountname=" & UserId & "))")
            mySearcher.PropertiesToLoad.Add("samAccountName")
            mySearcher.PropertiesToLoad.Add("displayName")
            mySearcher.PropertiesToLoad.Add("sn")
            mySearcher.PropertiesToLoad.Add("givenName")
            mySearcher.PropertiesToLoad.Add("mail")
            mySearcher.PropertiesToLoad.Add("department")
            mySearcher.PropertiesToLoad.Add("manager")
 
            For Each results In mySearcher.FindAll()
                If results.GetDirectoryEntry().Path <> "" Then
 
                    lblUser1.Text = GetUserInfo(results, "displayName")
                    lblEmail1.Text = GetUserInfo(results, "mail")
                    lblDept1.Text = GetUserInfo(results, "department")
 
                    If results.Properties("manager").Count > 0 Then
                        Dim managerName As New DirectoryEntry("LDAP://" & results.Properties("manager")(0).ToString.Trim)
                        lblManager1.Text = managerName.Properties("displayName").Value
                        lblManagerEmail1.Text = managerName.Properties("mail").Value
                    End If
 
                End If
            Next
        Catch 
        End Try
    End Sub

Open in new window

0
 
Jon WinterburnAuthor Commented:
Aha! It was throwing the error: "The authentication mechanism is unknown" when I removed the try-catch statement. I read up on this and it seems that I have to specify the credentials in web.config for identity impersonation (even though I programatically define the credentials for connection to AD!)

So this is why your suggested code did not work either. So now I know, I award you the points as your code was fine, but the authentication on my server was invalid.

Thanks for your help.
0
All Courses

From novice to tech pro — start learning today.