Powershell mostra usuários que são membros de um grupo duas vezes - uma vez diretamente uma vez indiretamente

4

Eu comecei a configurar grupos como:

  • Departamento de pessoal
    • Supervisores de departamento
      • Diretor de departamento

Quando os supervisores do departamento são membros do pessoal do departamento, e o diretor do departamento é membro dos supervisores do departamento.

Eu sei usar o powershell para listar de quais grupos uma pessoa é membro, diretamente atribuída ou herdada pelos grupos aninhados.

Mas o que estou tentando descobrir é um script que mostrará todos os usuários que são membros de um desses grupos, direta e indiretamente, por exemplo. O usuário A é um membro direto do Departamento de Pessoal e do Departamento de Direção.

Meu googling me falha ao tentar encontrar ou escrever um script que possa fazer isso.

Editar:

Na realidade, existem mais camadas e ramificações no aninhamento e em muitos departamentos, por isso é confuso. Eu quero obter uma lista de membros que fazem parte de qualquer grupo diretamente, e também um membro do mesmo grupo indiretamente, para que eu possa remover as associações diretas do grupo redundante.

    
por Grant 22.05.2013 / 19:49

2 respostas

4

Os itens a seguir percorrerão um determinado grupo pai (o nome deverá ser compatível com a sintaxe Get-ADGroupMember ) e preencherão dois hashes. Um hash terá o sAMAccountName do usuário como a chave e uma matriz de associações de grupo direct como o valor. O segundo hash conterá chaves de todos os grupos processados.

Ele detectará e ignorará corretamente os aninhamentos de grupos circulares (por exemplo, pai é filho de filho). Você pode comentar as linhas Write-Host para menos ruído de linha no console.

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 }
    
por 28.05.2013 / 14:33
2

EDIT: com base na sua descrição atualizada, algo como isto deve funcionar. Note que eu não cuidei de loops na associação ao grupo, então você pode encontrá-lo funcionando para sempre.

$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 
    
por 22.05.2013 / 20:01