Найти отношение пользователя и группы AD через вложенные группы AD

По сути, в нашей среде у нас есть масса групп безопасности. Группы безопасности, которые вложены в другие группы и т. д. Таким образом, это настоящая 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

Это отлично работает, но, похоже, выводит каждую группу безопасности, в отличие от подключающихся. Хотя, конечно, шаг в правильном направлении! Если я найду источник, я также опубликую кредит.


person user3317623    schedule 17.02.2014    source источник
comment
Я отредактировал свой пост выше, указав в основном решение, которое нуждается в некоторой доработке!   -  person user3317623    schedule 17.02.2014


Ответы (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

Обратите внимание, что этот метод вернет первое найденное соединение между пользователем и группой. Если, например, группа «Некоторая другая группа» также будет членом «Подподгруппы», это не изменит ни вывод, ни процесс поиска, упомянутый выше.

person Robert Westerlund    schedule 17.02.2014
comment
Спасибо за отличный пост :). - person user3317623; 19.02.2014