В очередной статье из цикла «конспект админа» мне хотелось бы освежить в памяти несколько нюансов использования групповых политик. Заодно поразвлекаемся с созданием своих шаблонов и с автоматизацией работы с этими самыми политиками.


Освежаем память


Я не буду рассказывать, что такое групповые политики, и остановлюсь лишь на основных моментах, которые стоит иметь в виду при работе с ними.


В системах Windows помимо доменных существуют и локальные групповые политики ? управлять ими можно при помощи оснастки gpedit.msc на системах редакции Professional и выше. Часто считается, что без домена можно настраивать локальные групповые политики только для всех пользователей на компьютере. Это не совсем верно ? с выходом Windows Vista появилась возможность использовать множественную локальную групповую политику или MLGPO. Этот механизм позволяет настраивать отдельные политики для разных пользователей.


Добраться до него можно через вызов консоли mmc: при добавлении оснастки «Управление объектами групповой политики» нажать кнопку «Обзор». Далее на вкладке «Пользователи» уже можно выбрать конкретного пользователя или группу «Администраторы» и «Не администраторы». К сожалению, управление для группы пользователей не реализовано.



Управление групповой политикой для отдельных пользователей.


Бывало и так, что на отдельностоящем терминальном сервере разворачивали Active Directory только для того, чтобы отдельному пользователю настроить поведение драйвера для EasyPrint. Не надо так.

При добавлении доменных групповых политик стоит помнить про порядок их применения ? политика, примененная последней, будет обладать наивысшим приоритетом (да и на собеседованиях часто спрашивают).


Итак, предположим, что у нас есть компьютер в домене и четыре групповые политики: локальная на этом компьютере; политика на подразделение, в котором находится компьютер; политика на домен и политика на лес. Порядок их применения будет следующим:


  1. Локальная групповая политика.
  2. Групповая политика сайта.
  3. Групповая политика домена.
  4. Групповая политика верхнего подразделения.
  5. Групповая политика дочернего подразделения.

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



Блокировка наследования.


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


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


Работа замыкания настраивается непосредственно в политике ? «Настройка компьютера ? Административные шаблоны ? Система ? Режим обработки замыкания пользовательской групповой политики». Подробнее про механизм уже писали в статье про использование Merge\Replace в GPO. Я лишь добавлю, что режим замыкания групповой политики ? тоже частый вопрос на собеседовании.



Настройка замыкания групповой политики.


Физически доменные групповые политики находятся в папке SYSVOL на контроллерах домена. Папка реплицируется между контроллерами. Каждая групповая политика выглядит как папка с именем в виде GUID.



Групповые политики домена.


Правила фильтрации, настраиваемые через редактор групповой политики, соответствуют настройкам прав NTFS на соответствующую подпапку.


Говоря о правилах фильтрации, нельзя не упомянуть обновление MS16-072, которое «сломало» групповые политики. Теперь для того чтобы работали правила фильтрации, надо добавлять к каждому фильтру правило «на чтение», но не «на применение» группе Domain Computers.

В каждой папке с групповой политикой существуют подпапки Machine и User, соответствующие настройкам пользователя и компьютера. Если углубиться в подпапки, можно легко понять структуру групповой политики:


  • В корне папки находится файл GPT.ini с настройками групповой политики, такими как ее название.
  • В подпапках Machine и User сидят файлы registry.pol с настройками соответствующих веток реестра.
  • По пути Microsoft\Windows NT\SecEdit можно найти шаблон настроек безопасности ? GptTmpl.inf.
  • В подпапке Preferences находятся предпочтения групповых политик, представляющие из себя подпапки с файлами xml.
  • В подпапке Applications сидят дистрибутивы для развертывания через групповые политики.
  • В папке Scripts находятся скрипты на logon\logoff для пользователя и startup\shutdown для компьютера.
  • В папке Documents and Settings есть настройки перенаправления пользовательских папок.
  • Наконец, в папке Adm находятся устаревшие шаблоны групповой политики.

Подробнее про структуру можно почитать в материале Group Policy Basics, поэтому перейдем сразу к шаблонам.


Административные шаблоны


По сути своей административные шаблоны ? это специальные файлы с инструкциями по изменению клиентского реестра (ветки HKCU или HKLM) и настройками отображения изменяемых параметров через «Управление групповой политикой». В принципе, реестр можно менять и через «Предпочтения групповых политик». Но разница здесь не только в красивом интерфейсе.


