В одной из прошлых заметок мы рассматривали пример скриптовой реализации задачи полного резервного копирования фермы SharePoint Server 2013. И в этом примере скрипт выполнялся в контексте учётной записи фермы (SharePoint Farm service account). В этой заметке мы рассмотрим решение аналогичной задачи применительно к SharePoint Server 2016, но вместо учётной записи фермы будем использовать выделенную управляемую служебную учетную запись Group Managed Service Account (gMSA).
Сразу отмечу тот факт, что никаких принципиальных отличий в самом ранее рассматриваемом скрипте резервного копирования при использовании в SharePoint Server 2016 нет. Основные нюансы, на которые мы обратим внимание в данной заметке, касаются особенностей выполнения задачи в контексте учётной записи gMSA и настройки прав доступа, требуемых для выполнения задачи.
Создание и установка учётной записи gMSA
Создание и установка учётной записи gMSA на сервере SharePoint, где планируется выполнять резервное копирование фермы, производится с помощью стандартных процедур, описанных в Вики.
В нашем примере для выполнения задачи резервного копирования фермы в домене Active Directory создана учётная запись gMSA с именем KOM\s-S02$.
Выдача прав локального администратора на сервере SharePoint
Установленную учётную запись gMSA в первую очередь необходимо включить в локальную группу администраторов на сервере SharePoint.
Если этого не сделать, то при попытке выполнения вызова командлета Backup-SPFarm из под учётной записи gMSA мы получим ошибку "You need to have Machine administrator priviliges to run this cmdlet"
Выдача привилегии SPShellAdmin
Далее, не смотря на то, что наша сервисная учётная запись gMSA включена в группу локальных администраторов на сервере SharePoint WFE, при попытке проверочного запуска скрипта мы получим ошибку "The local farm is not accessible. Cmdlets with FeatureDependencyId are not registered" с последующей ошибкой "Backup-SPFarm : Object reference not set to an instance of an object"
Данная ошибка может возникать безотносительно нашей задачи резервного копирования, при любой попытке обращения к ферме SharePoint Server через командлеты PowerShell от имени учётной записи, отличной от учётной записи фермы.
Связано это с тем, что для возможности использования PowerShell-командлетов на уровне фермы SharePoint Server, требуется отдельная привилегия SPShellAdmin (в системе безопасности баз данных SQL Server для SharePoint фигурирует, как роль SharePoint_Shell_Access).
Чтобы проверить список учётных записей, имеющий соответствующую привилегию, в консоли SharePoint 2016 Management Shell выполним команду:
Get-SPShellAdmin
Выдаём привилегию нашей служебной учётной записи gMSA и проверяем результат:
Add-SPShellAdmin -UserName KOM\s-S02$ Get-SPShellAdmin
Однако без явного указания дополнительных параметров командлет Add-SPShellAdmin даст доступ только к конфигурации фермы, то есть учётная запись gMSA на уровне SQL Server будет добавлена в соответствующую роль к базе данных SharePoint_Config.
Чтобы дать доступ сразу для всех баз SharePoint, в том числе и контентых, потребуется выполнить команду типа:
Get-SPDatabase | ForEach-Object {Add-SPShellAdmin -UserName "KOM\s-S02$" -Database $_.Id}
Назначение роли db_backupoperator на БД в SQL Server
Практика показала, что привилегии SPShellAdmin на уровне SQL Server всё же может не хватать, и это может вызывать дополнительные ошибки доступа к БД в ходе работы скрипта резервного копирования. Этот вопрос решается путём добавления роли db_backupoperator для учётной записи gMSA по каждой базе данных SharePoint.
Однако это ещё не всё.
Права доступа к каталогу размещения резервных копий
Уже после выдачи обозначенных выше привилегий, при очередном проверочном запуске скрипта резервного копирования, на этапе резервного копирования компонент поиска, мы снова можем получать ошибки типа:
[FatalError] Object Search Service Application failed in event OnBackup. For more information, see the spbackup.log or sprestore.log file located in the backup directory. FaultException: Management called failed with System.InvalidOperationException: 'Job failed: Have tried to perform backup/restore operation twice on all in-sync members in cluster SP25f34bf8b977.0, but none succeeded. Last failure message: Microsoft.Ceres.SearchCore.Seeding.SnapshotTransferException: Could not send chunk ms\%default\gen.0000000000000007.state: Localpath: [0-2426> to target BackupDirectoryTarget[directory=\\FS01\BACKUP-SharePointFarm$\KOM-WEB1\spbr0003\I.Part.0\FastServer.Ix.0\I.0.0,validateTransfers=False] at Microsoft.Ceres.SearchCore.Seeding.SnapshotSender.SendChunks(ISnapshot snapshot, ISeedSource source, ISeedTarget target, SeedStatus status, Func`1 checkAborted, Int32 targetFragIndex) at Microsoft.Ceres.SearchCore.Seeding.SnapshotSender.FirstPhaseTransfer(ISeedSource source, ISeedTarget target, Action`1 updateProgress, Func`1 shouldAbort) at Microsoft.Ceres.SearchCore.Seeding.BackupWorker.BackupWork.DoFirstPhaseWork()' at at Microsoft.Ceres.SearchCore.IndexController.BackupService.ThrowOnFailure(JobStatus status) at Microsoft.Ceres.SearchCore.IndexController.BackupService.ProgressFirstPhase(String handle) at Microsoft.Ceres.SearchCore.IndexController.IndexControllerManagementAgent.WrapCall[T](Func`2 original) ... [FatalError] Object Search_Service_Application_DB_cc511d419edd4eb695be5f0f5975bdae failed in event OnBackup. For more information, see the spbackup.log or sprestore.log file located in the backup directory. Aborted due to error in another component. ... [FatalError] Object Crawl-0 (C: on KOM-WEB1) failed in event OnBackup. For more information, see the spbackup.log or sprestore.log file located in the backup directory. Aborted due to error in another component.
Возникло предположение, что это как-то может быть связано со спецификой работы служб поиска SharePoint, которые в конфигурации по умолчанию работают от имени учётной записи фермы. И только после того, как учётной записи фермы дополнительно были выданы полные права на целевой каталог размещения резервных копий (на уровне ACL NTFS и SMB), скрипт резервного копирования отработал без ошибок.
В итоге получилось, что на каталог размещения резервных копий требуется выдать полные права для:
- Учетной записи, от имени которой выполняется скрипт. В нашем случае это учётная запись gMSA;
- Учётной записи, от имени которой выполняется служба экземпляра SQL Server, в котором размещены базы данных SharePoint;
- Учётной записи, от имени которой выполняется служба SharePoint Timer Service (SPTimerV4). Как правило, это учётная запись фермы (SharePoint Farm service account).
Такой требуемый набор прав доступа подтверждает и старая статья Backup failed due to insufficient permissions - Event 3353 (SharePoint 2010 Products).
После всех предоставленных прав, скрипт резервного копирования фермы SharePoint Server 2016 от имени выделенной учётной записи gMSA отработал успешно.
Отладка процедуры резервного копирования
В случае возникновения проблем при выполнении скрипта резервного копирования фермы SharePoint, полезным может оказаться лог-файл spbackup.log, создаваемый командлетом Backup-SPFarm. Однако, учитывая то обстоятельство, что в конфигурации по умолчанию этот командлет пытается выполнять резервное копирование сразу в 3 потока, сбивчивый порядок появления записей в логе-файле может приводить к затруднению читаемости лога. В этом случае на время отладки работы скрипта в строке вызова командлета Backup-SPFarm достаточно добавить параметр, определяющий количество потоков выполнения -BackupThreads:
... Backup-SPFarm -Directory $BackupFolder -BackupMethod Full -Verbose -BackupThreads 1 -Percentage 25 ...
Задача планировщика Windows Task Scheduler
Настроить в планировщике Windows Task Scheduler периодический запуск скрипта в контексте учётной записи gMSA в Windows Server 2012 R2 можно только с помощью PowerShell. В нашем случае команды создания задачи будут выглядеть следующим образом:
$Action = New-ScheduledTaskAction -Execute "PowerShell.exe" -Argument "-NoProfile -command `"C:\Scripts\SP2016-Farm-Full-Backup.ps1`"" $Trigger = New-ScheduledTaskTrigger -Daily -At 5:30 $SvcUser = New-ScheduledTaskPrincipal -UserID KOM\s-S02$ -LogonType Password Register-ScheduledTask -TaskName "SharePoint - Full Farm Backup" -TaskPath "\IT" -Action $Action -Trigger $Trigger -Principal $SvcUser
Дополнительные примеры создания и настройки заданий планировщика от имени учётной записи gMSA можно найти в отдельной статье Вики.
Решение применимо к SharePoint Server 2016/2019