Powershell은 그룹의 구성원인 사용자를 두 번 표시합니다(직접 한 번, 간접적으로 한 번).

Powershell은 그룹의 구성원인 사용자를 두 번 표시합니다(직접 한 번, 간접적으로 한 번).

다음과 같은 그룹을 설정하기 시작했습니다.

  • 부서직원
    • 부서장
      • 학과장

부서 감독자는 부서 직원의 구성원이고 부서 책임자는 부서 감독자의 구성원입니다.

나는 powershell을 사용하여 개인이 어떤 그룹에 속해 있는지, 직접 할당되거나 중첩된 그룹을 통해 상속되는지 나열하는 방법을 알고 있습니다.

하지만 제가 알아내려고 하는 것은 해당 그룹 중 하나의 구성원인 모든 사용자를 직간접적으로 표시하는 스크립트입니다. 사용자 A는 부서 직원 및 부서 책임자의 직속 구성원입니다.

내 인터넷 검색으로는 이를 수행할 수 있는 스크립트를 찾거나 작성하는 데 실패했습니다.

편집하다:

실제로는 중첩에 더 많은 레이어와 가지가 있고, 부서도 많아 혼란스럽습니다. 중복된 그룹 직접 멤버십을 제거할 수 있도록 어떤 그룹에 직접 속해 있는 구성원 목록과 간접적으로 동일한 그룹에 속해 있는 구성원 목록을 얻고 싶습니다.

답변1

다음은 지정된 상위 그룹(이름은 구문과 호환되어야 함 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 }

답변2

편집: 업데이트된 설명에 따르면 다음과 같이 작동합니다. 그룹 멤버십의 루프를 처리하지 않았으므로 영원히 실행될 수도 있습니다.

$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 

관련 정보