Способ изменения реестра Как ведет себя при удалении политики со стандартными настройками Можно ли изменить параметр вручную Можно ли изменить параметр через приложение
Шаблоны Параметр реестра восстанавливается на значение «по умолчанию», если настройки по умолчанию есть в шаблоне - -
Предпочтения политик Параметр реестра не изменяется + +

Сравнение предпочтения групповых политик и административных шаблонов.


Другими словами, настройка реестра через шаблоны групповых политик более строгая. Тогда как настройка через предпочтения групповых политик напоминает периодическое применение reg-файла. Конечно, предпочтения позволяют не только менять параметры реестра, но и довольно гибко настраиваются. Тем и ценны.


Это актуально при изменении ветки Policies, и настраиваемое приложение должно хранить свои настройки в реестре. Простое изменение параметров через Предпочтения и Шаблоны будет работать схожим образом, только шаблоны могут оказаться удобнее.

До появления Windows Vista\2008 в качестве шаблона групповых политик брали исключительно стандарт .adm. Будучи с простой структурой, которую было легко редактировать вручную, этот стандарт обладал и рядом недостатков:


  • Для каждого языка приходилось создавать отдельный файл шаблона.
  • Файл шаблона физически находился в папке с групповой политикой. При использовании одного и того же шаблона он сохранялся в каждую папку, что увеличивало занимаемое место и время репликации.
  • Не поддерживались мультистроковые параметры и параметры QWORD.

На замену устаревшему стандарту появился новый. Новые шаблоны представляют собой два файла: сам шаблон, не зависимый от языка ? .admx и языковой «пакет» к нему ? файл .adml. Теперь шаблоны можно «положить» в центральное хранилище, и обращаться к нему, не плодя одинаковые файлы в папке SYSVOL.


Не обошлось без ложки дегтя ? теперь содержимое файла представляет собой популярный в индустрии формат XML. И создавать новые шаблоны в блокноте стало уже не так удобно.


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



Если возникает необходимость разработать и внедрить свой административный шаблон, то самый простой вариант ? это создать старый файл .adm и сконвертировать его в admx специальной утилитой. Вариант посложнее ? начинать сразу с .admx.


Создаем свой шаблон


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


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

За необходимые нам параметры отвечают три ключа в реестре:


  • Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced\Hidden.
  • Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced\HideFileExt.
  • Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced\ShowSuperHidden.

Содержимое ADM-шаблона, который разберем далее, под спойлером.
CLASS USER
CATEGORY !!ShowExplorer
    POLICY !!ShowHiddenFiles
        KEYNAME "Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced"
        EXPLAIN !!ShowHiddenFilesExplanation
        VALUENAME "Hidden"
        VALUEON NUMERIC "1"
        VALUEOFF NUMERIC "2"
    END POLICY

    POLICY !!ShowFileExtensions
        KEYNAME "Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced"
        EXPLAIN !!ShowFileExtensionsExplanation
        VALUENAME "HideFileExt"
        VALUEON NUMERIC "0"
        VALUEOFF NUMERIC "1"
    END POLICY

    POLICY !!ShowSuperHiddenFiles
        KEYNAME "Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced"
        EXPLAIN !!ShowSuperHiddenFilesExplanation
        VALUENAME "ShowSuperHidden"
        VALUEON NUMERIC "1"
        VALUEOFF NUMERIC "0"
    END POLICY
END CATEGORY

[strings]
ShowExplorer="Отображение файлов в проводнике"
ShowHiddenFiles="Показывать скрытые файлы"
ShowHiddenFilesExplanation="Когда эта настройка включена, проводник будет показывать скрытые файлы."
ShowSuperHiddenFiles="Показывать системные файлы"
ShowSuperHiddenFilesExplanation="Когда эта настройка включена, проводник будет показывать системные файлы"
ShowFileExtensions="Показывать расширения файлов"
ShowFileExtensionsExplanation="Когда эта настройка включена, проводник будет показывать расширения файлов"

