Solved

VB.NET - Active Directory to find organizational unit for a user

Posted on 2010-08-19
37
1,788 Views
Last Modified: 2013-11-27
Hello experts,

I created a windows form application that create a record to a database.  The application will get the window user's login name as the creator of that record.  However, I also need to know where they're located.  In Active Directory, we have organizational units for various users.  Is there a way I can find out which organizational unit that user is from?

Here's my code to find out the username that is logged onto the machine:

Dim strUser as String = System.Environment.UserName

I need to find out which organizational unit this user is located within.  Any ideas?
0
Comment
Question by:holemania
  • 22
  • 15
37 Comments
 
LVL 16

Expert Comment

by:13598
ID: 33475330
Use the directorysearcher.
Here is an example to get the user's e-mail address. You will need to change the filter to get what you are looking for specifically: instead of e-mail address you need organizational unit

Using searcher As New DirectoryServices.DirectorySearcher()
'get the current root which is the domain name in DC=domain format
'remove the DC= to just have the name
Dim domainName As String = searcher.SearchRoot.Name.Replace("DC=", "")
Dim username As String = My.User.Name.ToLower.Replace(domainName, "").Replace("\", "")
'create a search/filter string to get that user
searcher.Filter = "(&(objectCategory=person)(objectClass=user)(samaccountName=" & username.Trim & "))"
'find the first user that matches the filter
Dim result As DirectoryServices.SearchResult = searcher.FindOne
If result IsNot Nothing Then
sEmailFromAddress = result.Properties("mail")(0).ToString
End If
End Using
0
 
LVL 16

Expert Comment

by:13598
ID: 33475563
You need to add a reference to the system.directoryservices
 and you could try something like this:

Using searcher As New DirectoryServices.DirectorySearcher()
'get the current root which is the domain name in DC=domain format
'remove the DC= to just have the name
Dim domainName As String = searcher.SearchRoot.Name.Replace("DC=", "")
Dim username As String = My.User.Name.ToLower.Replace(domainName, "").Replace("\", "")
'create a search/filter string to get that user
searcher.Filter = "(&(objectCategory=person)(objectClass=user)(samaccountName=" & username.Trim & "))"
'find the first user that matches the filter
Dim result As DirectoryServices.SearchResult = searcher.FindOne
If result IsNot Nothing Then
sCn = result.GetDirectoryEntry().Properties("cn").Value.ToString
End If
End Using  
0
 

Author Comment

by:holemania
ID: 33475909
Thanks.  This is the result that I get.

For the username string I get the following result:  Domain and Username (flxmurphy).  DM is the domain name and xmurphy is the user.  Once it does that it gives me nothing else through the filter.

This user is in the orginazational unit "Florida".  That's what I want to pull and insert that to my table.
0
 
LVL 16

Expert Comment

by:13598
ID: 33476007
It depends on how your AD is setup.
Are you saying the username should be xmurphy  but you get flxmurphy?
How do you arrive at flxmurphy? Can you post your code?
0
 
LVL 16

Expert Comment

by:13598
ID: 33476038
doesn't fl stand for Florida?
Do you just need to retrive the first 2 letters then something like:
yourou = mid(username.tostring,1,2)
0
 

Author Comment

by:holemania
ID: 33476155
So the OU doesn't give me the name?

Example the OU is FL, but the name is shown as Florida.  If that's the case, I guess I can use case "If" statement to tell me the name.
0
 
LVL 16

Expert Comment

by:13598
ID: 33476185
That is not what I am saying. What I am saying is that you need to know your AD structure and what info goes where.
How do you get flxmurphy as username?
0
 
LVL 16

Expert Comment

by:13598
ID: 33476257
I need more info on your comment: "Example the OU is FL, but the name is shown as Florida"
Are you saying the ou is FL then that is what you will get as ou.
The name is shown as Florida => where is it shown as Florida?  
0
 

Author Comment

by:holemania
ID: 33476449
Sorry, let me clarify.

Using your code, the domain is FL followed by the user name xmurphy.

'get the current root which is the domain name in DC=domain format
'remove the DC= to just have the name
Dim domainName As String = searcher.SearchRoot.Name.Replace("DC=", "")

Result is "fl".

Dim username As String = My.User.Name.ToLower.Replace(domainName, "").Replace("\", "")

Result is "flxmurphy".

In Active Directory below the AD structure if I go expand that there are folders for each organizational unit.  If I look at the organizational unit folder, it list that as Florida.  I was hoping I can pull that organizational unit folder name for the user that is in that OU.  There are a number of organizational unit folder under the domain FL.  One is Florida, Taveres, Tampa, etc.  If a user is located in one of the organizational unit, I want to pull that organizational unit name.
Sorry for the confusion.  "FL" is the domain but I need the organizational units inside of that domain since there are multiples.
0
 
LVL 16

Expert Comment

by:13598
ID: 33476582
Dim username As String = My.User.Name.ToLower.Replace(domainName, "").Replace("\", "")

Result is "flxmurphy". => How can this be if domainName = "fl" ?
0
 
LVL 16

Expert Comment

by:13598
ID: 33476611
This statement
My.User.Name.ToLower.Replace(domainName, "").Replace("\", "")
Is replacing the value in domainName with nothing (basically deleting it out)
If domainName is "fl" it would result in xmurphy not flxmurphy.
0
 
LVL 16

Expert Comment

by:13598
ID: 33476639
What is the value in this:
messagebox.show(my.user.name)
0
 
LVL 16

Expert Comment

by:13598
ID: 33476695
The only thing that would cause that result is if domainName is actually "FL" not "fl".
Change your statement to this:
Dim username As String = My.User.Name.ToLower.Replace(domainName.ToLower, "").Replace("\", "")
And let me know what you get for username.
 
0
 

Author Comment

by:holemania
ID: 33476720
It shows up as:

FL\xmurphy
0
 

Author Comment

by:holemania
ID: 33476790
If I don't use ToLower, this is what it would look like with the following code:

Dim username As String = My.User.Name.Replace(domainName, "").Replace("\", "")

FLxmurphy

Looking at the code, it's supposed to replace domainName with blank and "\" with blank.  But it doesn't seem to be doing that for some reason.
0
 
LVL 16

Expert Comment

by:13598
ID: 33476816
Did you see my previous post?  =>
"The only thing that would cause that result is if
domainName is actually "FL" not "fl".
Change your statement to this:
Dim username As String = My.User.Name.ToLower.Replace(domainName.ToLower, "").Replace("\", "")
And let me know what you get for username."

0
 

Author Comment

by:holemania
ID: 33476868
I think I should be able to use the following if all that we're pulling is the username.

Using searcher as New DirectoryServices.DirectorySearcher()
Dim username as string = System.Environment.Username
searcher.filter = "(&(objectCategory=person)(objectClass=user)(sameaccountName=" & username.trim & "))"
Dim result as DirectoryServices.SearchResult = searcher.Findone
If result IsNot Nothing then
    Dim sCn As string = result.GetDirectoryEntry().Properties("cn").Value.ToString
End If
End Using

Only thing is my searcher.filter returns no result.  So i'll have to see how the AD is structure.
0
 
LVL 16

Expert Comment

by:13598
ID: 33476908
What is the value you get here?
messagebox.show(username.trim)
If you are passing flxmurphy as username well it is not a valid username and that is why you get nothing.
 
This should give you username = xmurphy
Dim domainName As String = searcher.SearchRoot.Name.Replace("DC=", "")


Dim username As String = My.User.Name.ToLower.Replace(domainName.ToLower, "").Replace("\", "")
 
 
0
Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

 

Author Comment

by:holemania
ID: 33476917
Ah I caught where I did the typo also why it's not returning anything.  "samaccountName" is where my typo is.  So the above code is pulling it now.  Looking at the result, it is showing the OU.  How do I get the OU to show in show in a string?
0
 
LVL 16

Expert Comment

by:13598
ID: 33476948
What do you mean?
Isn't it showing in sCn ?
0
 

Author Comment

by:holemania
ID: 33477142
sCn is showing the full name:  Xavier Murphy

If I look at the Result string, this is what's showing:

Path  "LDAP://CN=Xavier Murphy, OU=IT, OU=FL, OU=Users, OU=Florida, DC=AD, DC=FL, DC=ContinentalSteel, DC=COM"

I want to pull the OU=Florida and not the CN name.
0
 
LVL 16

Expert Comment

by:13598
ID: 33477182
Did you try
   Dim sCn As string = result.GetDirectoryEntry().Properties("ou").Value.ToString
 
0
 
LVL 16

Expert Comment

by:13598
ID: 33477237
Try something like this:
If TypeOf Result.GetDirectoryEntry.Properties("ou") Is
System.Array Then
  Dim sCn As string = Result.GetDirectoryEntry.Properties("ou")(2).Value
Else
dim sCn As string = Result.GetDirectoryEntry.Properties("ou").Value
End If
 
0
 

Author Comment

by:holemania
ID: 33477261
Yes, I tried that and get the following error message:

Object reference not set to an instance of an objbect.
0
 
LVL 16

Expert Comment

by:13598
ID: 33477279
Is that error on the first suggestion or the last one?
If it is on the first suggestion it is because it is an array .
Did you try the last suggestion?
0
 

Author Comment

by:holemania
ID: 33477303
It's the first one.  The 2nd one that I tried, it as well and get this error message.

Expression of type 'System.DirectoryServices.PropertyValueCollection' can never be of type 'System.Array'.
0
 
LVL 16

Expert Comment

by:13598
ID: 33477724
I guess the quickest way will be to extract it from the string or we can try looping through subou entries. My AD is not setup like yours so I can't really test it.
What do you get if you use this:

result.GetDirectoryEntry().Properties("organizationalUnit").Value
 
0
 
LVL 16

Expert Comment

by:13598
ID: 33477828
Add this to your code (exactly as is especially the Try/catch block) and see if any of the properties will give you FLORIDA:

For Each mys As String In result.Properties.PropertyNames
Try
MsgBox(mys.ToString & "_" & result.GetDirectoryEntry().Properties(mys.ToString).Value)
Catch ex As Exception
End Try

Next
0
 

Author Comment

by:holemania
ID: 33478536
Tried your last example and it did a loop through.  Only property with the OU is from property distinguishedname.

CN=Xavier Murphy, OU=IT, OU=FL, OU=Users,OU=Florida, DC=AD, DC=ContinentalSteel, DC=COM

I guess a parse function should be able to filter out just Florida.
0
 
LVL 16

Expert Comment

by:13598
ID: 33478620
Does the distinguishedname then give you Florida, is that what you are saying?
0
 

Author Comment

by:holemania
ID: 33478638
It gives me the above example.

CN=Xavier Murphy, OU=IT, OU=FL, OU=Users,OU=Florida, DC=AD, DC=ContinentalSteel, DC=COM
0
 
LVL 16

Expert Comment

by:13598
ID: 33478657
do you mean the below example:
CN=Xavier Murphy, OU=IT, OU=FL, OU=Users,OU=Florida, DC=AD, DC=ContinentalSteel, DC=COM
distinguishedname gives you all that?
0
 

Author Comment

by:holemania
ID: 33478753
Yeah but then I was able to parse it and it's giving me what I want.

Dim sCn As String = result.GetDirectoryEntry().Properties("distinguishedname").Value
lblOU.Text = Replace(Split(sCn, ", ")(4), "OU", "")
0
 

Author Comment

by:holemania
ID: 33478993
Well the above only worked for 2 sites  and pulled differently for another site.  Any idea of how I can parse it from the right to left?  The extra folder is what's throwing it off, but if I can go from right to left, it'll be same for all sites.
0
 
LVL 16

Accepted Solution

by:
13598 earned 500 total points
ID: 33479114
This should work:
Dim sCn As String = result.GetDirectoryEntry().Properties("distinguishedname").Value.ToUpper

Dim iLength As Integer = InStr(InStrRev(sCn, "OU="), sCn, ",") - (InStrRev(sCn, "OU=") + 3)
lblOU.Text = Mid(sCn, InStrRev(sCn, "OU=") + 3, iLength)
0
 

Author Closing Comment

by:holemania
ID: 33479254
Thanks for the help.  Appreciate it.
0
 
LVL 16

Expert Comment

by:13598
ID: 33479353
You are welcome.
You should probably encapsulate it with some error trapping so it doesn't blow up if there was an entry that didn't follow the rule=>
try

Dim sCn As String = result.GetDirectoryEntry().Properties("distinguishedname").Value.ToUpper

'if for some reason the entry didn't contain OU= this will blow up=>
if scn.contains("OU=") then
Dim iLength As Integer = InStr(InStrRev(sCn, "OU="), sCn, ",") - (InStrRev(sCn, "OU=") + 3)
lblOU.Text = Mid(sCn, InStrRev(sCn, "OU=") + 3, iLength)  
else
lblOU.Text = "N/A"
end if
catch
end try
0

Featured Post

6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

Join & Write a Comment

Resolve DNS query failed errors for Exchange
Restoring deleted objects in Active Directory has been a standard feature in Active Directory for many years, yet some admins may not know what is available.
This tutorial will walk an individual through the steps necessary to join and promote the first Windows Server 2012 domain controller into an Active Directory environment running on Windows Server 2008. Determine the location of the FSMO roles by lo…
This tutorial will walk an individual through the process of transferring the five major, necessary Active Directory Roles, commonly referred to as the FSMO roles from a Windows Server 2008 domain controller to a Windows Server 2012 domain controlle…

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

14 Experts available now in Live!

Get 1:1 Help Now