PowerShell – Поддержание групп безопасности политики репликации паролей RODC в актуальном состоянии

imageПри использовании контроллеров домена «только на чтение» (RODC) для каждого RODC должна быть определена доменная группа безопасности, в которую входят учетные записи пользователей, чьи учетные данные могут реплицироваться на этот RODC. В крупной географически распределённой инфраструктуре с большим количеством контроллеров домена задача поддержания состава этих групп безопасности «в рукопашную» может стать проблемой, особенно если учесть «человеческий фактор», когда например, в каком-то из удалённых подразделений местный администратор создаёт новую учетную запись доменного пользователя, а включить в группу репликации паролей эту запись забывает. Для того чтобы исключить в данном случае «человеческий фактор», можно автоматизировать данный процесс с помощью PowerShell. Рассмотрим пример скрипта, который можно включить в планировщик задач на контроллере домена на периодическое выполнение.

Для работы скрипта потребуется файл в формате *.csv, в котором будет содержаться информация о том, какие OU в домене будут использоваться для поиска учетных записей пользователей и заполнения ими определённых групп репликации паролей. Каждая строчка файла представляет собой связку DN доменной группы безопасности репликации паролей и DN OU. Файл должен иметь примерно такое содержание:

RODCAllowGroupDN;UsersOUDN 
CN=RODC-Group1,OU=Groups,DC=mydom,DC=com;OU=Branch1,DC=mydom,DC=com 
CN=RODC-Group2,OU=Groups,DC=mydom,DC=com;OU=Branch2,DC=mydom,DC=com 
CN=RODC-Group3,OU=Groups,DC=mydom,DC=com;OU=Branch3,DC=mydom,DC=com

В самом скрипте в блоке переменных в переменной $DataFile нужно указать полный путь к соответствующему CSV файлу.

# Блок переменных
# $DataFile - Путь к файлу для сопоставления групп безопасности c OU
# $CountDisabledUsers - Признак необходимости обработки отключенных учетных записей пользователей (1 или 0)
# $CountServiceUsers - Признак необходимости обработки сервисных учетных записей пользователей (1 или 0) 
# $CountAdministrators - Признак необходимости обработки административных учетных записей пользователей (1 или 0) 
#
$DataFile = 'C:\Tools\Scripts\RODC-AddUsersToGroupsFromOUs.csv'
$CountDisabledUsers = 0
$CountServiceUsers = 1
$CountAdministrators = 1
#
# Описание фильтра поиска
#
$Filter = '(objectCategory=person)(objectClass=user)'
If ($CountDisabledUsers -eq 0) { $Filter = $Filter + '(!(userAccountControl:1.2.840.113556.1.4.803:=2))' }
If ($CountServiceUsers -eq 0) { $Filter = $Filter + '(!(sAMAccountName=s-*))' }
If ($CountAdministrators -eq 0) { $Filter = $Filter + '(!(sAMAccountName=a-*))' }
$Filter = '(&' + $Filter + ')'
#
# Функция сравнения и наполнения группы безопасности
#
Function AddUsersToGroupFromOU ($GroupDN, $OUDN) {
      $DomainOU = [ADSI]"LDAP://$OUDN"
      $DomainSG = [ADSI]"LDAP://$GroupDN"
      $Searcher = New-Object System.DirectoryServices.DirectorySearcher($DomainOU)
      $Searcher.Filter = $Filter
      $Searcher.PageSize  = 5000
      [Void]$Searcher.PropertiesToLoad.Add('cn')
      [Void]$Searcher.PropertiesToLoad.Add('distinguishedName')
      $Users = $Searcher.findall()
      #
      # Блок наполнения группы безопасности
      #
      $OldMembers = $DomainSG.member
      $NewMembers = $null
      ForEach ($User in $Users){
            $UserDN = $User.Properties.distinguishedname
            If ($OldMembers -notcontains $UserDN) {
                  $NewMembers = $NewMembers + $UserDN
                  Write-Host 'Add user:' $User.Properties.cn
                  }
      }
      #
      Write-Host '--------------------------------------------'
      Write-Host 'Total user accounts in OU: ' $Users.Count
      #
      If ($NewMembers -ne $null){
            $AllMembers = $OldMembers + $NewMembers
            $DomainSG.member = $AllMembers
            $DomainSG.SetInfo()
            Write-Host 'Old users in group: ' $OldMembers.Count
            Write-Host 'New users in group: ' $NewMembers.Count
      } Else { $AllMembers = $OldMembers }
      Write-Host 'Current users in group: ' $AllMembers.Count
      Write-Host '--------------------------------------------'
}
#
# Обработка входных данных файла 
#
$ConvFile = $DataFile + '_unicode'
Get-Content $DataFile | Set-Content $ConvFile -Encoding Unicode
Import-CSV $ConvFile -Delimiter ';' | ForEach-Object { 
      AddUsersToGroupFromOU $_.RODCAllowGroupDN $_.UsersOUDN
}
Remove-Item $ConvFile

Всего комментариев: 4 Комментировать

  1. Андрей Серенков /

    Алексей, юзеры это хорошо.
    А компьютеры?

    1. Алексей Максимов /

      Скрипт делался под стоящую передо мной конкретную задачу — наполнить лишь пользовательскую группу, так как в моём рабочем окружении доменная группа «Domain Computers» включена в список разрешенных групп на всех RODC. Доработать логику скрипта для включения в группы кэширования ещё и учетных записей компьютеров — дело нехитрое, для этого нужно лишь расширить фильтр поиска условием (&(objectCategory=computer)(!userAccountControl:1.2.840.113556.1.4.803:=2))

  2. Анонимус /

    21 век, а всё с файлами настроек. Давно модно OU помечать прямо в AD

    1. Алексей Максимов /

      «Давно модно…» — я не претендую на звание столичного франта :)
      Просто решил задачу доступным мне способом, делюсь этим с другими, кому это может пригодиться. Все мы понимаем, что вариантов реализации задачи можно найти много, всё зависит лишь от вашей фантазии.

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