Ich habe begonnen, Gruppen wie die folgenden einzurichten:
- Abteilungsmitarbeiter
- Abteilungsleiter
- Abteilungsleiter
- Abteilungsleiter
Wobei der Abteilungsleiter ein Mitglied des Abteilungspersonals und der Abteilungsdirektor ein Mitglied des Abteilungsleiters ist.
Ich weiß, wie man mit Powershell auflistet, zu welchen Gruppen eine Person gehört, entweder direkt zugewiesen oder über die verschachtelten Gruppen geerbt.
Was ich jedoch versuche, ist ein Skript zu entwickeln, das mir alle Benutzer anzeigt, die sowohl direkt als auch indirekt Mitglieder einer dieser Gruppen sind. Beispielsweise ist Benutzer A ein direktes Mitglied des Abteilungspersonals und des Abteilungsleiters.
Beim Googeln kann ich kein Skript finden oder schreiben, das dies kann.
Bearbeiten:
In Wirklichkeit gibt es mehr Ebenen und Verzweigungen in der Verschachtelung und viele Abteilungen, sodass es verwirrend wird. Ich möchte eine Liste der Mitglieder erhalten, die direkt Teil einer Gruppe sind und auch indirekt Mitglied derselben Gruppe, damit ich die redundanten direkten Gruppenmitgliedschaften entfernen kann.
Antwort1
Im Folgenden wird eine gegebene übergeordnete Gruppe (Name muss mit Get-ADGroupMember
der Syntax kompatibel sein) durchsucht und zwei Hashes gefüllt. Ein Hash hat den Benutzer sAMAccountName als Schlüssel und ein Array vonDirekteGruppenmitgliedschaften als Wert. Der zweite Hash enthält die Schlüssel aller verarbeiteten Gruppen.
Zirkuläre Gruppenverschachtelungen (z. B. übergeordnetes Element ist untergeordnetes Element) werden korrekt erkannt und übersprungen. Sie können die Zeilen auskommentieren, Write-Host
um Zeilenrauschen in der Konsole zu reduzieren.
Import-Module ActiveDirectory
function Walk-Group ( $group ) {
Get-ADGroupMember $group | Group-Object objectClass -ash | Foreach-Object {
# Add each user to $users hash, add current group to their collection
if ( $_.user ) {
foreach ( $u in $_.user.GetEnumerator() ) {
if ( $users[$u.sAMAccountName] ) {
$users[$u.sAMAccountName] += $group
} else {
$users.Add( $u.sAMAccountName, @($group) )
}
}
}
# Recurse into each child group, skip if group is circular member
if ( $_.group ) {
foreach ( $g in $_.group.GetEnumerator() ) {
if ( $groups[$g.Name] ) {
Write-Host "Existing:" $g.Name
} else {
Write-Host "New Group:" $g.Name
$groups.Add( $g.Name, $true )
Walk-Group $g.Name
}
}
}
}
}
# Hash to collect user/group info.
$users = @{}
# Hash to collect processed groups.
$groups = @{}
# Root group to walk
Walk-Group "Department-staff"
# Display users with mulitple direct memberships
$users.GetEnumerator() | Where-Object { $_.Value.Count -gt 1 }
Antwort2
EDIT: Basierend auf Ihrer aktualisierten Beschreibung sollte so etwas funktionieren. Beachten Sie, dass ich mich nicht um Schleifen in der Gruppenmitgliedschaft gekümmert habe, sodass es möglicherweise ewig läuft.
$RootGroup=Get-ADGroup "your group here"
$username = "test user here"
Function RecurseMembership( $FromAbove, $username )
{
"------------------------------------------------------"
$FromAbove
$LevelUsers=$FromAbove | Get-ADGroupMember | where { $_.objectClass -eq "user" -and $_.SamAccountName -eq "$username" }
$LevelGroups=$FromAbove | Get-ADGroupMember | where { $_.objectClass -eq "group" }
$LevelUsers
$LevelGroups | ForEach-Object { RecurseMembership $_ $username }
}
RecurseMembership $RootGroup $username