Powershell はグループのメンバーであるユーザーを 2 回表示します - 1 回は直接、もう 1 回は間接的に

Powershell はグループのメンバーであるユーザーを 2 回表示します - 1 回は直接、もう 1 回は間接的に

私は次のようなグループを立ち上げ始めました:

  • 部門スタッフ
    • 部門長
      • 部門長

部門管理者は部門スタッフのメンバーであり、部門ディレクターは部門管理者のメンバーです。

PowerShell を使用して、直接割り当てられているか、ネストされたグループを通じて継承されているかを問わず、ユーザーがメンバーになっているグループを一覧表示する方法を理解しています。

しかし、私が理解しようとしているのは、直接的および間接的にいずれかのグループのメンバーであるすべてのユーザーを表示するスクリプトです。たとえば、ユーザー A は、Department-staff および Department-director の直接のメンバーです。

グーグルで検索しても、それを実行できるスクリプトを見つけたり書いたりすることができません。

編集:

実際には、ネストにはさらに多くのレイヤーとブランチがあり、多くの部門があるため、混乱が生じます。任意のグループに直接属しているメンバーのリストと、同じグループに間接的に属するメンバーのリストを取得して、冗長なグループの直接メンバーシップを削除したいと考えています。

答え1

以下は、指定された親グループ(名前はGet-ADGroupMember構文と互換性がある必要があります)を調べ、2つのハッシュを作成します。1つのハッシュは、ユーザーのsAMAccountNameをキーとして持ち、直接値としてグループ メンバーシップを指定します。2 番目のハッシュには、処理されたすべてのグループのキーが含まれます。

循環的なグループ ネスト (例: 親が子の子) を正しく検出してスキップします。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 

関連情報