使用 Powershell 获取所有 AD 用户的递归组成员身份

问题描述 投票:0回答:6

我正在尝试制作一个 PS 脚本,它将列出所有 Active Directory 用户组成员身份(递归)。

我已经有了工作脚本:

import-module activedirectory

$users = get-aduser -Filter {Name -Like "*"} -Searchbase "ou=Users, dc=Domain" | Where-Object { $_.Enabled -eq 'True' } 

$targetFile = "D:\users.csv"
rm $targetFile
Add-Content $targetFile "User;Group"


foreach ($user in $users)
{
    $groups = Get-ADPrincipalGroupMembership $user

    foreach ($group in $groups)
    {
        $username = $user.samaccountname
        $groupname = $group.name
        $line = "$username;$groupname"
        Add-Content $targetFile $line
    }
}

但是脚本不会递归地列出组,即,如果输出文件中列出的组是另一个组的一部分。

示例:

组1:用户

组2:组3:用户

脚本仅显示 Group1 和 3,但不显示 2。

我应该在第一个以递归方式写入组成员身份的脚本中添加什么?

powershell recursion membership active-directory-group
6个回答
6
投票

抱歉,我正在发布 3 年前问题的答案,但如果有人会看到它,它会有所帮助。
归功于:
如何使用Powershell或其他工具(递归)获取所有AD用户组?

您可以使用 LDAP_MATCHING_RULE_IN_CHAIN

Get-ADGroup -LDAPFilter "(member:1.2.840.113556.1.4.1941:=CN=User,CN=USers,DC=x)"

您可以在任何可以使用 LDAP 过滤器的地方使用它。

示例:

$username = 'myUsername'
$dn = (Get-ADUser $username).DistinguishedName
Get-ADGroup -LDAPFilter ("(member:1.2.840.113556.1.4.1941:={0})" -f $dn) | select -expand Name | sort Name  

修复您的脚本:

import-module activedirectory

$users = get-aduser -Filter {Name -Like "*"} -Searchbase "ou=Users, dc=Domain" | Where-Object { $_.Enabled -eq 'True' } 

$targetFile = "D:\users.csv"
rm $targetFile
Add-Content $targetFile "User;Group"

foreach ($user in $users)
{
$dn = $user.DistinguishedName
    $groups = Get-ADGroup -LDAPFilter ("(member:1.2.840.113556.1.4.1941:={0})" -f $dn) | select -expand Name | sort Name

    foreach ($group in $groups)
    {
        $username = $user.samaccountname
        $groupname = $group.name
        $line = "$username;$groupname"
        Add-Content $targetFile $line
    }
}

2
投票

如果将其设为函数,则可以递归调用它。看看这个,我想你会对结果感到满意:

Function Get-ADGroupsRecursive{
Param([String[]]$Groups)
    Begin{
        $Results = @()
    }
    Process{
        ForEach($Group in $Groups){
            $Results+=$Group
            ForEach($Object in (Get-ADGroupMember $Group|?{$_.objectClass -eq "Group"})){
                $Results += Get-ADGroupsRecursive $Object
            }
        }
    }
    End{
        $Results | Select -Unique
    }
}

将其放在脚本的顶部,然后为每个用户调用它。比如:

import-module activedirectory

$users = get-aduser -Filter {Name -Like "*"} -Searchbase "ou=Users, dc=Domain" -Properties MemberOf | Where-Object { $_.Enabled -eq 'True' } 

$targetFile = "D:\users.csv"
rm $targetFile
Add-Content $targetFile "User;Group"


foreach ($user in $users)
{
    $Groups = $User.MemberOf
    $Groups += $Groups | %{Get-ADGroupsRecursive $_}
$Groups | %{New-Object PSObject -Property @{User=$User;Group=$_}}|Export-CSV $targetfile -notype -append
}

现在,根据您的广告结构的大小,这可能需要相当长的时间,但它会给您带来您想要的东西。


2
投票

较新版本的 PowerShell(AD 模块)确实有 -Recursive 开关。因此您可以轻松使用Get-ADGroupMember

示例:Get-ADGroupMember -Identity My_Group -Recursive


1
投票

这很容易。只需使用Active Directory 的 ActiveRoles Management Shell。带有参数 Indirect 的 Cmdlet Get-QADMemberOf 就是您要寻找的。示例:

Get-QADMemberOf john.smith -Indirect


1
投票

返回的 Quest 对象已在属性中包含所有递归组(和第一级用户)

$_.AllMembers

Add-PSSnapin Quest.ActiveRoles.ADManagement
$UsersFirstLevel = ($Members | Get-QADObject -Type Group -DontUseDefaultIncludedProperties | Get-QADGroupMember -DontUseDefaultIncludedProperties | ?{$_.type -eq 'user'})
$UsersSubGroup = ($Members | Get-QADObject -Type Group -DontUseDefaultIncludedProperties | Get-QADGroupMember -DontUseDefaultIncludedProperties | ?{$_.type -eq 'group'}).Allmembers | Get-QADObject -DontUseDefaultIncludedProperties | ?{$_.type -eq 'user'}

$RecursiveUsers = $UsersFirstLevel
$RecursiveUsers += $UsersSubGroup
$RecursiveUsers = $RecursiveUsers | Sort-Object -Unique

0
投票

我有一些对我有用的东西要补充。不太漂亮,但完成了工作,输入组的 txt 文件进行检查。如果有很多组,可以以更有用的方式导出。

$groups = Get-Content -Path 'C:\Export\groups.txt'

function CheckAccount($accountinquestion) {
    if($accountinquestion.objectClass -like 'group'){
        $members = get-adgroupmember $member.name | select name, objectClass
        foreach($member in $members){
            if($member.objectClass -like 'group'){
                CheckAccount($member.name)
            }
            else{write-host $member.name $member.objectClass}
        }
    }
}

foreach($group in $groups){
    $members = get-adgroupmember $group | select name, objectClass
    write-host "--------------------"
    write-host $group
    write-host "--------------------"
    foreach($member in $members){
        if($member.objectClass -like 'group'){
            CheckAccount($member.name)
        }
        else{write-host $member.name $member.objectClass}
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.