Разберем подробнее синтаксис файла.


  • CLASS. Может принимать значение USER или MACHINE ? в зависимости от класса будет изменятся ветка реестра HKCU или HKLM соответственно.
  • CATEGORY. Строка, в которой задается имя «папки» политики.
  • POLICY. В строке задается название конкретной политики ? у нас таких будет три.
  • KEYNAME. Путь в реестре к изменяемым параметрам.
  • EXPLAIN. Отсылка к «переменной» с объяснением настройки.
  • VALUENAME. Название изменяемого параметра в реестре.
  • VALUEON**VALUEOFF**. Значение, которое будет принимать параметр при включении и выключении его в политике.
  • [strings]. Секция со значениями переменных, которые я использовал для текстовых строк. Можно их не использовать, но тогда могут быть проблемы из-за русского языка.

Помимо задействованных опций есть и другие, например:


  • EDITTEXT. Текстовое поле для ввода.
  • NUMERIC. Поле для ввода цифр.
  • CHECKBOX. Список, где можно отмечать параметры «галочками».
  • COMBOBOX. Список с «переключателем»
  • DROPDOWNLIST. Выпадающий список.
  • LISTBOX. Список для ввода нескольких элементов.

Подробнее со всеми параметрами можно ознакомится в разделе MSDN ADM Format.


Установить новый шаблон не просто, а очень просто ? достаточно щелкнуть правой кнопкой мыши по пункту «Административные шаблоны», выбрать «Добавление и удаление шаблонов» и добавить наш свежесозданный шаблон.



Добавленный шаблон.


После установки шаблона он отобразится в ветке «Классические административные шаблоны».



Теперь можно сконвертировать наш шаблон в .admx с помощью утилиты faAdmxConv из ADMX Migrator.



Конвертируем шаблон.


После конвертации получившийся шаблон .admx и папку Ru-ru с файлом локализации .adml нужно скопировать в папку %Systemroot%\PolicyDefinitions для локальной политики или в папку Sysvol\PolicyDefinitions на контроллере домена.



Установленный шаблон .admx.


Полный листинг получившегося шаблона и файла локализации под спойлером.

Шаблон:


<?xml version="1.0" encoding="utf-8"?>
<policyDefinitions revision="1.0" schemaVersion="1.0">
  <policyNamespaces>
    <target prefix="fullarmor" namespace="FullArmor.6fb075d6-ddee-4302-9d06-50c4d83e1910" />
    <using prefix="windows" namespace="Microsoft.Policies.Windows" />
  </policyNamespaces>
  <supersededAdm fileName="E:\1\explorer.adm" />
  <resources minRequiredRevision="1.0" />
  <supportedOn>
    <definitions>
      <definition name="SUPPORTED_NotSpecified" displayName="$(string.ADMXMigrator_NoSupportedOn)" />
    </definitions>
  </supportedOn>
  <categories>
    <category name="ShowExplorer" displayName="$(string.ShowExplorer)" />
  </categories>
  <policies>
    <policy name="ShowHiddenFiles" class="User" displayName="$(string.ShowHiddenFiles)" explainText="$(string.ShowHiddenFilesExplanation)" presentation="$(presentation.ShowHiddenFiles)" key="Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" valueName="Hidden">
      <parentCategory ref="ShowExplorer" />
      <supportedOn ref="SUPPORTED_NotSpecified" />
      <enabledValue>
        <decimal value="1" />
      </enabledValue>
      <disabledValue>
        <decimal value="2" />
      </disabledValue>
    </policy>
    <policy name="ShowFileExtensions" class="User" displayName="$(string.ShowFileExtensions)" explainText="$(string.ShowFileExtensionsExplanation)" presentation="$(presentation.ShowFileExtensions)" key="Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" valueName="HideFileExt">
      <parentCategory ref="ShowExplorer" />
      <supportedOn ref="SUPPORTED_NotSpecified" />
      <enabledValue>
        <decimal value="0" />
      </enabledValue>
      <disabledValue>
        <decimal value="1" />
      </disabledValue>
    </policy>
    <policy name="ShowSuperHiddenFiles" class="User" displayName="$(string.ShowSuperHiddenFiles)" explainText="$(string.ShowSuperHiddenFilesExplanation)" presentation="$(presentation.ShowSuperHiddenFiles)" key="Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" valueName="ShowSuperHidden">
      <parentCategory ref="ShowExplorer" />
      <supportedOn ref="SUPPORTED_NotSpecified" />
      <enabledValue>
        <decimal value="1" />
      </enabledValue>
      <disabledValue>
        <decimal value="0" />
      </disabledValue>
    </policy>
  </policies>
