检查用户是否是一组AD组的成员。

5
$groups = 'group1', 'group2'....

我需要检查用户是否在特定的AD组中,并在他不在该组中时输出组名;我可以在管道中完成吗?

我已经进行了大量谷歌搜索,但没有找到任何信息,也许是因为我在使用英文进行谷歌搜索方面太差了 :).

$groups |
    Get-QADGroupMember |
    Get-QADUser -SamAccountName 'lalala' | ForEach-Object {
        if ($_.SamAccountName -ne $null) {
            Write-Host "ok"
        } else {
            Write-Host 'not ok'
        }
    }

我该如何显示:not ok. user is not ingroup_name

你有一个群组列表。用户应该是其中的哪一个成员?任何一个?全部?特定的一个?还是没有?此外,我建议从另一端开始:获取用户所属的群组,然后检查列表是否包含相关群组。 - Ansgar Wiechers
这里只是一个反问,理想情况下,一个组通常包含的成员比单个用户多。那么,这样说来,获取每个用户的组并检查他是否是某个组的成员比反过来做更快吗?只是问一下... :) - sk8er_boi47
4个回答

6

问题是为什么你想要使用管道,而只需通过结果进行循环就如此简单呢?

要检查用户是否是一组列表的成员:

$user = "TestUsername"
$groups = 'Domain Users', 'Domain Admins'

foreach ($group in $groups) {
    $members = Get-ADGroupMember -Identity $group -Recursive | Select -ExpandProperty SamAccountName

    If ($members -contains $user) {
        Write-Host "$user is a member of $group"
    } Else {
        Write-Host "$user is not a member of $group"
    }
}

而且针对多个用户:

看起来这个问题受到了很多关注,所以我更新了我的答案以解决原始版本的明显问题。这不是一个模范答案,也不是最高效的方法,但可以实现目标。

$users = "TestUsername1", "TestUsername2", "TestUsername3"
$groups = 'Domain Users', 'Domain Admins'

foreach ($group in $groups) {
    $members = Get-ADGroupMember -Identity $group -Recursive | Select -ExpandProperty SamAccountName

    foreach ($user in $users) {
        If ($members -contains $user) {
            Write-Host "$user is a member of $group"
        } Else {
            Write-Host "$user is not a member of $group"
        }
    }
}

1
我遇到了错误“Get-ADGroupMember”不被识别为cmdlet的名称。我需要导入哪个模块才能使其工作? -编辑- 在https://dev59.com/CGMm5IYBdhLWcg3whfWe#17548616找到了答案。 - deadlydog
@PSaR 虽然您的编辑是有建设性的,但它更适合作为一个单独的答案。这是我以前的一个旧答案,我现在也不会再这样做了,因为它并不那么高效。 - henrycarteruk
这似乎是对 Get-ADGroupMember 的许多不必要的查询 - 每次移动到一个新的用户名时,您都会提取所有组的成员,理论上可能有数千个人对象。如果您先循环遍历组,然后检查它们是否包含用户,将大大提高性能并减少运行时间。 - user520100

0
如果您的服务器上没有安装Active Directory PowerShell功能,则可以使用此方法。在这里,我正在检查域组是否是服务器上本地管理员组的一部分,但是如果您想要检查用户是否属于某个组,请仅更改GroupPrincipalUserPrincipal并提供用户名即可。另外,如果该组是域组,则对于两个FindByIdentity调用都使用$domainContext
function Test-DomainGroupIsMemberOfLocalAdministrators([string] $domainName, [string] $domainGroupName)
{
    Add-Type -AssemblyName 'System.DirectoryServices.AccountManagement'
    $domainContext = [System.DirectoryServices.AccountManagement.PrincipalContext]::new([System.DirectoryServices.AccountManagement.ContextType]::Domain, $domainName)
    $localMachineContext = [System.DirectoryServices.AccountManagement.PrincipalContext]::new([System.DirectoryServices.AccountManagement.ContextType]::Machine)
    $domainGroup = [System.DirectoryServices.AccountManagement.GroupPrincipal]::FindByIdentity($domainContext, $domainGroupName)
    $localAdministratorsGroup = [System.DirectoryServices.AccountManagement.GroupPrincipal]::FindByIdentity($localMachineContext, "Administrators")

    if($domainGroup -ne $null)
    {
        if ($domainGroup.IsMemberOf($localAdministratorsGroup))
        {
            return $true
        }
    }
    return $false
}

0

@henrycarteruk的回答是否真的是实现这个目标的最佳方法?让我们举个例子:

我有一个包含50个组的列表,我想检查用户是否是每个组的成员。

根据这个例子:

  • 我必须获取每个组的成员列表
  • 我必须检查每个列表是否包含我的用户登录
  • 编写答案

我看到的问题:

  • 组可以有很多用户
  • 我可能有很多组要检查用户是否是成员

我进行了快速测试:

  1. 我的用户有180个组
  2. 我想检查他是否是10个组的成员 我花了大约20秒钟

我的方法如下。

拥有您想要检查的组列表,但您需要整个组的DN。

$list = 'CN=Administrators,CN=Builtin,DC=Fabrikam,DC=com','CN=Administrators,CN=Builtin,DC=Fabrikam,DC=com','CN=Administrators,CN=Builtin,DC=Fabrikam,DC=com'

获取用户组:
$user_groups = (Get-ADUser $login -Properties memberof | Select-Object memberof).memberof

检查用户属于哪些组:

foreach($group2 in $list){
        if($user_groups.Contains($group2)){
            Write-Host "$login is member of $group2"
        }else{
           Write-Host "$login is not a member of $group2"
        }
    }

0
提供的答案可以适用于手头的任务,但并不提供最有效的方法,实际上是LDAP 完成其工作,而不是使用 PowerShell 进行过滤。
$groupsFilter = ''
# assuming we have the Group's SamAccountName
# create a filter clause for each group
'group1', 'group2', '...' | ForEach-Object {
   $groupsFilter += '(samAccountName={0})' -f $_
}

# We need the user's DistinguishedName
# to perform the Member Attribute filtering
$userDN = (Get-ADUser theUser).DistinguishedName

$filter = -join @(
   '(&'                          # AND, all conditions must be met
      '(!member={0})' -f $userDN # The user is NOT a member
      '(|'                       # OR, any of the conditions must be met
         $groupsFilter           # Follow with the filter for any of the groups
      ')'                        # Close OR clause
   ')'                           # Close AND clause
)

# Now with the constructed filter we can search for any group
# which's samAccountName is one of those in the array of Groups
# AND the target user IS NOT a Member of
Get-ADGroup -LDAPFilter $filter

如果我们想要找到那些用户不是“递归成员”的组,换句话说,用户不是该组或任何嵌套组的成员,我们只需要将“(!member=...)”子句更改为使用“LDAP_MATCHING_RULE_IN_CHAIN”即可。
'(!member:1.2.840.113556.1.4.1941:={0})' -f $userDN # The user is NOT a recursive member

为了参考,构建的LDAP过滤器将如下所示:
(&
   (!member=CN=someuser,OU=someOU,DC=someDomain)
   (|
      (samAccountName=group1)
      (samAccountName=group2)
      (samAccountName=group3)
   )
)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接