В статье «Инвентаризация SharePoint с использованием PowerShell» (опубликована в Windows IT Pro/RE № 8 за 2013 год) я рассказывал о том, как использовать Windows PowerShell для инвентаризации объектов SharePoint верхнего уровня. В статье «PowerShell и SharePoint: все о файлах, страницах и веб-частях» (см. №8 за 2013 год) мы рассмотрели, как с помощью сценариев PowerShell получить из SharePoint информацию о списках, библиотеках, файлах и страницах. На этот раз речь пойдет о пользователях, группах и запросах безопасности.

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

Прежде чем начать, я хочу подчеркнуть некоторые моменты.

  • Одна лишь возможность задействовать PowerShell не означает, что можно игнорировать систему защиты SharePoint. В статье «Инвентаризация SharePoint с использованием PowerShell» были описаны основные требования к безопасности. В частности, необходимо по меньшей мере иметь возможность читать разрешения для контента, который предстоит исследовать, и стать членом роли SharePoint_Shell_Access для баз данных, содержащих этот контент. Можно добавить учетную запись, используемую вами для запуска PowerShell в качестве администратора семейства сайтов, к каждому семейству сайтов. Другой вариант: можно задействовать пользовательские политики центра администрирования SharePoint, чтобы назначить своей учетной записи разрешения «Полное чтение» в каждом приложении. Для этого выберите Central Administration («Центр администрирования»), Application Management («Управление приложениями»), укажите приложение и щелкните User Policy («Политика пользователя»).
  • Сценарии PowerShell предназначены для локально выполненной установки SharePoint. Они не работают с Office 365 и SharePoint Online.
  • Выполнение сценариев PowerShell может привести к большой нагрузке на сервер, поэтому их рекомендуется запускать в нерабочее время.

Наконец, следует пояснить различие между пользователями и группами SharePoint. Пользователь SharePoint — человек (например, domain\mike) или группа/роль Active Directory (либо другая группа/роль проверки подлинности). Группа SharePoint представляет собой коллекцию учетных записей пользователей SharePoint. И пользователи, и группы SharePoint связаны с семействами сайтов. Например, можно иметь группу Sales Managers («Менеджеры по продажам») в семействе сайтов HR («Отдел кадров») и группу Sales Managers в семействе сайтов Sales («Продажи»). Группа Sales Managers в семействе сайтов HR — не обязательно такая же, как коллекция пользователей в группе Sales Managers в семействе сайтов Sales.

Учитывая эти особенности, посмотрим, каким образом можно:

  • получить доступ к информации о пользователе;
  • найти группы AD;
  • перечислить все группы SharePoint в семействе сайтов;
  • перечислить всех пользователей в группе SharePoint;
  • перечислить все группы SharePoint, к которым принадлежит пользователь;
  • перечислить всех пользователей в семействе сайтов;
  • перечислить всех владельцев сайтов;
  • перечислить всех администраторов семейства сайтов;
  • перечислить всех пользователей, группы AD и группы SharePoint, имеющие доступ к файлу, папке или элементу списка;
  • найти сайты, библиотеки, папки и документы с уникальными разрешениями;
  • перечислить членов группы AD.

Доступ к информации о пользователе

Иногда бывает необходимо получить доступ к информации о единственном пользователе. Для этого можно применить команду Get-SPUser с параметром –Identity:

Get-SPUser -web http://server/sites/yoursite
-Identity «yourdomain\mike» |
Select ID, UserLogin, DisplayName

