Я начал создавать такие группы, как:
Где супервайзеры департаментов входят в состав сотрудников департаментов, а директор департаментов входит в состав супервайзеров департаментов.
Я знаю, как использовать PowerShell, чтобы составить список групп, членом которых является человек, либо непосредственно назначенных, либо унаследованных через вложенные группы.
Но я пытаюсь придумать сценарий, который покажет мне всех пользователей, которые являются членами одной из этих групп прямо и косвенно, например. Пользователь А является прямым членом сотрудников отдела и директором отдела.
Мой поиск в Google терпит неудачу в попытке найти или написать сценарий, который может это сделать.
Редактировать:
На самом деле у вложенности больше слоев и ветвей, и много отделов, так что это сбивает с толку. Я хочу получить список участников, которые являются частью любой группы напрямую, а также косвенно членами той же группы, чтобы я мог удалить избыточное прямое членство в группе.
Следующее будет проходить по данной родительской группе (имя должно быть совместимо с Get-ADGroupMember
синтаксис) и заполните два хеша. Один хэш будет иметь пользователя sAMAccountName в качестве ключа и массив непосредственный членство в группах как значение. Второй хеш будет содержать ключи всех обрабатываемых групп.
Он будет правильно обнаруживать и пропускать циклические групповые вложения (например, родитель является дочерним элементом дочернего элемента). Вы можете прокомментировать Write-Host
линии для уменьшения линейного шума в консоли.
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 }
РЕДАКТИРОВАТЬ: на основе вашего обновленного описания должно работать что-то вроде этого. Обратите внимание, что я не позаботился о циклах в членстве в группах, поэтому вы можете обнаружить, что они работают вечно.
$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