В предыдущей части — Строим высоко-доступную Windows-инфраструктуру в командной строке. AD DS. Часть 3-я — Инфраструктура управления
Вступление
Когда мы говорим о системах управления версиями (CVS), то первым делом нам в голову, разумеется, приходит программирование. В наши дни любой уважающий себя разработчик использует Git, или TFS, или Mercurial, или Subversion итд. Но это не значит, что концепция CVS нужна только разработчикам: Adobe, например, предоставляет дизайнерам собственное решение для управления версиями файлов.
А как насчёт нас, IT-администраторов? Учитывая растущую популярность концепции «инфраструктура как код», многие администраторы уже начали применять CVS для хранения скриптов и файлов конфигурации.
Сегодня я хотел бы поговорить об управлении версиями для групповых политик. Вы, наверное, знаете, что групповые политики – это не совсем текстовые файлы, поэтому традиционные CVS здесь не подходят. Именно поэтому Microsoft выпустили собственное решение, которое позволяет отслеживать изменения, сравнивать версии объектов групповых политик (GPO) и оперативно возвращаться к предыдущим: Advanced Group Policy Management (AGPM).
Интересно, что это не просто CVS, а ещё и инструмент, позволяющий делегировать административные права объектам групповых политик при помощи встроенного механизма.
Но даже если вы работаете в небольшой команде, и делегирование управления GPO вам не нужно, я всё равно рекомендую использовать AGPM в качестве системы управления версиями.
AGPM входит в Microsoft Desktop Optimization Pack, бесплатный набор ПО, доступный подписчикам Microsoft Software Assurance. Узнать об этом продукте больше вы можете по ссылке.
Warning
Установка AGPM НЕ ОТМЕНЯЕТ необходимости делать резервные копии Active Directory.
In this article:
Переменные, используемые в статье:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
$Domain = Get-ADDomain $DomainFQDN = $Domain.DNSRoot $DomainNetBIOSName = $Domain.NetBIOSName $Tiers12CombinedOUName = 'Infra' $Tiers12CombinedOUPath = 'OU={0},{1}' -f $Tiers12CombinedOUName, $Domain.DistinguishedName $TierOU = @{ Tier0 = @{ OUName = 'DA' ComputerOUName = 'Servers' GroupOUName = 'Groups' AccountOUName = 'Accounts' OUPath = $Domain.DistinguishedName } Tier1 = @{ OUName = 'Secure' ComputerOUName = 'Servers' GroupOUName = 'Groups' AccountOUName = 'Accounts' OUPath = $Tiers12CombinedOUPath } Tier2 = @{ OUName = 'Normal' ComputerOUName = 'Servers' GroupOUName = 'Groups' AccountOUName = 'Accounts' OUPath = $Tiers12CombinedOUPath } Tier3 = @{ OUName = 'Clients' ComputerOUName = 'Workstations' GroupOUName = 'Groups' AccountOUName = 'Accounts' OUPath = $Domain.DistinguishedName } } $WorkstationPrefix = 'WS' $ServerPrefix = 'SRV' $ServiceAccountPrefix = 'svc' $AdminWSId = 'ADM' $AdminGroupId = 'ADM' $TierIds = @{ Tier0 = 'DA' Tier1 = 'SE' Tier2 = 'NO' Tier3 = 'CL' } $AGPMObjectsId = 'AGPM' $AdminUserNameTemplate = '{0}-admin' $AdminWSNameTemplate = '{0}{1}' -f $WorkstationPrefix, $AdminWSId $gMSAGroupNameTemplate = '{0}-gMSA-User-{1}' -f $AdminGroupId, '{0}' $AGPMgMSAGroupName = $gMSAGroupNameTemplate -f $AGPMServiceAccountName $AGPMOwnerGroupName = '{0}-{1}-Owner' -f $AdminGroupId, $AGPMObjectsId $AGPMServiceAccountName = '{0}-{1}' -f $ServiceAccountPrefix, $AGPMObjectsId $ServiceAccountsGroupTemplate = '{0}-ServiceAccounts-{1}' -f $AdminGroupId, '{0}' $AGPMServiceAccountsGroupName = $ServiceAccountsGroupTemplate -f $AGPMObjectsId $AGPMServerHostName = ('{0}{1}' -f $ServerPrefix, $AGPMObjectsId) $AGPMServerFQDN = ('{0}.{1}' -f $AGPMServerHostName, $Domain.DNSRoot) $AGPMServerIPAddress = '192.0.2.5' # Это настройки сети для машины AGPM-сервера. Измените соответственно вашей инфраструктуре. $AGPMServerDefaultGateway = '192.0.2.1' $AGPMServerSubnetPrefix = 24 $AGPMServerCDLetter = 'D' # Буква диска с дистрибутивом ОС на машине AGPM-сервера. $AGPMClientCDLetter = 'D' # Буква диска с дистрибутивом ОС на машине AGPM-клиента. $DC1IPAddress = '192.0.2.3' # Это два IP-адреса контроллеров домена, которые мы устанавливали в части 1. Измените соответственно вашей инфраструктуре. $DC2IPAddress = '192.0.2.4' |
Подготовка
Подготовка AD DS
AGPM состоит из двух частей: сервера и клиента. Сервер, к сожалению, нельзя сделать высоко-доступным, и, как правило, устанавливают одн его экземпляр на один на лес AD DS. Я советую использовать для этого отдельный компьютер. Клиент же устанавливается на административные рабочие станции.
Important
Paulo Francisco Viralhadas написал интересную статью о работе нескольких серверов AGPM в одном домене.
В числе прочих приготовлений, мы создадим серверную учётную запись, несколько групп и учётную запись службы. Для учётной записи службы мы используем Group-Managed Service Account (gMSA).
gMSA – новый тип учётной записи, который впервые появился в Windows Server 2012. gMSA – это нечто среднее между учётной записью компьютера и пользователя. Главное преимущество таких у/з в том, что их пароль регулярно автоматически обновляется внутренними механизмами AD DS.
У класса Computer gMSA переняла знак “$” в конце sAMAccountName и необходимость заполнения атрибута dNSHostName.
Мы начнём с создания объекта компьютера для AGPM-сервера. Учётная запись службы AGPM получает контроль над всеми групповыми политиками в домене, включая те, что применяются к корню домена и к OU “Domain Controllers”. Учётная запись, контролирующая групповые политики контроллеров домена, контролирует эти компьютеры. Учётная запись, контролирующая контроллер домена, контролирует домен. Поэтому такая учётная запись относится к Зоне 0. Поскольку ОС, работающая на сервере AGPM, имеет полный доступ к процессам учётной записи, и, следовательно, контролирует учётную запись — то AGPM-сервер также считается объектом Зоны 0.
На административной рабочей станции Зоны 0 запустите:
New-ADComputer -Name ('{0}{1}' -f $ServerPrefix, $AGPMObjectsId) -Path ('OU={0},OU={1},{2}' -f $TierOU.Tier0.ComputerOUName, $TierOU.Tier0.OUName, $TierOU.Tier0.OUPath)
Для именования серверов, я использую следующую схему: <префикс сервера + идентификатор службы + номер>. В данной серии постов я буду использовать “SRV” в качестве префикса сервера (переменная $ServerPrefix
).
Идентификатор службы – это строка, сообщающая администратору, какие службы запущены на данном машине. Сервер AGPM достаточно будет обозначить просто “AGPM” ($AGPMObjectsId
). Когда несколько компьютеров несут одни и те же сервиссы, то я просто добавляю в их имена цифровой суффикс.
Далее – создание gMSA:
gMSA требует наличия в домене Key Distribution Services Root Key. KDS на контроллерах домена использует этот ключ при создании паролей для учётных записей gMSA.
По умолчанию KDS Root Key в домене отсутствует. Проверить его наличие можно, запустив командлет Get-KdsRootKey
:
1 2 |
PS C:\> Get-KdsRootKey PS C:\> |
Для создания ключа используйте командлет Add-KdsRootKey
. Его можно запустить без параметров, однако по умолчанию создаётся ключ, вступающий в действие через 10 дней. Это делается для того, чтобы ключ успел распространиться по директории.
Для немедленного вступления ключа в действие используйте параметр -EffectiveImmediately
.
1 2 3 4 5 6 |
PS C:\Windows\system32> Add-KdsRootKey -EffectiveImmidiately Guid ---- 503c9d67-3643-0ac0-de67-bd7fc737c87d PS C:\> |
Important
Параметр -EffectiveImmediately
не предназначен для боевой среды. При добавлении новых ключей KDS в свою инфраструктуру проявите терпение.
Для создания gMSA используйте командлет New-ADServiceAccount
. Обратите внимание, что выполнять его нужно с параметром –DNSHostName
, что достаточно необычно для пользовательских учётных записей. На самом деле он не оказывает никакого эффекта, так что здесь можно использовать любое имя DNS на ваш вкус. Я обычно делаю так: <имя учётной записи службы> + “.” + <доменное имя DNS>.
По умолчанию командлет создаёт новые объекты в контейнере “CN=Managed Service Accounts” в корне домена AD DS. Однако в хорошей инфраструктуре все объекты хранятся в соответствующих организационных единицах, поэтому я применяю параметр -Path
, и создаю учётную запись в OU учётных записей Зоны 0.
New-ADServiceAccount -Name $AGPMServiceAccountName -DNSHostName ('{0}.{1}' -f $AGPMServiceAccountName, $Domain.DNSRoot) -Path ('OU={0},OU={1},{2}' -f $TierOU.Tier0.AccountOUName, $TierOU.Tier0.OUName, $TierOU.Tier0.OUPath)
Note
Чтобы создать управляемую учётную запись службы старого типа, без группового управления, используйте параметр -RestrictToSingleComputer.
Дело в том, что AGPM создавалось без учёта наличия MSA — во время установки, когда мы указываем, какая учётная запись используется для запуска службы, gMSA не учитывается. К счастью, Craig Foster описал, как использовать Managed Service Accounts с AGPM.
Поэтому нам нужно создать временную учётную запись пользователя: она будет использоваться только во время установки. Имя этой временной учётной записи будет таким же, только без символа “$” в конце.
Если вы хотите, чтобы учётная запись была активна с самого начала, то в процессе создания задайте ей пароль.
1 2 3 4 |
PS C:\> $AGPMPassword = Read-Host -AsSecureString ********************************* PS C:\> New-ADUser -Name $AGPMServiceAccountName -UserPrincipalName ('{0}@{1}' -f $AGPMServiceAccountName, $Domain.DNSRoot) -AccountPassword $AGPMPassword -Enabled $true -Path ('OU={0},OU={1},{2}' -f $TierOU.Tier0.AccountOUName, $TierOU.Tier0.OUName, $TierOU.Tier0.OUPath) PS C:\> |
Как я уже говорил, НИКОГДА не следует давать права конкретной учётной записи – только группе. Для установки AGPM нам потребуется 3 группы:
- Группа с правом возвращения пароля учётной записи службы. Её имя хранится в
$AGPMgMSAGroupName
. В моём примере это “ADM-gMSA-User-svc-AGPM”. В эту группу входит учётная запись компьютера-сервера AGPM. - Группа, являющаяся владельцем хранилища AGPM. Она называется
$AGPMOwnerGroupName
, то есть “ADM-AGPM-Owner”. В эту группу входят администраторы домена. - Группа, которая будет использоваться для того, чтобы добавлять учётную запись службы AGPM в другие группы.
И зачем нам для этого лишняя группа? – спросите вы. Мы не раздаём права напрямую учётным записям, а добавляем учётные записи в разные группы, так ведь?
Когда как. Как я уже говорил, AGPM ничего не знает про gMSA, поэтому мы вынуждены создать временную учётную запись исключительно для установки. И поскольку мы даём права этой учётной записи службы, позже мы должны будем передать их другой учётной записи. Получится две учётные записи с одинаковыми правами. А когда что-то повторяется, то следует так или иначе автоматизировать эти повторения. Использование группы, которая консолидирует учётные записи, имеющие одинаковые права в нескольких группах, позволяет автоматизировать изменения групповой принадлежности.
В нашем случае это не критично и вы вполне можете добавить учётную запись AGPM в группы напрямую, но при работе с десятками учётных записей такой подход оказывается крайне удобным.
Код для создания группы:
1 2 3 4 5 6 7 8 9 10 11 |
New-ADGroup -Name $AGPMgMSAGroupName -Path ('OU={0},OU={1},{2}' -f $TierOU.Tier0.GroupOUName, $TierOU.Tier0.OUName, $TierOU.Tier0.OUPath) -GroupCategory Security -GroupScope Universal Set-ADServiceAccount -Identity $AGPMServiceAccountName -PrincipalsAllowedToRetrieveManagedPassword $AGPMgMSAGroupName Add-ADGroupMember -Identity $AGPMgMSAGroupName -Members (Get-ADComputer -Identity $AGPMServerHostName) New-ADGroup -Name $AGPMOwnerGroupName -Path ('OU={0},OU={1},{2}' -f $TierOU.Tier0.GroupOUName, $TierOU.Tier0.OUName, $TierOU.Tier0.OUPath) -GroupCategory Security -GroupScope Universal Add-ADGroupMember -Identity $AGPMOwnerGroupName -Members (Get-ADGroup ('{0}-512' -f ($Domain).DomainSID.Value)) New-ADGroup -Name $AGPMServiceAccountsGroupName -Path ('OU={0},OU={1},{2}' -f $TierOU.Tier0.GroupOUName, $TierOU.Tier0.OUName, $TierOU.Tier0.OUPath) -GroupCategory Security -GroupScope Global # Область действия здесь важна: позже мы добавим другую глобальную группу, Group Policy Creator Owners, в эту группу. Add-ADGroupMember -Identity $AGPMServiceAccountsGroupName -Members (Get-ADServiceAccount -Identity $AGPMServiceAccountName) Add-ADGroupMember -Identity $AGPMServiceAccountsGroupName -Members (Get-ADUser -Identity $AGPMServiceAccountName) |
Согласно документации, учётная запись службы AGPM должна иметь членство в двух встроенных группах: Backup Operators и Group Policy Creator Owners. Как и с группой “Domain Admins”, к этим двум мы обращаемся по SID, потому что в локализированных версиях они могут называться по-другому.
Обратите внимание, что в первой строке я использую не SID домена, а короткий идентификатор. Это потому что первая строка относится к группе “Backup Operators”, которая является не группой по умолчанию, а встроенной группой. Встроенные группы не имеют в своих SID доменной части, а вместо этого используют хорошо-известные идентификаторы.
1 2 |
Add-ADGroupMember -Identity 'S-1-5-32-551' -Members (Get-ADGroup -Identity $AGPMServiceAccountsGroupName) Add-ADGroupMember -Identity (Get-ADGroup ('{0}-520' -f ($Domain).DomainSID.Value)) -Members (Get-ADGroup -Identity $AGPMServiceAccountsGroupName) |
Note
Узнать больше о встроенных и используемых по умолчанию идентификаторах безопасности можно здесь, здесь и здесь.
Перед тем, как двигаться дальше, приготовьте самый свежий файл дистрибутива сервера AGPM (на момент написания статьи, это – “agpm_403_server_amd64.exe) и обновление для него.
Подготовка сервера AGPM
Хорошо, переходим к серверу AGPM:
- Присвойте компьютеру новое имя и перезагрузите его.
- Присвоите ему статический IP-адрес.
- Активируйте удалённый рабочий стол.
- Установите обновления.
- Настройте сервера DNS в сетевом интерфейсе.
- Добавьте компьютер в домен. Перезагрузите его.
- Удалите SMB1.
- Установите компоненты, необходимые для сервера AGPM.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
#1 Rename-Computer -ComputerName $AGPMServerHostName -Restart #2 New-NetIPAddress -IPAddress $AGPMServerIPAddress -InterfaceAlias 'Ethernet' -DefaultGateway $AGPMServerDefaultGateway -PrefixLength $AGPMServerSubnetPrefix #3 Set-ItemProperty -Path 'HKLM:\System\CurrentControlSet\Control\Terminal Server\' -Name 'fDenyTSConnections' -Value 0 Set-NetFirewallRule -Name 'RemoteDesktop-UserMode-In-TCP' -Enabled True Set-NetFirewallRule -Name 'RemoteDesktop-UserMode-In-UDP' -Enabled True #5 Set-DnsClientServerAddress -InterfaceAlias 'Ethernet' -ServerAddresses @($DC1IPAddress, $DC2IPAddress) #6 Add-Computer -DomainName $DomainFQDN -Credential (Get-Credential) -Restart #7 Uninstall-WindowsFeature -Name 'FS-SMB1' -Restart #8 Install-WindowsFeature -Name 'NET-Non-HTTP-Activ' -Source ('{0}:\sources\sxs\' -f $AGPMServerCDLetter) Install-WindowsFeature -Name 'GPMC', 'RSAT-AD-PowerShell' |
Note
Компонент RSAT-AD-PowerShell нужен для установки на компьютер Group-Managed Service Account.
Теперь можно перейти на рабочую станцию Зоны 0 и продолжить оттуда.
Нам нужно скопировать дистрибутив на сервер AGPM, и сделать это можно как минимум двумя способами:
- Через SMB.
- С использованием протокола Windows Remote Management (WinRM).
Если вы хотите cкопировать файл по SMB, то сначала нужно включить его в МСЭ, потому что по умолчанию SMB запрещён.
Для выполнения команд PowerShell на удалённом компьютере, существует два встроенных канала:
- Первый – это, разумеется RDP и запуск команд локально.
- Второй – это WinRM.
Мы в основном будем пользоваться WinRM, потому что RDP задействует больше серверных ресурсов, а мы бы хотели минимизировать влияние операций управления на серверы.
Windows Remote Management – это вариант реализации стандартного протокола WS-Management (Web Services for Management) от Microsoft. Он основан на стандарте SOAP, все сообщения в нём — в формате XML, так что можно сказать, что это текстовый протокол (просто диагностировать!).
В Windows для работы с этим протоколом есть ряд встроенных инструментов:
- Утилита командной строки
winrm
. Используется для конфигурации клиентов и серверов WinRM. Позволяет вам работать с WMI на удалённом компьютере при помощи WS-Management, а не RPC. - Утилита командной строки
winrs
. Её можно рассматривать в качестве замены знаменитой Sysinternals psexec от Марка Руссиновича. Опять же, работает по WS-Management, а не по RPC. - Командлет
Enter-PSSession
. Обеспечивает интерактивную сессию PowerShell на удалённом компьютере. - Командлет
Invoke-Command
. Запускает код PowerShell на удалённом компьютере в неинтерактивном режиме.Поскольку в этой серии статей мы говорим о PowerShell, то касаться winrm и winrs мы не будем.
Есть два способа работы с удалённым компьютером при помощи командлетов
Enter-PSSession
/Invoke-Command
. Первый – это запуск командлета с параметром-ComputerName
. Второй – использование объекта PSSession.
Объект сессии PowerShell – это однажды установленное подключение к службе WS-Management, которое можно повторно использовать в скриптах. Создаётся оно при помощи командлетаNew-PSSession
.Копирование дистрибутива на сервер AGPM по SMB
Для начала рассмотрим, как открыть порт SMB (TCP 445) удалённо с помощью командлета
Invoke-Command
:1Invoke-Command -ComputerName $AGPMServerFQDN -ScriptBlock {Set-NetFirewallRule -Name 'FPS-SMB-In-TCP' -Enabled True}Это же можно сделать и с помощью командлета Enter-PSSession:
1234567Windows PowerShellCopyright (C) 2016 Microsoft Corporation. All rights reserved.PS C:\Users\ad-admin> Enter-PSSession -ComputerName $AGPMServerFQDN[srvagpm.lab.exchange12rocks.net]: PS C:\Users\ad-admin\Documents> Set-NetFirewallRule -Name 'FPS-SMB-In-TCP' -Enabled True[srvagpm.lab.exchange12rocks.net]: PS C:\Users\ad-admin\Documents> Exit-PSSessionPS C:\>Теперь создадим временную папку на системном диске сервера:
При помощи Invoke-Command
:
1Invoke-Command -ComputerName $AGPMServerFQDN -ScriptBlock {New-Item -Name 'Temp' -Path $env:SystemDrive -ItemType Directory}При помощи Enter-PSSession
:
123Enter-PSSession -ComputerName $AGPMServerFQDNNew-Item -Name 'Temp' -Path $env:SystemDrive -ItemType DirectoryExit-PSSessionЧерез SMB
:
Если хотите, вы можете создать эту папку напрямую по SMB. Но командлетInvoke-Command
всё равно придётся использовать, чтобы узнать букву системного диска (да, обычно это «C», но вы никогда не можете быть уверены в этом на 100%).12$AGPMServerSystemDriveLetter = (Invoke-Command -ComputerName $AGPMServerFQDN -ScriptBlock {$env:SystemDrive})[0]New-Item -Name 'Temp' -Path ('\\{0}\{1}$\' -f $AGPMServerFQDN, $AGPMServerSystemDriveLetter) -ItemType DirectoryИ скопируйте туда дистрибутив:
12Copy-Item -Path '.\agpm_403_server_amd64.exe' -Destination ('\\{0}\{1}$\Temp\' -f $AGPMServerFQDN, $AGPMServerSystemDriveLetter)Copy-Item -Path '.\AGPM4.0SP1_Server_X64_KB4014009.exe' -Destination ('\\{0}\{1}$\Temp\' -f $AGPMServerFQDN, $AGPMServerSystemDriveLetter)Я предполагаю, что вы находитесь в папке с файлами дистрибутива. Если нет, то измените путь к файлам соответствующим образом.
Копирование дистрибутива на сервер AGPM по WinRM
Для копирования файлов по WinRM открывать порт SMB не нужно, но тогда вы должны использовать объект PSSession:
1$AGPMPSSession = New-PSSession -ComputerName $AGPMServerFQDNЗатем вы можете использовать этот объект либо в командах
Invoke-Command
, либо подключаясь интерактивно при помощиEnter-PSSession
.1234$AGPMSystemDrive = (Invoke-Command -Session $AGPMPSSession -ScriptBlock {$env:SystemDrive})Invoke-Command -Session $AGPMPSSession -ScriptBlock {New-Item -Name 'Temp' -Path $env:SystemDrive -Type Directory}Copy-Item -Path '.\agpm_403_server_amd64.exe' -ToSession $AGPMPSSession -Destination (Join-Path -Path $AGPMSystemDrive -ChildPath 'Temp')Copy-Item -Path '.\AGPM4.0SP1_Server_X64_KB4014009.exe' -ToSession $AGPMPSSession -Destination (Join-Path -Path $AGPMSystemDrive -ChildPath 'Temp')Я предполагаю, что вы находитесь в папке с файлами дистрибутива. Если нет, то измените путь к файлам соответствующим образом.
Установка сервера AGPM
Для установки ПО сервера AGPM нужно проделать следующее:
- Дайте учётным записям в группе
$AGPMServiceAccountsGroupName
разрешение на вход в систему в качестве службы. - Установите ПО, используя учётную запись «svc-AGPM» для запуска службы.
- Установите обновление для сервера AGPM.
- Предоставьте gMSA «svc-AGPM$» разрешение на чтение и изменение базы данных сервера AGPM.
- Смените учётную запись службы на gMSA «svc-AGPM$».
- Присвойте SPNы.
- Перезагрузите сервер.
Шаг №2 нужно выполнять интерактивном режиме. По неизвестной мне причине, при попытке использования командлета
Invoke-Command
установка прерывается. Используйте интерактивную сессию PowerShell на сервере AGPM для выполнения команд из этого шага.Изменение политик безопасности компьютера при помощи командной строки – задача непростая, потому что придётся использовать утилиту secedit.exe, а она работает только с файлами конфигурации — невозможно просто передать ей команду на изменение политики безопасности. Поэтому я экспортирую текущую конфигурацию безопасности в файл «sec-export.inf», расположенный в папке
%TEMP%
, редактирую его, сохраняю туда же под именем «sec-import.inf» и импортирую новую конфигурацию безопасности уже из этого файла.123456789101112$SID = (Get-ADGroup -Identity $AGPMServiceAccountsGroupName -Properties SID).SID.Value$FileExport = Join-Path -Path $env:Temp -ChildPath 'sec-export.inf'$FileImport = Join-Path -Path $env:Temp -ChildPath 'sec-import.inf'$FileDB = Join-Path -Path $env:Temp -ChildPath 'sec-DB.sdb'Start-Process -FilePath 'secedit.exe' -ArgumentList ('/export /cfg {0}' -f $FileExport) -Wait$Lines = Get-Content -Path $FileExport$Lines2 = ''foreach ($Line in $Lines) {if ($Line -like 'SeServiceLogonRight *') {$Line +=",*$SID"}; $Lines2 += "$Line`r`n"}Set-Content -Path $FileImport -Value $Lines2Start-Process -FilePath 'secedit.exe' -ArgumentList ('/import /db {0} /cfg {1}' -f $FileDB, $FileImport) -WaitStart-Process -FilePath 'secedit.exe' -ArgumentList ('/configure /db {0}' -f $FileDB) -WaitInvoke-GPUpdate -ForceСледующая команда запускает установщик в тихом режиме. Обратите внимание, что устанавливается только английский язык. Если вам нужны другие языки, то установите соответствующие параметры на «1».
1Start-Process -FilePath (Join-Path -Path $env:SystemDrive -ChildPath 'Temp\agpm_403_server_amd64.exe') -ArgumentList ('/quiet /msicl "VAULT_OWNER={0} SVC_USERNAME={1} SVC_PASSWORD={2} USERRUNASSERVICE={1} DSN={0} ADD_PORT_EXCEPTION=0 BRAZILIAN_PT=0 CHINESE_S=0 CHINESE_T=0 ENGLISH=1 FRENCH=0 GERMAN=0 ITALIAN=0 JAPANESE=0 KOREAN=0 RUSSIAN=0 SPANISH=0"' -f ('{0}\{1}' -f $DomainNetBIOSName, $AGPMOwnerGroupName), ('{0}\{1}' -f $DomainNetBIOSName, $AGPMServiceAccountName), ([System.Runtime.InteropServices.Marshal]::PtrToStringAuto([System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($AGPMPassword)))) -WaitЕсли вы хотите, чтобы процесс установки записывался в файл (для диагностики), задайте переменную
$AGPMInstallationLogName
и используйте её с опцией «/log», как показано ниже:12$AGPMInstallationLogName = 'AGPM-Install.log'Start-Process -FilePath (Join-Path -Path $env:SystemDrive -ChildPath 'Temp\agpm_403_server_amd64.exe') -ArgumentList ('/quiet /log {0} /msicl "VAULT_OWNER={1} SVC_USERNAME={2} SVC_PASSWORD={3} USERRUNASSERVICE={2} DSN={1} ADD_PORT_EXCEPTION=0 BRAZILIAN_PT=0 CHINESE_S=0 CHINESE_T=0 ENGLISH=1 FRENCH=0 GERMAN=0 ITALIAN=0 JAPANESE=0 KOREAN=0 RUSSIAN=0 SPANISH=0"' -f (Join-Path -Path $env:Temp -ChildPath $AGPMInstallationLogName), ('{0}\{1}' -f $DomainNetBIOSName, $AGPMOwnerGroupName), ('{0}\{1}' -f $DomainNetBIOSName, $AGPMServiceAccountName), ([System.Runtime.InteropServices.Marshal]::PtrToStringAuto([System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($AGPMPassword)))) -WaitЭта странная конструкция нужна, чтобы расшифровать SecureString обратно в текст:
12345[System.Runtime.InteropServices.Marshal]::PtrToStringAuto([System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($AGPMPassword))Убедитесь, что служба работает. Если нет — заставьте её =)
123PS C:\> (Get-Service -Name 'AGPM Service').StatusRunningPS C:\>Установите обновление:
Start-Process -FilePath (Join-Path -Path $env:SystemDrive -ChildPath 'Temp\AGPM4.0SP1_Server_X64_KB4014009.exe') -ArgumentList '/quiet' -Wait
Убедитесь, что служба работает и после обновления:
123PS C:\> (Get-Service -Name 'AGPM Service').StatusRunningPS C:\>Остановите службу:
1234PS C:\> Stop-Service -Name 'AGPM Service'PS C:\> (Get-Service -Name 'AGPM Service').StatusStoppedPS C:\>Предоставьте группе
$AGPMServiceAccountsGroupName
разрешение на изменение файлов в папке “$env:ProgramData\Microsoft\AGPM” — именно там AGPM хранит свою базу данных:1Get-Acl -Path (Join-Path -Path $env:ProgramData -ChildPath 'Microsoft\AGPM') | %{ $_.AddAccessRule((New-Object System.Security.AccessControl.FileSystemAccessRule ((Get-ADGroup -Identity $AGPMServiceAccountsGroupName -Properties SID).SID, 'Modify', 'ContainerInherit, ObjectInherit', 'None', 'Allow'))); Set-Acl -Path (Join-Path -Path $env:ProgramData -ChildPath 'Microsoft\AGPM') -AclObject $_}Чтобы использовать групповую управляемую учётную запись службы на хосте, сначала нужно её установить. Для этого используйте командлет
Install-ADServiceAccount
(входит в компонент RSAT-AD-PowerShell):
Install-ADServiceAccount -Identity $AGPMServiceAccountName
Чтобы проверить результат установки, можно использовать командлет
Test-ADServiceAccount
:123PS C:\> Test-ADServiceAccount -Identity $AGPMServiceAccountNameTruePS C:\>Чтобы сменить в настройках службы обычную учётную запись на gMSA, вызовите метод “Change” у соответствующего экземпляра класса Win32_Service:
Invoke-CimMethod -Query 'SELECT Name FROM Win32_Service WHERE Name="AGPM Service"' -MethodName 'Change' -Arguments @{StartName = ('{0}\{1}$' -f $DomainNetBIOSName, $AGPMServiceAccountName)}
Теперь установите необходимое для работы AGPM-сервера SPN (AgpmServer/<имя сервера>/<имя домена>) на у/з gMSA и удалите это SPN со временной учётной записи.
12Get-ADServiceAccount -Identity $AGPMServiceAccountName | Set-ADObject -Add @{servicePrincipalName = ('AgpmServer/{0}/{1}' -f $AGPMServerFQDN, $DomainFQDN)}Get-ADUser -Identity $AGPMServiceAccountName | Set-ADUser -ServicePrincipalNames $nullХотя у командлета
Set-ADServiceAccount
и есть параметр-ServicePrincipalNames
, приходится использовать командлетSet-ADObject
, потому чтоSet-ADServiceAccount
отказывается работать с SPN AGPM (скорее всего из-за того, что оно содержит два прямых слэша).Для клиент-серверного взаимодействия AGPM использует отдельный порт TCP. Давайте его откроем:
1234567891011121314151617181920212223PS C:\> New-NetFirewallRule -Name 'AGPM-Service' -DisplayName 'AGPM Service' -Enabled True -Direction Inbound -Action Allow -LocalPort 4600 -Protocol TCPName : AGPM-ServiceDisplayName : AGPM ServiceDescription :DisplayGroup :Group :Enabled : TrueProfile : AnyPlatform : {}Direction : InboundAction : AllowEdgeTraversalPolicy : BlockLooseSourceMapping : FalseLocalOnlyMapping : FalseOwner :PrimaryStatus : OKStatus : The rule was parsed successfully from the store. (65536)EnforcementStatus : NotApplicablePolicyStoreSource : PersistentStorePolicyStoreSourceType : LocalPS C:\>И, наконец, удалим командлеты AD DS с машины и перезагрузим её:
Uninstall-WindowsFeature -Name 'RSAT-AD-PowerShell' -Restart
Установка клиента AGPM
Перейдём к установке клиента: клиент AGPM нужно устанавливать на рабочую станцию в Зоне 0 (например, WSADMAD), потому что с его помощью администратор домена будет управлять всеми групповыми политиками в лесу.
Для управления групповыми политиками нам понадобится компонент Windows «GPMC». Мы установили его в прошлой части, как один из компонентов RSAT.Кроме того, для установки клиента нам, увы, понадобится .NET 3.5:
1234567891011PS C:\> Start-Process -FilePath 'dism' -ArgumentList ('/online /Enable-Feature /FeatureName:NetFx3 /Source:{0}:\sources\sxs' -f $AGPMClientCDLetter)Deployment Image Servicing and Management toolVersion: 10.0.14393.0Image Version: 10.0.14393.0Enabling feature(s)[==========================100.0%==========================]The operation completed successfully.PS C:\>Из папки, с дистрибутивом клиента AGPM, запускаем автоматическую установку:
Start-Process -FilePath '.\agpm_403_client_amd64.exe' -ArgumentList ('/quiet /msicl "PORT=4600 ARCHIVELOCATION={0} ADD_PORT_EXCEPTION=1 BRAZILIAN_PT=0 CHINESE_S=0 CHINESE_T=0 ENGLISH=1 FRENCH=0 GERMAN=0 ITALIAN=0 JAPANESE=0 KOREAN=0 RUSSIAN=0 SPANISH=0"' -f $AGPMServerFQDN)
Импорт объектов групповой политики в AGPM
Давайте ещё раз посмотрим на наши текущие объекты групповой политики:
123456789101112131415161718192021222324252627PS C:\> Get-GPO -AllDisplayName : Default Domain PolicyDomainName : lab.exchange12rocks.netOwner : LAB\Domain AdminsId : 31b2f340-016d-11d2-945f-00c04fb984f9GpoStatus : AllSettingsEnabledDescription :CreationTime : 10/2/2016 4:59:42 AMModificationTime : 10/2/2016 4:59:42 AMUserVersion : AD Version: 0, SysVol Version: 0ComputerVersion : AD Version: 1, SysVol Version: 1WmiFilter :DisplayName : Default Domain Controllers PolicyDomainName : lab.exchange12rocks.netOwner : LAB\Domain AdminsId : 6ac1786c-016f-11d2-945f-00c04fb984f9GpoStatus : AllSettingsEnabledDescription :CreationTime : 10/2/2016 4:59:42 AMModificationTime : 10/2/2016 4:59:42 AMUserVersion : AD Version: 0, SysVol Version: 0ComputerVersion : AD Version: 1, SysVol Version: 1WmiFilter :PS C:\>По умолчанию предустанавливается два объекта политик. Для того, чтобы управлять ими с помощью AGPM, сначала их нужно импортировать в него. Для импорта объекта групповой политики, служба AGPM должна обладать разрешением на его изменение. Такое разрешение легко предоставляется с помощью командлета
Set-GPPermission
. Запустите команду на рабочей станции Зоны 0:1234567891011121314151617181920212223242526PS C:\> Set-GPPermission -All -PermissionLevel GpoEditDeleteModifySecurity -TargetName ('{0}\{1}' -f $DomainNetBIOSName, $AGPMServiceAccountsGroupName) -TargetType GroupDisplayName : Default Domain PolicyDomainName : lab.exchange12rocks.netOwner : LAB\Domain AdminsId : 31b2f340-016d-11d2-945f-00c04fb984f9GpoStatus : AllSettingsEnabledDescription :CreationTime : 9/30/2016 4:45:53 PMModificationTime : 9/30/2016 4:45:52 PMUserVersion : AD Version: 0, SysVol Version: 0ComputerVersion : AD Version: 1, SysVol Version: 1WmiFilter :DisplayName : Default Domain Controllers PolicyDomainName : lab.exchange12rocks.netOwner : LAB\Domain AdminsId : 6ac1786c-016f-11d2-945f-00c04fb984f9GpoStatus : AllSettingsEnabledDescription :CreationTime : 9/30/2016 4:45:53 PMModificationTime : 9/30/2016 4:45:52 PMUserVersion : AD Version: 0, SysVol Version: 0ComputerVersion : AD Version: 1, SysVol Version: 1WmiFilter :PS C:\>Important
Возможно вам придётся подождать несколько минут, пока NTFS-разрешения будут реплицироваться. Подробности см. в статье KB3212430.
Теперь вы можете импортировать объекты групповой политики в AGPM:
Get-GPO -All | Add-ControlledGpo
С этого момента копии ваших предустановленных GPO сохранены в системе контроля версий. Откройте Group Policy Management Console и посмотрите в раздел «Change Control»: вы увидите там две групповые политики.
Помните, что AGPM не мешает администраторам домена изменять GPO напрямую, без использования системы контроля версий. В точности, как в ситуации, когда у вас в системе контроля есть исходный код сайта, однако его копия выполняется на рабочих серверах, и люди, имеющие к ним доступ, могут изменять код, не импортируя изменения в CVS.
Если сейчас вы задумались об ограничении доступа для администраторов домена техническими средствами, то почитайте статью Шона Райта, в которой написано, почему делать этого не следует.Заключение
В этой статье мы установили в нашей инфраструктуре систему управления версиями для групповых политик (AGPM). Мы запустили её под gMSA — самый безопасный способ запускать службы Windows на сегодняшний день. Мы можем управлять AGPM с рабочей станции Зоны 0 используя как графический интерфейс, так и PowerShell.
В следующей части мы ограничим наши администраторские учётные записи, и я покажу вам, как создавать и изменять объекты групповой политики из командной строки.Stay tuned!
- Дайте учётным записям в группе