【问题标题】:Find user and AD group relation via nested AD groups通过嵌套的 AD 组查找用户和 AD 组的关系
【发布时间】:2014-02-17 04:18:59
【问题描述】:

基本上,在我们的环境中,我们有大量的安全组。嵌套在其他组等中的安全组。因此,找出为什么将设置应用于用户是一个真正的 PITA,因为它们可能属于也可能不属于其中的一个嵌套组

例如如果您将用户添加到组 X,他们会突然在 Citrix 中拥有一个已发布的应用程序。 Citrix 为安全组 Y 配置。尝试查找 X 和 Y 之间的链接非常耗时,但可以自动化。

我想创建一个脚本,在其中输入用户和最终安全组(上面的组 Y),脚本输出将用户连接到最终组的中间组。如果这有意义?

类似这样的:

function get-grouprelationship($username, $knownsecuritygroup)
{
    $getallgroups = get-adgroupmember $knownsecuritygroup | where-object {$_.ObjectClass -eq "Group" | select-object SamAccountName | foreach-object {get-adgroupmember $_.SamAccountName}
}

(上面的变量获取你的组,并遍历该组的所有成员,打印他们的成员)

$usergroups = (get-aduser -identity $username -Properties memberof | select-object memberof).memberof

(上面获取用户所在的所有组)

$usergroups1 = $usergroups.split(",")
$usergroups2 = $usergroups1[0]
$usergroups3 = $usergroups2.substring(3)

(上面的文本格式很好)

if ($usergroups3 -contains $groupname){write-host "$username is directly in $groupname}

从这里开始,我被困住了,因为我基本上需要嵌套多个 for 循环,具体取决于每个组中有多少组。然后做一个条件检查

if ($groupname -eq $currentgroup){write-host "connected by $groupname and $currentgroup}

我也坚持使用 $getallgroups 变量,因为它只检查 1 级。然后它需要另一个 foreach 循环在里面,这将需要另一个循环等等。

之前没有编码经验,我真的很难想出一个简单的方法来实现我的目标。

编辑:

我在这里找到了这个脚本 - script。下面基本上是有效的,除了它是冗长的方式:

import-module activedirectory
$username = read-host "What's their username?"
Function RecurseUsersInGroup {
    Param ([string]$object = "", [int]$level = 0)
    $indent = "-" * $level

    $x = Get-ADObject -Identity $object -Properties SamAccountName

    if ($x.ObjectClass -eq "group") {
        Write-Host "# $($x.SamAccountName)"

        $y = Get-ADGroup -Identity $object -Properties Members

        $y.Members | %{
            $o = Get-ADObject -Identity $_ -Properties SamAccountName

            if ($o.ObjectClass -eq "user" -and $o.SamAccountName -eq $username) {
                Write-Host "-> $($o.SamAccountName)"
            } elseif ($o.ObjectClass -eq "group") {
                RecurseUsersInGroup $o.DistinguishedName ($level + 1)
            }
        }
    } else {
        Write-Host "$($object) is not a group, it is a $($x.ObjectClass)"
    }
}
$thegroup = read-host "What's the Group?"
RecurseUsersInGroup (get-adgroup $thegroup).DistinguishedName

这工作正常,但似乎输出每个安全组,反对连接的。当然,这是朝着正确方向迈出的一步!如果我找到来源,我也会发布信用。

【问题讨论】:

  • 我编辑了我上面的帖子,基本上是一个需要修改的解决方案!

标签: powershell security active-directory nested active-directory-group


【解决方案1】:

下面的版本不那么冗长(可能写得更简洁,但我希望脚本至少是半可读的),但它会搜索组并返回 Active Directory 组对象沿着找到该组的分支的每个组。

function Get-GroupConnection
{
    [CmdletBinding()]
    PARAM (
        $Username,
        $GroupName
    )

    $User = Get-AdUser -Identity $Username -Properties MemberOf
    if (-Not ($User))
    {
        return;
    }

    $SearchedGroups = @()

    function Find-GroupBranches
    {
        [CmdletBinding()]
        PARAM (
            $GroupNameList,
            $SearchForGroupName
        )

        $ADGroups = $GroupNameList | Foreach { Get-ADGroup -Identity $_ -Properties MemberOf }

        foreach($group in $ADGroups)
        {
            Write-Verbose "Testing if either '$($Group.SamAccountName)' or '$($Group.DistinguishedName)' are equal to '$SearchForGroupName'"
            if ($Group.SamAccountName -eq $SearchForGroupName -OR $Group.DistinguishedName -eq $SearchForGroupName)
            {
                Write-Verbose "Found $($Group.DistinguishedName)"
                Write-Output $Group
                return
            }
        }

        Write-Verbose "No match in current collection, checking children"
        foreach ($currentGroup in $ADGroups)
        {
            if ($SearchedGroups -Contains $currentGroup.DistinguishedName)
            {
                Write-Verbose "Already checked children of '$($currentGroup.DistinguishedName)', ignoring it to avoid endless loops"
                continue
            }
            $SearchedGroups += $currentGroup.DistinguishedName

            if ($currentGroup.MemberOf)
            {
                Write-Verbose "Checking groups which $($currentGroup.DistinguishedName) is member of"

                $foundGroupInTree = Find-GroupBranches -GroupNameList $currentGroup.MemberOf -SearchForGroupName $SearchForGroupName
                if ($foundGroupInTree)
                {
                    Write-Output $currentGroup
                    Write-Output $foundGroupInTree
                    break
                }
            }
            else
            {
                Write-Verbose "$($currentGroup.DistinguishedName) is not member of any group, branch ignored"
            }
        }
    }

    Write-Verbose "Searching immediate group membership"
    Find-GroupBranches -GroupNameList $User.MemberOf -SearchForGroupName $GroupName
}

Get-GroupConnection -Username MyUser -GroupName SubSubGroup -Verbose

下面是它如何搜索的描述。

鉴于以下 Active Directory 结构:

MyUser
    Domain Admins
        AnotherSubGroup
    Other Group
    DirectMemberGroup
        Domain Admins (same group as MyUser is direct member of, above)
            AnotherSubGroup (which is of course the same as above too)
        SubGroup
            SubSubGroup
    Some Other Group

如果我们搜索 MyUser 和“SubSubGroup”之间的连接,脚本将首先搜索 MyUser 用户的直接成员身份,即“域管理员”、“其他组”、“DirectMemberGroup”和“其他组”。这些都不匹配我们搜索的“SubSubGroup”,因此它开始检查“子”组。

“域管理员”是“AnotherSubGroup”的成员,但与“SubSubGroup”不匹配。 'AnotherSubGroup' 不是任何组的成员,因此忽略该分支。

“其他组”不是任何组的成员,因此忽略该分支。

'DirectMemberGroup' 是其他组的成员,因此它会遍历这些组。它已经为孩子检查了“域管理员”,因此跳过该组以避免陷入循环搜索。因此它检查“子组”。

'SubGroup' 与 'SubSubGroup' 不匹配,因此它会检查 'SubGroup' 所属的组。 'SubGroup' 是 'SubSubGroup' 的成员,因此它会检查该组。

“SubSubGroup”确实匹配“SubSubGroup”,因此将被选为匹配项。

在上面的示例中,输出组对象将是指向“SubSubGroup”组的分支,按以下顺序:

DirectMemberGroup
SubGroup
SubSubGroup

请注意,此方法将返回它在用户和组之间找到的第一个连接。例如,如果“Some Other Group”组也是“SubSubGroup”的成员,这不会改变输出,也不会改变上面提到的搜索过程。

【讨论】:

  • 感谢您的精彩帖子:)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多