</policyDefinitions>

Файл локализации:


<?xml version="1.0" encoding="utf-8"?>
<policyDefinitionResources revision="1.0" schemaVersion="1.0">
  <displayName></displayName>
  <description></description>
  <resources>
    <stringTable>
      <string id="ShowExplorer">Отображение файлов в проводнике</string>
      <string id="ShowHiddenFiles">Показывать скрытые файлы</string>
      <string id="ShowHiddenFilesExplanation">Когда эта настройка включена, проводник будет показывать скрытые файлы.</string>
      <string id="ShowSuperHiddenFiles">Показывать системные файлы</string>
      <string id="ShowSuperHiddenFilesExplanation">Когда эта настройка включена, проводник будет показывать системные файлы</string>
      <string id="ShowFileExtensions">Показывать расширения файлов</string>
      <string id="ShowFileExtensionsExplanation">Когда эта настройка включена, проводник будет показывать расширения файлов</string>
      <string id="ADMXMigrator_UnresolvedString">ADMX Migrator encountered a string that is not present in the source ADM string table.</string>
      <string id="ADMXMigrator_NoSupportedOn">ADMX Migrator encountered a policy that does not have a supportedOn value.</string>
    </stringTable>
    <presentationTable>
      <presentation id="ShowHiddenFiles" />
      <presentation id="ShowFileExtensions" />
      <presentation id="ShowSuperHiddenFiles" />
    </presentationTable>
  </resources>
</policyDefinitionResources>

Действительно, xml в новом формате читается чуть хуже, чем старый .adm. Для облегчения работы с новым форматом в поставке ADMX Migrator есть утилита faAdmxEditor.msc. Помимо этой утилиты есть и скрипты для конвертации reg-файлов в шаблоны, и сторонние платные утилиты.


Конечно же, можно обойтись без вот-этого-всего и разобраться самостоятельно ? оставлю это в качестве домашнего задания. Благо на портале MSDN есть подробное описание XML-схемы, и есть неплохие материалы с примерами в сети. Например, «Административные шаблоны групповой политики».


Теперь перейдем к автоматизации.


Автоматическое управление


Работать с групповыми политиками из командной строки довольно тоскливо. Основных инструментов можно выделить три.


PowerShell. Есть набор командлетов для резервного копирования, восстановления и управления групповыми политиками. Создание новых политик ограничено ? можно лишь изменять реестр. Впрочем, в большинстве случаев и этого достаточно. В качестве примера создадим групповую политику, которая отключит автоматическое обновление Adobe Reader DC.


За отключение автоматического обновления отвечает ключ реестра bUpdater в ветке [HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Adobe\Acrobat Reader\DC\FeatureLockDown]. Установив параметр в 0, мы отключим опцию.


Создание групповой политики на PowerShell будет выглядеть так:


Import-module -Name GroupPolicy
Write-Host "Создаем новый объект политики с именем Adobe_Reader_disable_autoupdate"
New-GPO -Name Adobe_Reader_disable_autoupdate
Write-Host "Добавляем нужное нам значение реестра"
Set-GPRegistryValue -Name "Adobe_Reader_disable_autoupdate" -key "HKLM\SOFTWARE\Policies\Adobe\Acrobat Reader\DC\FeatureLockDown" -ValueName  bUpdater -TypeDWord -value 0
Write-Host "Прилинковываем новый объект к нужному OU"
Set-GPLink -Name Adobe_Reader_disable_autoupdate -Target "ou=Computers,dc=domain,dc=com" -LinkEnabled Yes


Свежесозданная групповая политика.


Полный список и описание командлетов доступны в материале Technet Group Policy Cmdlets in Windows PowerShell.


Интерфейс COM к GPMC (консоли управления групповой политикой). Способ позволяет сделать с политиками многое, на любом языке программирования, поддерживающим COM-интерфейсы. К сожалению, популярность он не приобрел и примеров в сети довольно мало, несмотря на богатое описание методов интерфейса на портале MSDN. Немногочисленные примеры использования доступны для загрузки в галерее Technet.


