Исправляем имя доменной группы в SharePoint 2013 после переименования в Active Directory

SharePoint Server AD Group Sync В SharePoint Server 2013 есть проблема, которая тянется с предыдущих версий SharePoint. Суть её заключается в том, что информация о той или иной доменной группе безопасности, единожды попав в SharePoint из каталога Active Directory, не обновляется в SharePoint в дальнейшем. И если в последствии в Active Directory группа безопасности будет переименована, то получится так, что на всех веб-узлах SharePoint эта группа останется со старым именем, что в некоторых ситуациях может привести к путанице. В этой заметке мы рассмотрим действия, которые можно предпринять на стороне SharePoint Server для актуализации информации об именах групп безопасности.

Рассмотрим пример, в котором изначально созданная в домене группа безопасности с именем "KOM\My-Group-Old-Name" и попавшая с этим именем в SharePoint, была через некоторое время переименована в Active Directory в "KOM\My-Group-New-Name".

SharePoint Server AD Group UnSync

При этом SID группы, разумеется, остался прежним "s-1-5-21-2955499624-4996244754-1486499624-289425". Чтобы быстро получить SID доменной группы безопасности для сверки с тем, что мы видим в поле "Учётная запись" на узле SharePoint можем выполнить команду PowerShell:

Get-ADGroup "My-Group-New-Name" | Select SID

PowerShell Get AD group SID

Теперь, убедившись в том, что речь идёт об одной и той же группе безопасности, чтобы обновить на стороне SharePoint Server информацию об имени группы выполним пару действий.

Для начала обновим информацию в механизме "People Picker", который используется в SharePoint в тех местах, где требуется выбор пользователей или групп безопасности. Для этого на сервере SharePoint откроем командную строку с правами Администратора, перейдём в каталог исполняемых файлов и выполним смену имени с помощью утилиты stsadm.

cd /d "C:\Program Files\Common Files\microsoft shared\Web Server Extensions\15\BIN\"
stsadm -o migrategroup -oldlogin 'KOM\My-Group-Old-Name' -newlogin 'KOM\My-Group-New-Name'

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

SharePoint stsadm migrategroup

Вообще замечено, что информация в "People Picker" без выполнения вышеуказанной команды обновляется автоматически через некоторое время, но в некоторых случаях по какой-то невыясненной причине она остаётся устаревшей, поэтому выполнение данной команды может форсировать процесс обновления.

После выполнения команды проверим то, как группа отображается в диалоговой форме поиска "People Picker". Теперь группа с новым именем должна успешно обнаруживаться, а поиск старого имени группы, напротив, – не должен давать результатов.

SharePoint Server People Picker Sync from AD

Опять же, если результата выполнения команды не видно сразу, стоит подождать 10-15 минут и после попытаться снова выполнить проверку.

После того, как изменения отразились в "People Picker", нам остаётся обновить информацию на всех сайтах SharePoint, на каждом их которых есть скрытый системный список siteusers, в котором хранится информация о пользователях и группах.

Для этого на сервере SharePoint откроем консоль "SharePoint 2013 Management Shell" и выполним следующий скрипто-блок:

$login = "c:0+.w|s-1-5-21-2955499624-4996244754-1486499624-280536"
$title = "KOM\my-group-new-name"
Get-SPSite -Limit all | % {$domainGroup = $_.OpenWeb().SiteUsers[$login]; if ($domainGroup -ne $null) {$domainGroup.DisplayName=$title; $domainGroup.Update()}}

SharePoint Server 2013 Shell Sync AD group name

Теперь проверяем информацию об имени группы на примере какого-нибудь сайта по ссылке типа http://{адрес сайта}/_layouts/15/userdisp.aspx?ID={идентификатор группы}SharePoint Server AD Group Sync with new name

Таким образом мы обновили имя одной конкретной доменной группы безопасности в SharePoint. Если же ситуация с количеством доменных групп с изменёнными именами более серьёзная и администратору SharePoint не известны все когда-либо переименованные в Active Directory группы можно попробовать воспользоваться ниже представленным скриптом PowerShell.

За основу был взят скрипт из статьи How to change SharePoint AD group names after the group name has changed in Active Directory, который позволяет оперировать лишь списком групп отдельно взятого сайта, имея при этом ряд проблем, таких как операции сравнения без учёта регистра и отсутствие обработки ошибок. Переработанный вариант позволяет обновлять имена групп сразу во всех корневых сайтах (либо в конкретном сайте через переменную $SPSiteFilter). Предназначение других переменных:

  • $SPADLoginNamePrefix – префикс имени учётной записи, хранимой в свойстве UserLogin. Как правило, для доменных групп он имеет значение  "c:0+.w|", после которого идёт доменный SID группы.
  • $ADLoginNamePrefix - Префикс домена. Обязательно измените переменную, указав в ней префикс своего домена.
  • $UseSAMAccountName – Использовать для сравнения в качестве опорного атрибута в AD sAMAccountName (в противном случае используется Name, т.е. cn)
  • $ShowUnchangedGroups – Выводить информацию о группах в SharePoint, имена которых не конфликтуют с данными в AD.
  • $ShowNonExistentGroups – Выводить информацию о группах, которые есть в SharePoint, но не обнаружены по SID в AD (удалённые со временем из AD группы).
  • $EmulationMode – Включение режима эмуляции, позволяющего предварительно оценить необходимые изменения в SharePoint без их фактического применения.

