Powershell дважды показывает пользователей, которые являются членами группы: один раз напрямую, другой — косвенно.

Powershell дважды показывает пользователей, которые являются членами группы: один раз напрямую, другой — косвенно.

Я начал создавать такие группы, как:

  • Отдел-сотрудники
    • Руководители отделов
      • Директор департамента

Где руководитель отдела является членом коллектива сотрудников отдела, а директор отдела является членом коллектива руководителей отдела.

Я знаю, как использовать PowerShell для вывода списка групп, членом которых является человек, либо назначенных напрямую, либо унаследованных через вложенные группы.

Но я пытаюсь придумать скрипт, который покажет мне всех пользователей, которые являются членами одной из этих групп КАК напрямую, так и косвенно, например, Пользователь А является прямым членом Department-staff и Department-director.

Мои попытки найти или написать скрипт, который мог бы это сделать, не увенчались успехом.

Редактировать:

На самом деле, есть больше слоев и ветвей для вложенности и много отделов, так что это становится запутанным. Я хочу получить список участников, которые являются частью любой группы напрямую, а также косвенным членом той же группы, чтобы я мог удалить избыточные прямые членства в группе.

решение1

Следующий код будет проходить заданную родительскую группу (имя должно быть совместимо с Get-ADGroupMemberсинтаксисом) и заполнять два хеша. Один хеш будет иметь пользователя sAMAccountName в качестве ключа и массивпрямойgroup memberships в качестве значения. Второй хэш будет содержать ключи всех обработанных групп.

Он будет правильно определять и пропускать циклические вложения групп (например, родитель является потомком потомка). Вы можете закомментировать строки, 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 }

решение2

EDIT: основываясь на вашем обновленном описании, что-то вроде этого должно работать. Обратите внимание, что я не позаботился о циклах в членстве в группе, поэтому вы можете обнаружить, что это работает вечно.

$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 

Связанный контент