LGPO.exe. Не так давно Microsoft заменил набор утилит для работы с локальными групповыми политиками на единую утилиту. Скачать ее можно на официальном сайте. Утилита удобна для копирования и развертывания локальных групповых политик. Заявлена и поддержка MLGPO. Создавать свои политики тоже можно. Также программа удобна для создания и изменения файлов реестра registry.pol. Для примера изменим локальную групповую политику, добавив в нее отключение обновления несчастного Acrobat Reader DC.


Сделаем бэкап локальной групповой политики командой


lgpo.exe /b C:\Temp /n "Backup"

В папке C:\Temp появится подпапка с GUID по структуре схожая с доменными групповыми политиками:


Теперь развернем registry.pol в текстовый файл:


LGPO.exe /parse /m C:\temp\{GUID}\DomainSysvol\GPO\Machine\registry.pol >> reg.txt

Синтаксис текстового файла очевиден. Добавим в него значения реестра для отключения автоматического обновления «Акробата»:



Добавленный в файл параметр реестра.


Теперь останется завернуть наш reg.txt обратно в registry.pol и импортировать изменившийся файл обратно в локальную групповую политику:


LGPO.exe /r C:\Temp\reg.txt /w C:\Temp\registry.pol
LGPO.exe /m C:\Temp\registry.pol?

Все эти махинации, конечно же, можно завернуть в один скрипт и использовать для массового изменения локальной групповой политики привычным инструментом для запуска команд на удаленных компьютерах. Подробнее про методы запуска команд можно почитать в нашей статье «1000++ способ запуска команд на удаленном компьютере».


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

Комментарии (7)


  1. sukharichev
    15.03.2018 17:37

    Бывало и так, что на отдельностоящем терминальном сервере разворачивали Active Directory только для того, чтобы отдельному пользователю настроить поведение драйвера для EasyPrint.


    По-моему, так не бывало, потому что роли терминального сервера и контроллера домена взаимоблокирующие. Без нехороших хаков поставить их одновременно невозможно начиная с windows 2003 до 2008 R2 (дальше не знаю, не пробовал).


    1. dimskiy
      15.03.2018 18:24

      Все же, не взаимоблокирующие. Разумеется, ставить AD и RDS на один хост вендор не рекомендует, но при большом желании — не запрещает. Только что включил роль RDSH на контроллере домена с эксченджем — никаких проблем.
      И на 2003 так делал пару раз в прошлом. Тогда виртуализация не была так распространена, а инфраструктура в тот момент была бедной :\


    1. avelor
      15.03.2018 19:53

      без проблем делал с 2003 по 2012r2. причем в 2012 пару раз прям приходилось — отдельно стоящий сервер и необходимость подключаться к пользовательским сессиям через mstsc /shadow (без домена не работает).
      вот в 2016 если хочется через красивую коллекцию — тогда ждёт фиаско, нужно или грязными хаками (права для внутренней базы Windows править и ещё чего-то) или тупо поставить роль и настроить политиками.


  1. spitkia
    16.03.2018 12:22

    не могу победить в windows 10 1607 с помощью gpo две задачи:
    — сделать по-умолчанию язык ввода английский для текущего и нового пользователей и на экране приветствия,
    — удалить все modern apps
    может гуру подскажет?


    1. whiplash
      16.03.2018 15:38

      К GPO я еще не привязывал, но сам PS код для удаления modern apps (частично или всех я не разбирался), есть в известном скрипте reclaim-win10.ps1
      gist.github.com/alirobe/7f3b34ad89a159e6daa1


      1. spitkia
        16.03.2018 15:48

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


        1. avelor
          16.03.2018 21:44

          А запуска скрипта от системы не достаточно (не логон-скрипт вешаете, а стартап)?
          Ещё можно просто назначенное задание создать — через то же gpo.

          Язык емнип это тоже параметры реестра — пользовательского, defaultuser и системного.
          Да, посмотрите на эту тему social.technet.microsoft.com/wiki/contents/articles/6281.how-to-set-the-keyboard-layout-through-group-policy-gpo.aspx
          И на эту
          social.technet.microsoft.com/Forums/windows/en-US/291ab0d8-d119-4050-ad32-924f2fe2898d/how-to-change-the-default-keyboard-input-language-for-all-new-users?forum=w7itproui
          А особенности (и почему жто не работает в вин10) раскрыты тут superuser.com/questions/955783/setting-the-default-input-method-for-the-windows-10-login-screen

          Конечно проще это сделать всё при подготовке образа для установки.