Выполнение скрипта предполагается на сервере SharePoint из под учётной записи Farm Account (чтобы не иметь сложностей с доступом к спискам и веб-приложениям всех сайтов). Предварительно потребуется установить PowerShell-модуль для работы с Active Directory:

Add-WindowsFeature RSAT-AD-PowerShell

Содержимое скрипта:

param (
 #
 # For all root sites use $SPSiteFilter = "*"
 # For specific root site use $SPSiteFilter = "http://my.site.fqdn"
 # 
 [string]$SPSiteFilter = "*",
 [string]$SPADLoginNamePrefix = "c:0+.w|",
 [string]$ADLoginNamePrefix = "KOM\",
 [bool]$UseSAMAccountName = $true,
 [bool]$ShowUnchangedGroups = $false,
 [bool]$ShowNonExistentGroups = $false,
 [bool]$EmulationMode = $true
 )
 
if ((Get-PSSnapin 'Microsoft.SharePoint.PowerShell' -ErrorAction SilentlyContinue) -eq $null){Add-PSSnapin 'Microsoft.SharePoint.PowerShell'}
 if (Get-Module -ListAvailable -Name ActiveDirectory) {
  Import-Module ActiveDirectory
} else {
 Write-Host "ActiveDirectory Module does not exist. This Script requires this module. Please check that the module is installed."
 Write-Host "To install the module through PowerShell you can use the following command:"
 Write-Host "Add-WindowsFeature RSAT-AD-PowerShell"
 return
}

If ($SPSiteFilter -eq "*") {
    $spWebApp = Get-SPWebApplication | Get-SPSite | Get-SPWeb -Limit All | Where { $_.IsRootWeb -eq $true}
    }
Else {
    $spWebApp = Get-SPSite $SPSiteFilter | Get-SPWeb -Limit All | Where { $_.IsRootWeb -eq $true}
}

foreach($site in $spWebApp) {
 # 
 Write-Host "SITE: $($site.Url)" -ForegroundColor Yellow
 #
 # Notice that the SPADLoginNamePrefix variable prefix is used to identify a AD group and also to parse the SID value
 #
 $site.siteusers | where { $_.IsDomainGroup -and $_.UserLogin.ToString().Contains($SPADLoginNamePrefix) } | % {
  
 $SPName = $_.Name.ToString()
 $dispNameSplit = $_.UserLogin.ToString().Replace($SPADLoginNamePrefix, "")
  
 # Get the Account from AD to retrieve to correct name
 #

 Try {
 $adAccount = Get-ADGroup -Identity $dispNameSplit
  
 $newSPAccountDisplayName = ""
 #  
 # Modify the SharePoint Account DisplayName and Name based on the AD SamAccountName OR the Name 
 #
 if($UseSAMAccountName -eq $true){ 
    $newSPAccountDisplayName = $adAccount.SamAccountName 
    }
 else { 
    $newSPAccountDisplayName = $adAccount.Name
 }
 [string]$newSPAccountDisplayName = $ADLoginNamePrefix + $newSPAccountDisplayName.ToLower()

 if($SPName -ne $newSPAccountDisplayName) {
    Write-Host "Changed SharePoint AD Group: $($SPName) to: $($newSPAccountDisplayName)"
    If ($EmulationMode -ne $true) {
        $_.DisplayName = $newSPAccountDisplayName
        $_.Name = $newSPAccountDisplayName
        $_.Update()
    }
    } 
 else {
 If ($ShowUnchangedGroups) {
    Write-Host "SharePoint AD Group name '$($SPName)' is the same as in AD '$($newSPAccountDisplayName)'" -ForegroundColor DarkGreen
   }
 }
 $adAccount = $null
         
 }
 Catch {
 If ($ShowNonExistentGroups) {
    Write-Host "Group from Sharepoint '$($SPName)' with SID '$($dispNameSplit)' not found in Active Directory" -ForegroundColor Red
  }
 }

 }
$site.Dispose();
}

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

Для особо впечатлительных "экспертов по всем вопросам" и любителей запускать скрипты без предварительного анализа и тестирования, обращаю отдельное внимание на то, что прямая правка скрытого списка siteusers, вероятней всего не может считаться "официально поддерживаемым решением" и может использоваться лишь на Ваш страх и риск. Все стихийные бедствия, вызванные работой выше обозначенного скрипта, возлагаются исключительно на совесть администратора SharePoint Server. Аминь.

Дополнительные источники информации:

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