He empezado a montar grupos como:
- Personal del Departamento
- supervisores de departamento
- director de departamento
- supervisores de departamento
Donde los supervisores de departamento son miembros del personal del departamento y el director de departamento es miembro de los supervisores de departamento.
Sé cómo usar PowerShell para enumerar de qué grupos es miembro una persona, ya sea asignados directamente o heredados a través de los grupos anidados.
Pero lo que estoy tratando de encontrar es un script que me muestre todos los usuarios que son miembros de uno de esos grupos TANTO directa como indirectamente, por ejemplo. El usuario A es miembro directo del personal del departamento y del director del departamento.
Mi búsqueda en Google me falla al intentar encontrar o escribir un script que pueda hacer eso.
Editar:
En realidad, hay más capas y ramas en el anidamiento, y muchos departamentos, por lo que resulta confuso. Quiero obtener una lista de miembros que forman parte de cualquier grupo directamente, y también miembros del mismo grupo indirectamente para poder eliminar las membresías directas redundantes del grupo.
Respuesta1
Lo siguiente recorrerá un grupo principal determinado (el nombre debe ser compatible con Get-ADGroupMember
la sintaxis) y completará dos hashes. Un hash tendrá el usuario sAMAccountName como clave y una matriz dedirectopertenencia a grupos como valor. El segundo hash contendrá claves de todos los grupos procesados.
Detectará y omitirá correctamente los anidamientos de grupos circulares (por ejemplo, el padre es hijo del hijo). Puede comentar las Write-Host
líneas para reducir el ruido de línea en la consola.
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 }
Respuesta2
EDITAR: según su descripción actualizada, algo como esto debería funcionar. Tenga en cuenta que no me ocupé de los bucles en la membresía del grupo, por lo que es posible que se ejecute para siempre.
$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