Re: Populate TreeView with Active Directory objects
Right so you are using the expand groups option - I'm afraid there's no way I can make that part any faster as this is all the code that is responsible for getting the group members:
vb Code:
Dim Members As Object = ObjectDE.Invoke("Members", Nothing) '<<< Get members
For Each Member As Object In CType(Members, IEnumerable) '<<< loop through members
Dim CurrentMember As New DirectoryEntry(Member) '<<< Get directoryentry for user
ChildNode.Nodes.Add(New AdTreeNode(CurrentMember.Name.Remove(0, 3), CurrentMember.Properties("distinguishedName").Value.ToString, GetAdObjectType(CurrentMember))) '<<< Add this node to our group node (which will later be added to the tree view)
Next
and that is the only way I know of that you can get the group members.
Do you really need to be able to expand groups? To be honest I couldn't see much use for that option when I added it. I mean if you are using this control to let the user of your application select a User or Group from AD then they dont need to be able to expand groups... they just need to know where the user or group is.
Re: Populate TreeView with Active Directory objects
Well after 60 seconds I get this:
The CLR has been unable to transition from COM context 0x20a310 to COM context 0x20a480 for 60 seconds. The thread that owns the destination context/apartment is most likely either doing a non pumping wait or processing a very long running operation without pumping Windows messages. This situation generally has a negative performance impact and may even lead to the application becoming non responsive or memory usage accumulating continually over time. To avoid this problem, all single threaded apartment (STA) threads should use pumping wait primitives (such as CoWaitForMultipleHandles) and routinely pump messages during long running operations.
I really dont need to expand the groups. I did not know it would enumerate all the members of each group for the entire groups OU. I was hopping it would just show the members when I click on that group within the OU. Anyway, great work and this will really save me a bunch of time:-)
Re: Populate TreeView with Active Directory objects
I never added the ability to specify exactly which objects you want to be visible but I did add a property that lets you choose to only show containers and OUs if that is of any use?
Re: Populate TreeView with Active Directory objects
Hi Chris
Firstly, thanks for posting this. Works a treat. I'm just having a small issue with the icons.. In my tree view, all objects appear using the same icon (the computer icon). I followed your instructions with extracting the icons, creating an image list and attaching this to the tree view. Not sure what I might be doing wrong?
Re: Populate TreeView with Active Directory objects
You probably didn't name the images correctly then You need to set the ImageKey property of each image in the image list to the names that I mentioned in my original post.
Having said that, I'm working on a much better version that will handle the icons for you and be faster and behave more like other .NET dialog windows.
Re: Populate TreeView with Active Directory objects
Thanks Robert let me know how it goes and if you have any feedback
I'll also be releasing another dialog window soon that can be used to select users/groups/computers from AD, similar to the native window built in to Windows shown below:
Re: Populate TreeView with Active Directory objects
Is it possible to start in a specified OU, such as domain.org/Computers? I'm using this to select the container in a program that will add computers to AD, I already know they will go in this container.
Re: Populate TreeView with Active Directory objects
Originally Posted by awsnap
Is it possible to start in a specified OU, such as domain.org/Computers? I'm using this to select the container in a program that will add computers to AD, I already know they will go in this container.
No I'm afraid not, but if you already know which OU they will go in, why do you need them to select an OU at all?
Re: Populate TreeView with Active Directory objects
Our AD structure is highly organizational under that first OU. Also, it takes a while for this to load everything as talked about. It looks like you are looking at what children there are and then looking to see if the children have children. For me that's very time consuming. Anyway to just do the first query for each level?
Re: Populate TreeView with Active Directory objects
Actually there is a way. I haven't figure out the little things about it but it's possible.
On the line in AdTreeViewForm.vb:
Using RootDirectoryEntry As New DirectoryEntry("LDAP://" & _DomainController & ":389/" & "OU=***,DC=***,DC=***")
This will take you there BUT, will not auto load that OU, nor show the OU in the tree. Anyone have any ideas? (This cuts out loading about 11000 users among other things for me.)
Re: Populate TreeView with Active Directory objects
First I would like to say this app is greate.
I have one semi challenging question. Right now I am able to view the containers and select them in AD and at the bottom of your app it shows the LDAP path of the container you have selected.
What I want to do is search for a user and get the path of the container where it is located.
So my question is, is there anyway to search for a container in AD with out haveing to visually see it, rather then having the user visually click on the OU's and have the program tell what OU they have selected?
Re: Populate TreeView with Active Directory objects
Yeah that's easy, but nothing to do with my example here. Just use the built in DirectorySearcher class (in the System.DirectoryServices namespace) to search for the user by their username (sAMAccountName) or whatever you want, and then get the DistinguishedName attribute from the user object as that has the full path to the object in it.
So how do I use the second part of the code? How do I compare the samAccountName to the DistinguishedName attribute from the user object as that has the full path to the object in it?
Re: Populate TreeView with Active Directory objects
Thanks very much for the response! Ok so I have everything working but one piece. Is there a way to move a user or object that you bind to up one or down one organizational unit with out binding to that OU directly?
The problem I am having is my company names there OU's a certain way, For example:
Company Sites
Site OU
Site PC Users
The computers and User lives in that Bottom OU. I want to move the user up one OU long enough to make changes to the PC's so ther Group Policy is not applied. But I cant compare the Username to the strings in the OU's because our users are usually something like : z_123 or some type of letter_and a three digit number, Not the Site Name.
So I am looking for an easy way to just move a user Up one OU and then back down with out excatly knowing the OU's Specific name I want to move it into and then back down?
Re: Populate TreeView with Active Directory objects
Why do you want to move them into an OU and then straight back out of it? I know you said you don't want them to be in the upper OU long enough for GPOs linked to that OU to apply to them, but why move them in there at all?
Re: Populate TreeView with Active Directory objects
Because the Global Policy is being applied at the lower level so I need to move the user up one level so the policy will become unapplied long enough for the application to configure the computer, once the application has configuered the computer correctly it will verify everything is correct move the user back down and reboot the computer.
Re: Populate TreeView with Active Directory objects
Why can't the application configure the computer while the "global policy" is applied to it? What does the application need to do that the GPO is preventing? The idea of moving a user to another OU temporarily just so that something can work is a good sign of pretty bad GPO design. If the application needs to do something on the client computer that the user does not have permission to do (due to the GPO applying to that user) then it should not be running as that user.
Also you would have to do a gpupdate on the client computer for it to detect that the user has moved to a new OU as well, otherwise it could be up to 90 minutes between you moving the user in AD and the client machine actually picking up that change and applying (or removing in this case) the new GPOs it should apply.
Re: Populate TreeView with Active Directory objects
The environment was configuered like this when I got here. I am just trying to work with what I have.
The application configures the laptop in 3 steps:
1. Renames it and Adds it to the domain and drops the pc in the proper OU.
Reboots
2. Moves the user up, Configures the laptop with the proper registry edits, etc.
Reboots
3. Adds the printers Moves the user back down
Reboots
Its complete.
So I need to be able to move a user up and down one level each way.
Re: Populate TreeView with Active Directory objects
You still haven't answered the question of what exactly the application CAN'T do whilst the normal GPOs are applying. Registry edits should work fine regardless of what GPO settings you've got configured... if they didn't then half the programs your users use wouldn't work.
Re: Populate TreeView with Active Directory objects
The Group Policy completly locks the computer down from ther user. And that is the user that has to be logged in when configuring the laptop becuase alot of the config changes we make are user based changes not global changes to the laptop. For example, Tabbed browsing, adding printers, Verifying if adobe is installed if it is installing it, things like that.
Re: Populate TreeView with Active Directory objects
Yes but Group Policy generally just disables the GUI for changing something so that the user cannot change it, but a program changing it would still work most of the time. Have you actually tried running your program while the user is in the regular OU?
Re: Populate TreeView with Active Directory objects
Hi Chris,
First of all I'd like to thank you for the code.
Further I have written a small recursive routine to populate the tree and since I have seen in one of the threads that you intended to do this I thought I'd post it.
If you have already done this then ignore this thread.
P.S. I have re-used some of your code to do this.
Code:
Private Sub btnConnect_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnConnect.Click
m_userDomainName = ActiveDirectoryHelper.GetUserDomainName
m_domainController = ActiveDirectoryHelper.GetSingleDomainController(m_userDomainName, m_domainUserName, m_domainUserPassword)
Dim DomainObject As Domain = Domain.GetDomain(ActiveDirectoryHelper.GetDomainContext(m_userDomainName, m_domainUserName, m_domainUserPassword))
Dim RootNode As New TreeNode
Using RootDirectoryEntry As DirectoryEntry = DomainObject.GetDirectoryEntry
RootNode.Name = CStr(RootDirectoryEntry.Properties("distinguishedName").Value).Replace("/", "\/")
RootNode = adTree.Nodes.Add(RootNode.Name)
CreateTree(RootDirectoryEntry, RootNode)
End Using
End Sub
Private Sub CreateTree(ByVal dirEntry As DirectoryEntry, ByVal parentNode As TreeNode)
For Each ChildObj As DirectoryEntry In dirEntry.Children
'add it first
Dim childNode As New TreeNode
childNode.Name = CStr(ChildObj.Properties("distinguishedName").Value).Replace("/", "\/")
childNode = parentNode.Nodes.Add(childNode.Name)
'do the recursive call
CreateTree(ChildObj, childNode)
Next
End Sub
Can't wait to try it out. Thank you! The previous version has been a favorite tool. I'm looking forward to updating all my programs withthis new one.
Dim SelectContainerDialog As New Cjwdev.ActiveDirectory.Dialogs.SelectAdContainerDialog
SelectContainerDialog.Title = ("Choose the department OU to search for Job Role groups.")
SelectContainerDialog.ShowDialog()
Chris the new dialog is too cool. Thank you. but, Is there a way to defalut to an expanded view? At least the first domain node. Oh the Mouse wheel scroll doesn't seem to work for me. How do I progamatically size the control?
Last edited by RKirchhof; Nov 1st, 2012 at 12:01 PM.
Re: Populate TreeView with Active Directory objects
Chris,
I'm using your code in a C# project. Do you have any idea why I'd be able to load the main now, obtain the distinguished name, but not be able to load the child nodes? When I expand the very first node, it just says loading. When I debug it, it goes through the steps just like it does in the VB project.
I can show how I'm implementing it of course, but wanted to see if you knew anything off the top of your head.
EDIT: It's throwing an exception in the LoadAdNodes method via LoadFinished.
Logon failure: unknown user name or bad password
But I've verified that the domain, domain controller, user, and password are all correct.
Last edited by weirddemon; Nov 28th, 2012 at 09:38 AM.
Re: Populate TreeView with Active Directory objects
Originally Posted by chris128
How are you specifying the username? Try using DOMAIN\Username if you were just using Username on its own
Or did it work fine with the same username and password in my VB example?
I got it to work. I pasted something wrong. When I deleted everything and repasted, it worked.
But, it won't work if I leave the password as an empty string. I can't look through your code right now, but I thought if a password wasn't passed, it would still work if the current user has access. Which I remember it doing, but if I pass a an empty string to it in my project, it fails. I have to pass the password to it.
Re: Populate TreeView with Active Directory objects
Chris,
Also, is there an easy way to get the attributes for each container? For the attributes you see in ADSI Edit.
EDIT: Never mind. I figure it out. You were already populating this data via ChildObject. So I created a property for AdTreeNode that is a List<string>. Then I iterated through the property list and added each one to the AdTreeNodes property list.
Last edited by weirddemon; Nov 29th, 2012 at 02:32 PM.
Re: Populate TreeView with Active Directory objects
Originally Posted by weirddemon
I got it to work. I pasted something wrong. When I deleted everything and repasted, it worked.
But, it won't work if I leave the password as an empty string. I can't look through your code right now, but I thought if a password wasn't passed, it would still work if the current user has access. Which I remember it doing, but if I pass a an empty string to it in my project, it fails. I have to pass the password to it.
For it to use the current user's credentials you need to not set the username or password properties
Re: Populate TreeView with Active Directory objects
Originally Posted by chris128
For it to use the current user's credentials you need to not set the username or password properties
Oh. Ok. That should be easy. One more thing, if you don't mind. This is the code I'm using to get the OU/Container attributes and their values.
C# Code:
foreach (PropertyValueCollection p in ChildObject.Properties)
{
ActiveDirectoryAttributeList ADAList = new ActiveDirectoryAttributeList();
ADAList.Attribute = p.PropertyName;
ADAList.AttributeValue = p.Value.ToString();
ChildNode.Attributes.Add(ADAList);
}
Your code defines ChildObject as a DirectoryEntry, with which you use to loop through the RootDirectory.Children. I then loop through all of the properties for the ChildObject to get the attributes and attribute values. I add those two data points to a list of a custom class called ActiveDirectoryAttributeList. I then add them to a property of AdTreeNode I added, called Attributes. All of that works just fine. I can see the attributes and their values during runtime, but it only pulls some attributes. Not all of them.
Re: Populate TreeView with Active Directory objects
Nice piece of code. I tried to use some of the code in my app.
"Using SelectContainerDialog As New cjwdev.ActiveDirectory.Dialogs.SelectAdContainerDialog"
but I get this error:
"Type 'cjwdev.ActiveDirectory.Dialogs.SelectAdContainerDialog' is not defined."
What am I missing?
Thanks