sergey vasin

The IT blog

Вложенные группы Active Directory и PowerShell

leave a comment »

Группы Active Directory используются для множества разных целей, будь то фильтрация групповой политики или назначение определенных привилегий пользователям. Достаточно гибкая структура позволяет разграничивать объекты пользователей и компьютеров наиболее удобным для нас образом.

Но в то же время это приводит к образованию иерархии групп, состоящей из нескольких уровней (что, в общем то, нормально), тем самым затрудняя определение, в какие же именно группы входит определенный пользователь.

Для поиска подобной информации мы можем использовать командлеты модуля ActiveDirectory.

Group

Для получения объекта группы мы используем командлет Get-ADGroup.

Get-ADGroup -Identity somegroup

Для получения непосредственно входящих в нее объектов, будь то пользователь, компьютер или группа — командлет Get-ADGroupMember.

Get-ADGroupMember -Identity somegroup

Для того, чтобы получить список как непосредственных участников группы, так и тех, кто является членом всех вложенных групп, мы можем воспользоваться параметром -Recursive.

Стоит сказать, что использование этого параметра изменяет вывод таким образом, что присутствовать в нем будут только объекты, не имеющие дочерних объектов. То есть информация о вложенных группах среди результатов вывода будет отсутствовать.

Например:

Get-ADGroupMember -Identity somegroup -Recursive

Кроме того, получить список участников группы мы можем, запросив значение атрибута Member:

Get-ADGroup somegroup -Properties Member | Select-Object -ExpandProperty Member

Стоит сказать, что командлет Get-ADGroup добавляет еще один атрибут — Members — равнозначный по содержанию атрибуту Member. Таким образом, если для выполнения запросов к Active Directory вы используете командлеты одноименного модуля, вы можете обращаться к любому из этих двух атрибутов.

Get-ADGroup somegroup -Properties Members | Select-Object -ExpandProperty Members

При использовании других способов, например ADSI, нам будет доступен только атрибут Member.

[ADSI]"LDAP://CN=somegroup,OU=groups,DC=domain,DC=com" | Select-Object -ExpandProperty Member

Также мы можем использовать вид запроса с использованием свойства AttributeScopeQuery объекта DirectorySearcher:

$adsisearcher = New-Object -TypeName System.DirectoryServices.DirectorySearcher
$adsisearcher.SearchRoot = "LDAP://CN=somegroup,OU=groups,DC=domain,DC=com"
$adsisearcher.Filter = "(objectCategory=person)"
$adsisearcher.AttributeScopeQuery = 'Member'
$adsisearcher.FindAll()

Начиная с Windows Server 2012 R2, мы можем получить список всех членов группы, как непосредственных, так и входящих во вложенные группы, обратившись к атрибуту типа constructed — msds-MemberTransitive.

Стоит упомянтуь, что использовать для этого командлет Get-ADGroup не получится. Вместо этого нам понадобится командлет Get-ADObject.

Get-ADObject -Identity "CN=somegroup,OU=groups,DC=domain,DC=com" -Properties msds-MemberTransitive | Select-Object -ExpandProperty msds-MemberTransitive

В этом случае результат запроса будет содержать все входящие в группы объекты — как пользователей и компьютеров, так и других групп.

При помощи ADSI мы можем запросить значение атрибута msds-MemberTransitive следующим образом:

$adsisearcher = New-Object -TypeName System.DirectoryServices.DirectorySearcher
$adsisearcher.SearchRoot = "LDAP://CN=somegroup,OU=groups,DC=domain,DC=com"
$adsisearcher.SearchScope = "Base"
$adsisearcher.PropertiesToLoad.Add("msds-MemberTransitive")
$result = $adsisearcher.FindAll()
$result[0].Properties.'msds-MemberTransitive'

В данном случае нам пришлось явно указать нужную группу в качестве значения свойства SearchRoot, потому что получение значений большинства constructed-атрибутов (кроме таких, как createTimestamp, modifyTimestamp, structuralObjectClass и objectClasses) через ADSI возможно только при SearchScope в значении ‘Base’.

Еще одним способом получения списка всех членов группы, явных или неявных, является использование оператора -RecursiveMatch. Например, так:

Get-ADUser -Filter {MemberOf -RecursiveMatch "CN=somegroup,OU=groups,DC=domain,dc=com"}

Get-ADComputer -Filter {MemberOf -RecursiveMatch "CN=somegroup,OU=groups,DC=domain,dc=com"}

Get-ADObject -Filter {MemberOf -RecursiveMatch "CN=somegroup,OU=groups,DC=domain,dc=com"}

Если же нас интересует только, например, входит ли определенный пользователь в определенную группу, мы можем поступить следующим образом:

Get-ADUser -Filter {MemberOf -RecursiveMatch "CN=somegroup,OU=groups,DC=domain,dc=int"} -SearchBase "CN=someuser,CN=Users,DC=domain,DC=com"

При использовании LDAP, синтаксис немного изменится:

Get-ADUser -LDAPFilter '(MemberOf:1.2.840.113556.1.4.1941:=CN=somegroup,OU=groups,DC=domain,dc=com)'

