Imports System.DirectoryServices Imports System.DirectoryServices.AccountManagement Public Class ClassActiveDirectory Private Shared excludedGroupNames As New List(Of String) From { "Abgelehnte", "DHCP", "Distributed COM", "Dns", "Domänen-Gäste", "Domänencomput", "Domänencontroller", "Druck", "Einstellungen eingehender", "Erstellungen", "Ereignis", "Gäst", "Hyper-V", "IIS_", "Klonbare", "Konten-Oper", "Kryptografie", "Leistungs", "Netzwerkskon", "PrivUser", "Protected User", "Prä-Windows", "RAS- und IAS-Server", "RDS-", "Remoteverwaltungs", "Replikations", "Reporting", "Richtlinien-Ersteller", "SQLAccess", "Schreibgeschützte Domänen", "Schlüsseladministratoren", "Server-Operatore", "Sicherungs", "Storage", "System Managed", "Terminalserver-Liz", "WinRMR", "Windows-Auth", "Unternehme", "Zertifikat", "Zugriffssteuerungs", "Zulässige" } Private Shared Function GetDirectoryEntry() Dim de As New DirectoryEntry($"LDAP://{Environment.UserDomainName}") de.Username = Nothing de.Password = Nothing de.AuthenticationType = AuthenticationTypes.Secure Return de End Function Public Shared Function GetDirectorySearch() As DirectorySearcher Dim dirEntry As DirectoryEntry = GetDirectoryEntry() Dim dirSearcher As DirectorySearcher = New DirectorySearcher(dirEntry) Return dirSearcher End Function Public Shared Function GetActiveDirectoryGroups() As List(Of String) Dim groups As New List(Of String) Dim de As DirectoryEntry = GetDirectoryEntry() Dim deSearch As DirectorySearcher = New DirectorySearcher() deSearch.SearchRoot = de deSearch.Filter = "(&(objectClass=group) (samAccountName=" & "*" & "))" Dim results As SearchResultCollection = deSearch.FindAll() For Each r As SearchResult In results Try 'Dim groupName = r.GetDirectoryEntry.Name.Replace("CN=", "") Dim groupName = r.Properties.Item("samaccountname").Item(0) If Not IsNothing(groupName) Then Dim isExcluded = excludedGroupNames.Where(Function(excludedGroup) Return (groupName.Contains(excludedGroup) Or groupName.StartsWith(excludedGroup)) End Function).Any() If Not isExcluded Then groups.Add(groupName) End If End If Catch ex As Exception MsgBox("Error while fetching Active Directory groups", MsgBoxStyle.Critical) End Try Next Return groups End Function 'Public Shared Function GetActiveDirectoryGroups(samAccountName As String) As List(Of String) ' Dim groups As New List(Of String) ' Dim adRoot As New DirectoryEntry() With { ' .AuthenticationType = AuthenticationTypes.Secure ' } ' Dim user As DirectoryEntry = FindUser(adRoot, samAccountName) ' If IsNothing(user) Then ' MsgBox($"Benutzer {samAccountName} wurde nicht in der Active Directory gefunden!") ' Return groups ' End If ' user.RefreshCache(New String() {"tokenGroups"}) ' For Each tokenGroup As Byte() In user.Properties("tokenGroups") ' Dim groupName As String = GetGroupNameFromTokenGroupEntry(adRoot, tokenGroup) ' If Not IsNothing(groupName) Then ' Dim isValidGroup As Boolean = excludedGroupNames.Where(Function(excludedGroup) Not groupName.StartsWith(excludedGroup)).Any() ' If isValidGroup Then ' groups.Add(groupName) ' End If ' End If ' Next ' Return groups 'End Function Public Shared Function GetActiveDirectoryUsersForGroup(groupName As String) As List(Of UserPrincipal) Dim users As New List(Of UserPrincipal) Using context As New PrincipalContext(ContextType.Domain) Using group As GroupPrincipal = GroupPrincipal.FindByIdentity(context, IdentityType.Name, groupName) Using members = group.GetMembers(True) For Each member As UserPrincipal In members If TypeOf member Is UserPrincipal Then users.Add(member) End If Next End Using End Using End Using Return users End Function Private Shared Function GetGroupNameFromTokenGroupEntry(rootEntry As DirectoryEntry, tokenGroup As Byte()) Dim sID As New Security.Principal.SecurityIdentifier(tokenGroup, 0) Dim sIDSearch = New DirectorySearcher(rootEntry, $"(objectSid={sID.Value})", New String() {"name"}) Dim sIDResult = sIDSearch.FindOne() If IsNothing(sIDResult) Then Return Nothing Else Return sIDResult.Properties("name").Item(0).ToString() End If End Function Private Shared Function FindUser(rootEntry As DirectoryEntry, samAccountName As String) As DirectoryEntry Dim userSearch = New DirectorySearcher( rootEntry, $"(samAccountName={samAccountName})", New String() {"displayName"} ) Dim result = userSearch.FindOne() If IsNothing(result) Then Return Nothing Else Return result.GetDirectoryEntry() End If End Function End Class