Comecei a configurar grupos como:
- Pessoal do departamento
- Supervisores de departamento
- Diretor de departamento
- Supervisores de departamento
Onde os supervisores de departamento são membros do pessoal do departamento e o diretor de departamento é membro dos supervisores de departamento.
Eu sei como usar o PowerShell para listar de quais grupos uma pessoa é membro, atribuídos diretamente ou herdados pelos grupos aninhados.
Mas o que estou tentando descobrir é um script que me mostre todos os usuários que são membros de um desses grupos, direta e indiretamente, por exemplo. O usuário A é um membro direto da equipe do departamento e do diretor do departamento.
Minha pesquisa no Google falha ao tentar encontrar ou escrever um script que possa fazer isso.
Editar:
Na realidade, há mais camadas e ramificações no aninhamento e muitos departamentos, por isso fica confuso. Quero obter uma lista de membros que fazem parte diretamente de qualquer grupo e também de um membro do mesmo grupo indiretamente, para que possa remover as associações diretas redundantes do grupo.
Responder1
O seguinte percorrerá um determinado grupo pai (o nome deve ser compatível com Get-ADGroupMember
a sintaxe) e preencherá dois hashes. Um hash terá o usuário sAMAccountName como chave e uma matriz dediretoassociações de grupo como o valor. O segundo hash conterá as chaves de todos os grupos processados.
Ele detectará e pulará corretamente os aninhamentos de grupos circulares (por exemplo, pai é filho de filho). Você pode comentar as Write-Host
linhas para obter 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 }
Responder2
EDIT: com base na sua descrição atualizada, algo assim deve funcionar. Observe que eu não cuidei dos 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