Powershell muestra a los usuarios que son miembros de un grupo dos veces: una vez directamente y otra indirectamente

Powershell muestra a los usuarios que son miembros de un grupo dos veces: una vez directamente y otra indirectamente

He empezado a montar grupos como:

  • Personal del Departamento
    • supervisores de departamento
      • director 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-ADGroupMemberla 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-Hostlí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 

información relacionada