Hi,
I'm currently building an Active Directory syncing service that takes a group email address as input and then needs to iterate over all the members (including nested) and retrieve the SMTP addresses of all these.
e.g.
Group A (groupA@firm.com):
- test1@firm.com
- test2@firm.com
- GroupB
Group B (groupB@firm.com):
- test3@firm.com
If the address groupA@firm.com, I need to get the following output as a list of 3 properties per item:
- (email: groupA@firm.com, parent: groupA@firm.com, isParent: True)
- (email: test1@firm.com, parent: groupA@firm.com, isParent: False)
- (email: test2@firm.com parent: groupA@firm.com, isParent: False)
- (email: groupB@firm.com, parent: groupA@firm.com, isParent: True)
- (email: test3@firm.com, parent: groupB@firm.com, isParent: False)
This service will be install on a server / pc with windows authentication access to AD, so ideally I don't want there to be any need for adding username / password, or even entering in a specific path.
So far I have looked at using DirectoryServices.AccountManagement and have written the below function. I intend to make a recursive sub function to iterate over nested groups, and will also add the three properties listed above later (currently just doing email).
Public Sub update_group(ByRef group As LDAP_Groups) Dim userList As New List(Of String) Dim DirectoryMemberProperties As System.DirectoryServices.PropertyCollection Dim DirectoryMail As Object Dim uac As Object Using context As New PrincipalContext(ContextType.Domain) Dim groupPr As GroupPrincipal = GroupPrincipal.FindByIdentity(context, IdentityType.Name, group.ad_address) If groupPr IsNot Nothing Then Dim members As PrincipalSearchResult(Of Principal) = groupPr.GetMembers(False) For Each principal As Principal In members ' get DirectoryEntry underlying it Dim de As DirectoryEntry = TryCast(principal.GetUnderlyingObject(), DirectoryEntry) If de IsNot Nothing Then DirectoryMemberProperties = de.Properties DirectoryMail = DirectoryMemberProperties("mail").Value uac = DirectoryMemberProperties("userAccountControl").Value Select Case de.SchemaClassName Case "group" If Not userList.Contains(LCase(DirectoryMail.ToString())) Then userList.Add(LCase(DirectoryMail.ToString())) Console.WriteLine(DirectoryMail.ToString()) 'ITERATIVE FUNCTIONALITY TO GO HERE End If Case "user" ' this is a user. If Nothing IsNot DirectoryMail Then If AccEnabled(uac) = 1 Then ' check the ad account is enabled 'If ModifiedDate > storedModifiedDate Then If Not userList.Contains(LCase(DirectoryMail.ToString())) Then userList.Add(LCase(DirectoryMail.ToString())) End If 'End If End If End If End Select End If Next groupPr.Dispose() End If End Using End Sub
The one problem is that this only works with AD group identity as per https://msdn.microsoft.com/en-us/library/bb356425(v=vs.110).aspx.
Is there anyway I can do a similar thing but where it takes the SMTP address as input for the search? I have looked also at DirectoryEntry and DirectorySearcher from System.DirectoryServices, however it seems this requires a path and domain input always?
Really appreciate any help here!
Thanks,
Tom