Get-ADUser -LDAPFilter '(MemberOf:1.2.840.113556.1.4.1941:=CN=somegroup,OU=groups,DC=domain,dc=com)' -SearchBase "CN=someuser,CN=Users,DC=domain,DC=com"

Где 1.2.840.113556.1.4.1941 — это Object ID правила LDAP_MATCHING_RULE_IN_CHAIN, что является LDAP-аналогом оператора -RecursiveMatch.

При использовании ADSI запросы будут выглядеть следующим образом:

$adsisearcher = New-Object -TypeName System.DirectoryServices.DirectorySearcher
$adsisearcher.Filter = "(&(objectCategory=person)(MemberOf:1.2.840.113556.1.4.1941:=CN=TopLevelGroup,OU=groups,DC=domain,dc=int))"
$adsisearcher.FindAll()

$adsisearcher = New-Object -TypeName System.DirectoryServices.DirectorySearcher
$adsisearcher.Filter = "(&(objectCategory=person)(MemberOf:1.2.840.113556.1.4.1941:=CN=TopLevelGroup,OU=groups,DC=domain,dc=int))"
$adsisearcher.SearchRoot = "LDAP://CN=Ivanov Ivan,OU=allusers,DC=domain,DC=int"
$adsisearcher.FindAll()

User

Перейдем теперь к объектам пользователей.

Чтобы получить список групп, в которые непосредственно входит пользователь, мы можем поступить следующим образом:

Get-ADPrincipalGroupMembership -Identity someuser

Если же нам понадобится узнать все группы, в которые он входит посредством вложенных групп, мы можем воспользоваться командлетом Get-ADAccountAuthorizationGroup:

Get-ADAccountAuthorizationGroup -Identity someuser

В данном случае среди результатов будут присутствовать не только созданные вами группы, в которые явно или неявно входит определенный пользователь, но и системные группы, такие, например, как Authenticated Users и This Organization.

По сути, командлет Get-ADAccountAuthorizationGroup выводит все группы, SID которых будет присутствовать в токене безопасности данного пользователя.

Если же нас интересуют только действительно существующие группы, то есть те, членством в которых мы можем управлять явным образом, мы можем отфильтровать результаты по существованию значения атрибута objectClass, поскольку у групп, не присутствующих в Active Directory в виде объектов, оно будет отсутствовать:

Get-ADAccountAuthorizationGroup -Identity someuser | Where-Object objectClass

Точно так же, как и в случае с группами, мы можем обратиться к атрибутам объекта пользователя, чтобы получить информацию о том, членом каких групп он является.

Для получения групп, в которые пользователь входит явным образом, мы можем запросить значение атрибута MemberOf.

Это backlink-атрибут, то есть он не присутствует в ActiveDirectory явно, а является отражением значений других атрибутов — в данном случае атрибута Member.

Get-ADUser -Identity someuser -Properties MemberOf | Select-Object -ExpandProperty MemberOf

На что тут стоит обратить внимание, так это на то, что среди вывода будет отсутствовать одна группа — та, что значится как Primary Group. Обычно это Domain Users для пользователей и Domain Computers для компьютеров.

Текущая primary group объекта определяется значением атрибута primaryGroupID, но об этом отдельно.

Также значение атрибута MemberOf мы можем получить следующими способами:

[ADSI]"LDAP://CN=someuser,CN=Users,DC=domain,DC=com" | Select-Object -ExpandProperty Memberof

или:

$adsisearcher = New-Object -TypeName System.DirectoryServices.DirectorySearcher
$adsisearcher.SearchRoot = "LDAP://CN=someuser,CN=Users,DC=domain,DC=com"
$adsisearcher.Filter = "(objectCategory=group)"
$adsisearcher.AttributeScopeQuery = 'MemberOf'
$adsisearcher.FindAll()

Как и в случае групп, для объектов пользователей и компьютеров, начиная с Windows Server 2012 R2, доступен атрибут типа constructed — msds-MemberOfTransitive.

Его значение содержит все группы, в которые явно или неявно входит объект — но опять же за исключением primary group.

Для получения значения атрибута msds-MemberOfTransitive нам снова понадобится командлет Get-ADObject:

Get-ADObject -Identity "CN=someuser,CN=Users,DC=domain,DC=com" -Properties msds-MemberOfTransitive | Select-Object -ExpandProperty msds-MemberOfTransitive

Еще одним способом будет использование объекта DirectorySearcher:

$adsisearcher = New-Object -TypeName System.DirectoryServices.DirectorySearcher
$adsisearcher.SearchRoot = "LDAP://CN=someuser,CN=Users,DC=domain,DC=com"
$adsisearcher.SearchScope = "Base"
$adsisearcher.PropertiesToLoad.Add("msds-MemberOfTransitive")
$result = $adsisearcher.FindAll()
$result[0].Properties.'msds-memberoftransitive'

Страницы в социальных сетях:

Twitter: https://twitter.com/vsseth
Facebook: https://fb.com/inpowershell
VKontakte: https://vk.com/inpowershell


Реклама

Written by Сергей Васин

Сентябрь 15, 2017 в 14:36

Опубликовано в Active Directory, PowerShell

Добавить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход / Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход / Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход / Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход / Изменить )

Connecting to %s