Обратите внимание, что параметр -Identity в SharePoint 2013 не всегда работает, как ожидалось, так как свойство UserLogin может отображать простое имя регистрации (domain\mike) или более сложное имя регистрации, содержащее информацию поставщика утверждений (i:0#.w|domain\mike).

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

Get-SPUser -Web http://server/sites/yoursite |
Where { $_.UserLogin -LIKE «*|yourdomain\mike» } |
Select ID, UserLogin, DisplayName

Вы также можете искать пользователей путем фильтрации по свойству DisplayName объекта SPUser:

Get-SPUser -Web http://server/sites/yoursite |
Where { $_.DisplayName -LIKE «*Conklin*» } |
Select ID, UserLogin, DisplayName

В результатах вы увидите поле ID. Оно уникально для пользователя, но только в текущем семействе сайтов. Например, пользователь domain\mike может иметь ID со значением 117 в семействе сайтов HR и ID со значением 12 в семействе сайтов Sales.

Объект SPUser представляет многие свойства помимо DisplayName. В следующих сценариях будут применяться некоторые из них. Список всех свойств приведен на веб-странице свойств SPUser (http://msdn.microsoft.com/en-us/library/office/Microsoft.SharePoint.SPUser_properties(v=office.15).aspx).

Кроме того, можно направить запрос в службы профилей пользователей, чтобы получить дополнительную информацию о каждом из них. Следующая команда получает пользовательское свойство hobbies для пользователя с именем sam. Указанным сайтом может быть любое семейство сайтов в веб-приложении, использующем службу профилей пользователей.

$aSiteCollection = «http://yourdomain/sites/yoursite»;
$serviceContext = Get-SPServiceContext($aSiteCollection);
$profileManager = New-Object Microsoft.Office.Server.UserProfiles.UserProfileManager($serviceContext);
$profileManager.GetUserProfile(«yourdomain\sam»).GetProfileValueCollection(«hobbies»)

Дополнительные примеры можно получить, выполнив поиск в Интернете с ключевой фразой PowerShell UserProfileManager.

Поиск групп AD

В SharePoint группа AD (или другой метод проверки подлинности) является пользователем особого типа. Чтобы найти группы AD, можно фильтровать список пользователей с помощью свойства IsDomainGroup объекта SPUser:

Get-SPUser -Web http://server/sites/yoursite |
Where { $_.IsDomainGroup }

Перечисление всех групп SharePoint в семействе сайтов

Группы SharePoint имеют заданную область, или уникальны для семейства сайтов. Например, группа Sales Managers в семействе сайтов Sales — группа, отличная от Sales Managers в семействе сайтов Training. При перечислении групп из всех семейств сайтов необходимо указывать URL-адрес или имя семейства.

Чтобы получить информацию о группах SharePoint в одном семействе сайтов, можно воспользоваться командой Get-SPSite следующим образом:

Get-SPSite http://server/sites/yoursite |
Select -ExpandProperty RootWeb |
Select -ExpandProperty Groups |
Select {$_.ParentWeb.Url}, Name

Обратите внимание, что вместо Get-SPSite можно задействовать команду Get-SPSiteAdministration, чтобы получить подмножество данных семейства сайтов, которые могут содержать данные о семействах сайтов, к которым у вас нет доступа.

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

Get-SPSite -Limit All |
Select -ExpandProperty RootWeb |
Select -ExpandProperty Groups |
Select {$_.ParentWeb.Url}, Name

Перечисление всех пользователей в группе SharePoint

Вы можете получить список пользователей в группе с помощью команды Get-SPUser или любого свойства, которое возвращает объекты SPGroup. Например, ниже приведена команда, в которой реализован второй вариант:

Get-SPSite http://server/sites/yoursite |
Select -ExpandProperty RootWeb |
Select -ExpandProperty Groups |
Where {$_.Name -EQ «your group name here»} |
Select -ExpandProperty Users |
Select Name, Email

Перечисление всех групп SharePoint, к которым принадлежит пользователь

Чтобы перечислить все группы SharePoint, к которым принадлежит пользователь, нужно сначала найти объект SPUser пользователя:

$user = Get-SPUser -Web http://server/sites/yoursite |
Where {$_.LoginName -LIKE «*|DOMAIN\SAMC»}

Получив этот объект, можно просмотреть все семейства сайтов в ферме и найти все группы, к которым принадлежит пользователь:

Get-SPSite -Limit All |
Select -ExpandProperty RootWeb |
Select -ExpandProperty SiteUsers |
Where { $user.UserLogin -EQ $_.LoginName } |
Select -ExpandProperty Groups |
Select Name, {$_.ParentWeb.Url}

Перечисление всех пользователей в семействе сайтов

Чтобы перечислить всех пользователей в семействе сайтов, можно применить команду Get-SPUser и установить атрибут –Web. Поскольку в выходных данных будут присутствовать как отдельные лица, так и группы AD, можно вставить в выходные данные значение свойства IsDomainGroup или выполнить фильтрацию по этому свойству. Однако члены группы AD, которые никогда не посещали сайта, не будет перечислены. Например, следующая команда выдает в выходных данных значение свойства IsDomainGroup, а также значения свойств UserLogin и DisplayName:

Get-SPUser -Web http://server/sites/yoursite |
Select UserLogin, DisplayName, IsDomainGroup

На экране 1 показаны примеры результатов. Обратите внимание на ID для системной учетной записи. Это фиксированное значение, которое будет одинаковым для всех семейств сайтов. Также обратите внимание на префикс поставщика утверждений на каждом из значений свойства UserLogin.

 

Перечисление всех пользователей в семействе сайтов
Экран 1. Перечисление всех пользователей в семействе сайтов

Перечисление всех владельцев сайтов

Прежде чем перечислить всех владельцев сайтов, уточним определение владельца сайта. Иногда считают, что владелец сайта — это любой пользователь с разрешением Full Control («Полный доступ»), но существует формальная группа владельцев сайтов. Эта группа может быть получена из свойства SPWeb.AssociatedOwnerGroup. Дополнительные сведения о трех связанных свойствах группы (AssociatedOwnerGroup, AssociatedMemberGroup и AssociatedVisitorGroup) можно найти в публикации When is Full Control not Full Control (http://techtrainingnotes.blogspot.com/2014/09/when-is-full-control-not-full-control.html).

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

$web = Get-SPWeb http://server/sites/yoursite
$web.AssociatedOwnerGroup.Users

Чтобы перечислить все группы владельцев сайтов в ферме, воспользуемся командой:

Get-SPSite -Limit All | Get-SPWeb -Limit All |
Where { $_.AssociatedOwnerGroup -Ne $null } |
Select Url, AssociatedOwnerGroup

Чтобы перечислить всех владельцев сайтов в ферме, можно применить команду:

Get-SPSite -Limit All | Get-SPWeb -Limit All |
Where { $_.AssociatedOwnerGroup -Ne $null } |
Select Url, {$_.AssociatedOwnerGroup.Users}

Перечисление всех администраторов коллекции сайтов

Существует три вида администраторов коллекции сайтов: основной администратор семейства сайтов (SPSite.Owner), вторичный администратор семейства сайтов (SPSite.SecondaryContact) и все остальные, имеющие свойство SPUser.IsSiteAdmin, установленное в значение True. Если вы не знакомы с этими тремя типами администраторов семейства сайтов, обратите внимание на мою статью Fun and Games with Site Collection Administrators (http://techtrainingnotes.blogspot.com/2012/12/fun-and-games-with-site-collection.html). Возможно, вас удивят способы их назначения и изменения.

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

Get-SPSite -Limit All | Select Url, Owner, SecondaryContact

Чтобы перечислить администраторов семейства сайтов и их роли, выполните команду:

Get-SPSite -Limit All |
foreach {$Url = $_.Url; $site=$_; $_.RootWeb} |
Select -ExpandProperty SiteUsers |
Where { $_.IsSiteAdmin } |
Select {$Url}, Name,
{$(If($_.UserLogin -Eq $site.Owner.UserLogin) {«Primary Contact»}
Else {
If($_.UserLogin -Eq $site.SecondaryContact.UserLogin) {«Secondary Contact»}
Else {«Other»}
})
}

На экране 2 показаны примеры результатов.

 

Перечисление всех администраторов семейств сайтов и их ролей
Экран 2. Перечисление всех администраторов семейств сайтов и их ролей

Если требуются более удобные для пользователей заголовки столбцов, можно добавить пользовательские столбцы с применением @{ label=«"; expression={} }, как показано ниже:

Get-SPSite -Limit All |
foreach {$Url = $_.Url; $site=$_; $_.RootWeb} |
Select -ExpandProperty SiteUsers |
Where {$_.IsSiteAdmin} |
Select @{label=»Url«; expression={$Url}},
Name,
@{ label=»Admin Role«; expression={
$(If($_.UserLogin -Eq $site.Owner.UserLogin) {»Primary Contact«}
Else {
If($_.UserLogin -Eq $site.SecondaryContact.UserLogin) {»Secondary Contact«}
Else {»Other«}
})
} }

На экране 3 показаны результаты с новыми заголовками столбцов.

 

Перечисление всех администраторов семейств сайтов и их ролей
Экран 3. Перечисление всех администраторов семейств сайтов и их ролей

Администраторы семейства и их роли

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

$web = Get-SPWeb http://server/sites/yoursite
$web.GetFile(»Shared Documents/Training Schedule.docx«) |
Select -ExpandProperty ListItemAllFields |
Select -ExpandProperty RoleAssignments |
Select {$_.Member.DisplayName}, {$_.Member.LoginName}, RoleDefinitionBindings

Как можно заметить, в выходные данные входит свойство RoleDefinitionBindings, содержащее уровни разрешений SharePoint, назначенные пользователю или группе. Примеры результатов на экране 4 показывают, что эта команда не развертывает группы AD или группы SharePoint для перечисления членов групп.

 

Перечисление всех пользователей, групп AD и групп SharePoint, имеющих доступ к файлу или папке
Экран 4. Перечисление всех пользователей, групп AD и групп SharePoint, имеющих доступ к файлу или папке

Сценарий для перечисления всех пользователей, групп AD и групп SharePoint с доступом к элементу списка аналогичен приведенному сценарию, единственное отличие — в нем указан один элемент списка. Для указания элемента списка можно использовать такой сценарий:

$web = Get-SPWeb http://server/sites/yoursite
$web.lists[»Bikes«].items[0] | Select -ExpandProperty RoleAssignments |
Select {$_.Member.DisplayName}, {$_.Member.LoginName}, RoleDefinitionBindings

Вы можете выбрать элемент»nth«как сделано в этом сценарии (.items[0]) или добавить фильтр Where-Object, чтобы выбрать элемент списка.

Поиск всех сайтов, библиотек, папок и документов с уникальными разрешениями

В SharePoint существует лишь несколько типов защищаемых объектов: сайты, списки, библиотеки, папки, элементы списка и элементы библиотеки. Чтобы убедиться в наличии у защищаемого объекта уникальных разрешений, можно проверить свойство HasUniquePerm для сайтов и свойство HasUniqueRoleAssignments для всех других типов защищаемых объектов. Для сайтов также необходимо проверить, принадлежат ли они к верхнему уровню, потому что сайты верхнего уровня всегда имеют уникальные разрешения и должны быть исключены из списка broken inheritance. Инструкция Where для исключения сайтов верхнего уровня выглядит следующим образом:

Where { $_.HasUniquePerm -AND $_.ParentWeb -NE $Null }

Для списков и библиотек полезно еще исключить скрытые списки. В данном случае инструкция Where выглядит так:

Where { $_.HasUniqueRoleAssignments -AND -NOT $_.Hidden }

Команда для проверки различных типов защищаемых объектов сравнительно проста. Чтобы найти все сайты с уникальными разрешениями в семействе сайтов, можно выполнить команду:

Get-SPSite http://yourSiteUrl |
Get-SPWeb -Limit All |
Where { $_.HasUniquePerm -AND $_.ParentWeb -NE $Null } |
Select ServerRelativeUrl

Чтобы найти все списки и библиотеки с уникальными разрешениями в семействе сайтов, можно воспользоваться командой:

Get-SPSite http://yourSiteUrl |
Get-SPWeb -Limit All |
Select -ExpandProperty Lists |
Where { $_.HasUniqueRoleAssignments -AND -NOT $_.Hidden } |
Select Title, ParentWebUrl

Для поиска всех папок с уникальными разрешениями в семействе сайтов можно применить команду:

Get-SPSite http://yourSiteUrl |
Get-SPWeb -Limit All |
Select -ExpandProperty Lists |
Select -ExpandProperty Folders |
Where { $_.HasUniqueRoleAssignments } |
Select {$_.ParentList.ParentWebUrl +»/«+ $_.ParentList.Title +»/«+$_.DisplayName}

Чтобы найти все элементы списков и библиотек с уникальными разрешениями в семействе сайтов, можно использовать команду:

Get-SPSite http://yourSiteUrl |
Get-SPWeb -Limit All |
Select -ExpandProperty Lists |
Select -ExpandProperty Items |
Where { $_.HasUniqueRoleAssignments } |
Select Name, {$_.ParentList.ParentWebUrl +»/«+ $_.ParentList.Title}

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

Если вы хотите объединить команды в один сценарий и выводить результаты в одном отчете, придется обрабатывать другие столбцы и типы данных, а затем сортировать результаты. Можно сформировать массив для хранения всего содержимого, а затем сортировать его, но он может оказаться очень большим. Лучше воспользоваться преимуществами команды Export-CSV из PowerShell 3.0, чтобы объединить все коллекции данных в один файл, а затем прочитать этот файл и сортировать содержимое.

Сценарий в листинге 1 немного сложен, но если разделить его на части, то можно увидеть четыре команды, приведенные рядом с пользовательскими столбцами ( @{Label=»…«; Expression={…}} ), служащие для формирования соответствующего вывода для каждого списка объектов. Сценарий изменяет вывод каждой команды, чтобы получить совместимые столбцы (Securable, Item и Parent).

Перечисление членов группы AD

Как отмечалось выше, учетная запись пользователя SharePoint сопоставлена человеку (domain\mike) или группе AD. До этого этапа команды просто перечисляли группы AD и не развертывали их для перечисления членов групп AD. В состав единственной группы AD могут входить тысячи членов. Модуль PowerShell в SharePoint не содержит команды для управления пользователями и группами AD, но существует модуль AD. Дополнительные сведения можно получить на веб-странице Active Directory Administration with Windows PowerShell (http://technet.microsoft.com/en-us/library/dd378937(WS.10).aspx).

В PowerShell 2.0 необходимо загрузить модуль AD с использованием команды

Import-Module -Name activedirectory

PowerShell 3.0 обнаружит модуль AD, если он присутствует на сервере. В качестве теста можно опробовать следующие две команды, которые отыскивают группы AD и пользователей в группе:

Get-ADGroup -Filter * | Select Name
Get-ADGroupMember -Identity Sales | Select Name

В листинге 2 приведен сценарий, который развертывает группу AD, показывая ее членов. До этого в большинстве представленных фрагментов сценария использовались однострочные команды на основе конвейеров PowerShell. Данный сценарий использует программный стиль с инструкциями foreach и if/else. Его можно скопировать в оболочку PowerShell, но проще всего работать с интегрированной средой сценариев PowerShell (ISE) и редактором PowerShell стороннего поставщика.

На экране 5 показаны примеры результатов. В этом случае в группе SharePoint с именем Demo3 Members насчитывается три пользователя: одна группа AD с именем Sales и два пользователя с именами Robert и Sam. В группу AD с именем Sales входят три пользователя с именами named Stella, Richard и Susan. Таким образом, развернув группу AD, можно увидеть, что в группе Demo3 Members на сайте действительно пять человек.

 

Развертывание группы AD для ?просмотра ее?членов
Экран 5. Развертывание группы AD для просмотра ее членов

От инвентаризации к безопасности

Итак, мы рассмотрели, как получить информацию о пользователях, группах, владельцах сайтов и администраторах семейств сайтов. Кроме того, я рассказал о том, как запускать запросы безопасности, чтобы выяснить, к каким файлам, папкам и элементам списков имеют доступ пользователи, группы AD и группы SharePoint. И, наконец, мы выяснили, как с помощью PowerShell узнать, имеются ли у нас сайты, библиотеки, папки и документы с уникальными разрешениями.

Листинг 1. Сценарий поиска всех сайтов, библиотек, папок и документов с уникальными разрешениями

# Specify the site collection.
$siteUrl =»http://urlToYourSite«
# Specify the output file.
$savePath =»c:\test\BrokenInheritanceReport.csv«
# Get the sites with unique permissions.
Get-SPSite $siteUrl |
Get-SPWeb -Limit All |
Where { $_.HasUniquePerm -AND $_.ParentWeb -NE $Null } |
Select @{Label=»Securable«; Expression={»Web«}},
@{Label=»Item«; Expression={$_.ServerRelativeUrl}},
@{Label=»Parent«; Expression={$_.ParentWeb.ServerRelativeUrl}} |
Export-CSV $savePath
# Get the lists and libraries with unique permissions.
Get-SPSite $siteUrl |
Get-SPWeb -Limit All |
Select -ExpandProperty Lists |
Where { $_.HasUniqueRoleAssignments -AND -NOT $_.Hidden } |
Select @{Label=»Securable«; Expression={»List«}},
@{Label=»Item«; Expression={$_.Title}},
@{Label=»Parent«; Expression={$_.ParentWebUrl}} |
Export-CSV $savePath -Append
# Get the folders with unique permissions.
Get-SPSite $siteUrl |
Get-SPWeb -Limit All |
Select -ExpandProperty Lists |
Where { -NOT $_.Hidden -AND $_.EntityTypeName -NE»PublishedFeedList«} |
Select -ExpandProperty Folders |
Where { $_.HasUniqueRoleAssignments } |
Select @{Label=»Securable«; Expression={»Folder«}},
@{Label=»Item«; Expression={$_.Title}},
@{Label=»Parent«; Expression={$_.ParentList.ParentWebUrl +»/«+$_.ParentList.Title}} |
Export-CSV $savePath -Append
# Get the list items and library files with unique permissions.
Get-SPSite $siteUrl |
Get-SPWeb -Limit All |
Select -ExpandProperty Lists |
Where { -NOT $_.Hidden -AND $_.EntityTypeName -NE»PublishedFeedList«} |
Select -ExpandProperty Items |
Where { $_.HasUniqueRoleAssignments } |
Select @{Label=»Securable«; Expression={»Item«}},
@{Label=»Item«; Expression={$_.Name}},
@{Label=»Parent«; Expression={$_.ParentList.ParentWebUrl +»/«+$_.ParentList.Title}} |
Export-CSV $savePath -Append
Import-CSV $savePath | Sort Parent | Select *
# or open the BrokenInheritanceReport.csv file in Excel and sort there.

Листинг 2. Сценарий для просмотра членов группы AD

$site = Get-SPSite http://server/sites/yoursite
$groups = $site.RootWeb.SiteGroups
foreach ($grp in $groups)
{
»SP Group: «+ $grp.Name;
foreach ($user in $grp.Users)
{
if ($user.IsDomainGroup -eq $False)
{
» User: «+ $user.Name
}
else
{
» AD group: «+$user.Name
$adusers={}
$adusers = Get-ADGroupMember -Identity $user.name.split(»\«)[1]
foreach ($aduser in $adusers)
{
» AD User: " + $aduser.Name
}
}
}
}