Дополнительная защита

Credential Guard предлагает средства защиты от атак на производные учетные данные, предотвращая использование украденных учетных данных в другом месте. Однако устройства по-прежнему могут быть уязвимы для определенных атак, даже если производные учетные данные защищены Credential Guard. Эти атаки могут включать злоупотребление привилегиями и использование производных учетных данных непосредственно с скомпрометированного устройства, повторное использование украденных учетных данных до включения Credential Guard, злоупотребление средствами управления и слабыми конфигурациями приложений. В связи с этим необходимо также развернуть дополнительные средства защиты, чтобы сделать среду домена более надежной.

Дополнительные требования к безопасности

Все устройства, отвечающие базовым требованиям защиты оборудования, встроенного ПО и программного обеспечения, могут использовать Credential Guard.
Устройства, которые соответствуют большей квалификации, могут обеспечить дополнительную защиту для дальнейшего сокращения направлений атак.

В следующей таблице перечислены требования для повышения безопасности. Мы рекомендуем использовать дополнительные квалификации, чтобы повысить уровень безопасности, который может обеспечить Credential Guard.

Защиты Требования Преимущества безопасности
Настройка и управление безопасной загрузкой — Должен поддерживаться
пароль BIOS или более надежная проверка подлинности. В конфигурации BIOS должна быть задана
проверка подлинности BIOS. Должна быть поддержка защищенного параметра BIOS для настройки списка разрешенных загрузочных устройств (например, загрузка только с внутреннего жесткого диска) и порядка загрузочных устройств, переопределения BOOTORDER изменений, внесенных операционной системой.
— Запрет запуска других операционных систем
-Предотвращение изменения параметров BIOS
Безопасная загрузка платформы доверия с аппаратными корнями — Должна поддерживаться целостность загрузки (безопасная загрузка платформы). См. требования программы совместимости оборудования Windows в разделе System.Fundamentals.Firmware.CS.UEFISecureBoot.ConnectedStandby
— необходимо реализовать аппаратный тестовый интерфейс безопасности (HSTI). См. спецификацию тестируемости безопасности оборудования.
- Целостность загрузки (безопасная загрузка платформы) с момента включения обеспечивает меры защиты от физического доступа злоумышленников, а также надежную защиту от вредоносного ПО.
— HSTI обеспечивает безопасность для правильно защищенного кремния и платформы
Обновление встроенного ПО через клиентский компонент Центра обновления Windows — встроенное ПО должно поддерживать обновления полей через клиентский компонент Центра обновления Windows и обновление инкапсуляции UEFI. Преимущества безопасности: обеспечивает быстрое, надежное и безопасное обновление встроенного ПО.
Защита конфигурации загрузки и управления ими — Обязательные возможности BIOS: возможность oem добавлять ISV, OEM или корпоративный сертификат в безопасную загрузочную базу данных во время
производства. Необходимые конфигурации: ЦС Microsoft UEFI необходимо удалить из базы данных безопасной загрузки. Поддержка сторонних модулей UEFI разрешена, но для конкретного программного обеспечения UEFI должны использоваться сертификаты, предоставляемые поставщиком программного обеспечения, или oem-сертификат.
— Предприятия могут разрешить запуск
собственных драйверов или приложений EFI. Удаление ЦС Microsoft UEFI из базы данных безопасной загрузки обеспечивает предприятиям полный контроль над программным обеспечением, которое запускается до загрузки операционной системы.
Включение VBS защиты No-Execute (NX) для служб среды выполнения UEFI — VBS обеспечивает защиту NX для кода службы среды выполнения UEFI и областей памяти данных. Код служб среды выполнения UEFI должен поддерживать защиту страниц только для чтения. Кроме того, данные службы среды выполнения UEFI не должны быть исполняемыми. Служба среды выполнения UEFI должна соответствовать следующим требованиям:
— Реализация UEFI 2.6 EFI_MEMORY_ATTRIBUTES_TABLE. В этой таблице
должна быть описана вся память службы среды выполнения UEFI (код и данные). Разделы PE должны быть выровнены по страницам в памяти (не требуется для энергонезависимого хранилища).
— Таблица атрибутов памяти должна правильно пометить код и данные RO/NX как для настройки операционной системой
. Все записи должны содержать атрибуты EFI_MEMORY_RO, EFI_MEMORY_XPили оба.
— Ни один из указанных выше атрибутов не может оставаться ни в каких записях, что указывает на то, что память является исполняемой и записываемой. Память должна быть либо читаемой и исполняемой, либо записываемой и неисполняемой
(СМ. ВАЖНУЮ ИНФОРМАЦИЮ ПОСЛЕ ЭТОЙ ТАБЛИЦЫ).
— Уязвимости в среде выполнения UEFI, если таковые имеются, блокируются из-за компрометации VBS (например, в таких функциях, как UpdateCapsule и SetVariable).
Сокращает область атак до VBS из встроенного ПО системы.
Поддержка встроенного ПО для защиты ОТ СММ Спецификация windows SMM Security Mitigations Table (WSMT) содержит сведения о таблице ACPI, созданной для использования с операционными системами Windows, поддерживающими функции на основе виртуализации Windows. — Защищает от потенциальных уязвимостей в службах среды выполнения UEFI, если таковые есть, будет заблокирована компрометации VBS (например, в таких функциях, как UpdateCapsule и SetVariable).
— уменьшает область атаки на VBS из встроенного ПО системы.
— блокирует дополнительные атаки безопасности на СММ

Важно.

Что касается включения VBS защиты NX для служб среды выполнения UEFI:

  • Он применяется только к памяти службы среды выполнения UEFI, но не к памяти загрузочной службы UEFI.
  • Защита применяется VBS к таблицам страниц ОС
  • Не используйте разделы, доступные для записи и исполняемые файлы.
  • Не пытайтесь напрямую изменить память исполняемой системы
  • Не используйте динамический код

Ограничение пользователей домена определенными устройствами, присоединенными к домену

Атака на учетные данные позволяет злоумышленнику украсть секреты с одного устройства и использовать их на другом. Если пользователь можете выполнить вход на нескольких устройствах, то любое устройство может использоваться для кражи учетных данных. Как обеспечить вход пользователей только с устройств с включенным Credential Guard? Путем развертывания политик проверки подлинности, которые ограничивают их определенными присоединенными к домену устройствами, настроенными с помощью Credential Guard. Чтобы контроллер домена мог узнать, с какого устройства пользователь выполняет вход, необходимо использовать защиту Kerberos.

Защита Kerberos

Защита Kerberos является частью RFC 6113. Если устройство поддерживает защиту Kerberos, его TGT используется для защиты пользовательского подтверждения собственности, что позволяет противостоять автономным атакам с перебором по словарю. Защита Kerberos также предоставляет дополнительное преимущество в виде подписанных ошибок KDC. Это позволяет бороться с попытками взлома, которые могут привести к таким результатам, как атаки с возвратом к предыдущей версии.

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

  • Пользователи должны находиться в доменах, в которых используется Windows Server 2012 R2 или более поздняя версия
  • Все контроллеры домена в этих доменах должны быть настроены для поддержки защиты Kerberos. Задайте для параметра групповой политики Поддержка KDC требований, комплексной проверки подлинности и защиты Kerberos значение Поддерживается или Всегда предоставлять утверждения.
  • Все устройства с Credential Guard, которыми будут ограничены пользователи, должны быть настроены для поддержки защиты Kerberos. Включите поддержку клиентов Kerberos для утверждений, составной проверки подлинности и защиты Kerberos групповая политика параметров в разделе Конфигурация компьютера ->Административные шаблоны ->Система ->Kerberos.

Защита секретов устройств, присоединенных к домену

Поскольку присоединенные к домену устройства также используют общие секретные данные для проверки подлинности, злоумышленники могут украсть и их. При использовании сертификатов устройств с помощью Credential Guard можно защитить закрытый ключ. Затем политики проверки подлинности могут требовать, чтобы пользователи входить на устройства, которые проходят проверку подлинности с помощью этих сертификатов. Это не позволит использовать общие секретные данные, украденные с этого устройства, с украденными учетными данными пользователей для входа от имени пользователя.

Для проверки подлинности с использованием сертификатов присоединенных к домену устройств необходимо следующее.

  • Учетные записи устройства должны находиться на функциональном уровне домена Windows Server 2012 или более высоком уровне.
  • Все контроллеры домена в этих доменах должны иметь сертификаты KDC, которые отвечают строгим требованиям проверки сертификата KDC:
    • KDC EKU в наличии
    • Имя DNS-домена соответствует полю DNSName расширения SubjectAltName (SAN)
  • На устройствах Windows ЦС выдает сертификаты контроллера домена в корпоративном хранилище.
  • Удостоверение и надежность устройства проверяется так же, как удостоверение и надежность пользователя перед выдачей ему смарт-карты.

Развертывание присоединенных к домену сертификатов устройств

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

Например, вы хотите использовать политику "Высокая надежность" только на этих устройствах. С помощью центра сертификации Windows Server Enterprise следует создать новый шаблон.

Создание шаблона сертификата

  1. В консоли диспетчера сертификатов щелкните правой кнопкой мыши элемент Управление шаблонами сертификатов>.
  2. Щелкните правой кнопкой мыши повторяющийся шаблон проверки подлинности > рабочей станции
  3. Щелкните правой кнопкой мыши новый шаблон и выберите пункт Свойства.
  4. На вкладке Расширения выберите Изменить политики приложений>.
  5. Выберите Проверка подлинности клиента, а затем нажмите кнопку Удалить.
  6. Добавьте EKU ID-PKInit-KPClientAuth. Выберите Добавить > , а затем укажите следующие значения:
    • Имя: Kerberos Client Auth
    • Идентификатор объекта: 1.3.6.1.5.2.3.4
  7. На вкладке Расширения выберите Изменить политики выдачи>.
  8. В разделе Политики выдачи выберите Высокий уровень надежности.
  9. На вкладке Имя субъекта снимите флажок DNS-имя проверка, а затем выберите поле Имя субъекта-пользователя (UPN) проверка

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

Регистрация устройств в сертификате

Выполните следующую команду.

CertReq -EnrollCredGuardCert MachineAuthentication

Примечание.

После регистрации сертификата проверки подлинности компьютера необходимо перезагрузить устройство.

Как политика выдачи сертификатов может использоваться для управления доступом

Начиная с функционального уровня домена Windows Server 2008 R2, поддержка контроллеров домена для контроля механизма проверки подлинности позволяет сопоставить политики выдачи сертификатов OID универсальным группам безопасности. Контроллеры домена Windows Server 2012 с поддержкой требований могут сопоставить их требованиям. Дополнительные сведения о контроле механизма проверки подлинности см. в разделе Пошаговое руководство по настройке контроля механизма проверки подлинности для доменных служб Active Directory в ОС Windows Server 2008 R2 на сайте TechNet.

Просмотр доступных политик выдачи

  • Сценарий get-IssuancePolicy.ps1 отображает все политики выдачи, доступные в центре сертификации.
    В командной строке Windows PowerShell введите следующую команду:
.\get-IssuancePolicy.ps1 -LinkedToGroup:All

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

  • Сценарий set-IssuancePolicyToGroupLink.ps1 создает универсальную группу безопасности и подразделение, а также связывает политику выдачи с универсальной группой безопасности.
    В командной строке Windows PowerShell введите следующую команду:
.\set-IssuancePolicyToGroupLink.ps1 -IssuancePolicyName:"<name of issuance policy>" -groupOU:"<Name of OU to create>" -groupName:"<name of Universal security group to create>"

Ограничение входа пользователей

Итак, вот что мы сделали.

  • Создали политику выдачи специальных сертификатов для определения устройств, соответствующих критериям развертывания, необходимую для того, чтобы пользователь мог выполнить вход в систему
  • Сопоставили эту политику универсальной группе безопасности или требованию
  • Предоставляется для контроллеров домена способ получения данных авторизации устройства во время входа пользователя с помощью защиты Kerberos. Таким образом, теперь нам осталось настроить проверку доступа на контроллерах домена. Это делается с помощью политик проверки подлинности.

Политики проверки подлинности имеют следующие требования.

  • Учетные записи пользователей должны находиться на функциональном уровне домена Windows Server 2012 или более высокого домена.

Создание политики проверки подлинности, предоставляющей доступ только пользователям, состоящим в определенной универсальной группе безопасности

  1. Открытие Центра администрирования Active Directory
  2. Выберите Проверка подлинности > Новая > политика проверки подлинности
  3. В поле Отображаемое имя введите имя для этой политики проверки подлинности.
  4. В разделе Учетные записи выберите Добавить.
  5. В диалоговом окне Выбор пользователей, компьютеров или учетных записей служб введите имя учетной записи пользователя, которую вы хотите ограничить, и нажмите кнопку ОК.
  6. Под заголовком User Sign On (Вход пользователя ) нажмите кнопку Изменить .
  7. Выберите Добавить условие.
  8. В поле Изменение условий контроль доступа убедитесь, что он считывает элемент группы > пользователей > каждого > значения, а затем выберите Добавить элементы.
  9. В диалоговом окне Выбор пользователей, компьютеров или учетных записей служб введите имя универсальной группы безопасности, созданной с помощью сценария set-IssuancePolicyToGroupLink, а затем нажмите кнопку ОК.
  10. Нажмите кнопку ОК, чтобы закрыть поле Изменение условий контроль доступа
  11. Нажмите кнопку ОК , чтобы создать политику проверки подлинности.
  12. Выберите Центр администрирования Active Directory

Примечание.

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

Обнаружение сбоев проверки подлинности из-за политик проверки подлинности

Чтобы облегчить отслеживание ошибок проверки подлинности, связанных с политиками проверки подлинности, ведется операционный журнал, в котором регистрируются только такие события. Чтобы включить журналы на контроллерах домена, в Просмотр событий перейдите в раздел Журналы приложений и служб\Microsoft\Windows\Authentication, щелкните правой кнопкой мыши AuthenticationPolicyFailures-DomainController и выберите Включить журнал.

Дополнительные сведения о событиях политики проверки подлинности см. в разделе Политики проверки подлинности и хранилища политик проверки подлинности.

Приложение. Сценарии

Ниже перечислены сценарии, упоминавшиеся в этом разделе.

Получение доступных политик выдачи в центре сертификации

Сохраните этот файл сценария под именем get-IssuancePolicy.ps1.

#######################################
##     Parameters to be defined      ##
##     by the user                   ##
#######################################
Param (
$Identity,
$LinkedToGroup
)
#######################################
##     Strings definitions           ##
#######################################
Data getIP_strings {
# culture="en-US"
ConvertFrom-StringData -stringdata @'
help1 = This command can be used to retrieve all available Issuance Policies in a forest. The forest of the currently logged on user is targeted.
help2 = Usage:
help3 = The following parameter is mandatory:
help4 = -LinkedToGroup:<yes|no|all>
help5 = "yes" will return only Issuance Policies that are linked to groups. Checks that the linked Issuance Policies are linked to valid groups.
help6 = "no" will return only Issuance Policies that are not currently linked to any group.
help7 = "all" will return all Issuance Policies defined in the forest. Checks that the linked Issuance policies are linked to valid groups.
help8 = The following parameter is optional:
help9 = -Identity:<Name, Distinguished Name or Display Name of the Issuance Policy that you want to retrieve>. If you specify an identity, the option specified in the "-LinkedToGroup" parameter is ignored.
help10 = Output: This script returns the Issuance Policy objects meeting the criteria defined by the above parameters.
help11 = Examples:
errorIPNotFound = Error: no Issuance Policy could be found with Identity "{0}"
ErrorNotSecurity = Error: Issuance Policy "{0}" is linked to group "{1}" which is not of type "Security".
ErrorNotUniversal = Error: Issuance Policy "{0}" is linked to group "{1}" whose scope is not "Universal".
ErrorHasMembers = Error: Issuance Policy "{0}" is linked to group "{1}" which has a non-empty membership. The group has the following members:
LinkedIPs = The following Issuance Policies are linked to groups:
displayName = displayName : {0}
Name = Name : {0}
dn = distinguishedName : {0}
        InfoName = Linked Group Name: {0}
        InfoDN = Linked Group DN: {0}   
NonLinkedIPs = The following Issuance Policies are NOT linked to groups:
'@
}
##Import-LocalizedData getIP_strings
import-module ActiveDirectory
#######################################
##           Help                    ##
#######################################
function Display-Help {
    ""
    $getIP_strings.help1
    ""
$getIP_strings.help2
""
$getIP_strings.help3
"     " + $getIP_strings.help4
"             " + $getIP_strings.help5
    "             " + $getIP_strings.help6
    "             " + $getIP_strings.help7
""
$getIP_strings.help8
    "     " + $getIP_strings.help9
    ""
    $getIP_strings.help10
""
""    
$getIP_strings.help11
    "     " + '$' + "myIPs = .\get-IssuancePolicy.ps1 -LinkedToGroup:All"
    "     " + '$' + "myLinkedIPs = .\get-IssuancePolicy.ps1 -LinkedToGroup:yes"
    "     " + '$' + "myIP = .\get-IssuancePolicy.ps1 -Identity:""Medium Assurance"""
""
}
$root = get-adrootdse
$domain = get-addomain -current loggedonuser
$configNCDN = [String]$root.configurationNamingContext
if ( !($Identity) -and !($LinkedToGroup) ) {
display-Help
break
}
if ($Identity) {
    $OIDs = get-adobject -Filter {(objectclass -eq "msPKI-Enterprise-Oid") -and ((name -eq $Identity) -or (displayname -eq $Identity) -or (distinguishedName -like $Identity)) } -searchBase $configNCDN -properties *
    if ($OIDs -eq $null) {
$errormsg = $getIP_strings.ErrorIPNotFound -f $Identity
write-host $errormsg -ForegroundColor Red
    }
    foreach ($OID in $OIDs) {
        if ($OID."msDS-OIDToGroupLink") {
# In case the Issuance Policy is linked to a group, it is good to check whether there is any problem with the mapping.
            $groupDN = $OID."msDS-OIDToGroupLink"
            $group = get-adgroup -Identity $groupDN
    $groupName = $group.Name
# Analyze the group
            if ($group.groupCategory -ne "Security") {
$errormsg = $getIP_strings.ErrorNotSecurity -f $Identity, $groupName
                write-host $errormsg -ForegroundColor Red
            }
            if ($group.groupScope -ne "Universal") {
                $errormsg = $getIP_strings.ErrorNotUniversal -f $Identity, $groupName
write-host $errormsg -ForegroundColor Red
            }
            $members = Get-ADGroupMember -Identity $group
            if ($members) {
                $errormsg = $getIP_strings.ErrorHasMembers -f $Identity, $groupName
write-host $errormsg -ForegroundColor Red
                foreach ($member in $members) {
                    write-host "          "  $member -ForeGroundColor Red
                }
            }
        }
    }
    return $OIDs
    break
}
if (($LinkedToGroup -eq "yes") -or ($LinkedToGroup -eq "all")) {
    $LDAPFilter = "(&(objectClass=msPKI-Enterprise-Oid)(msDS-OIDToGroupLink=*)(flags=2))"
    $LinkedOIDs = get-adobject -searchBase $configNCDN -LDAPFilter $LDAPFilter -properties *
    write-host ""    
    write-host "*****************************************************"
    write-host $getIP_strings.LinkedIPs
    write-host "*****************************************************"
    write-host ""
    if ($LinkedOIDs -ne $null){
      foreach ($OID in $LinkedOIDs) {
# Display basic information about the Issuance Policies
          ""
  $getIP_strings.displayName -f $OID.displayName
  $getIP_strings.Name -f $OID.Name
  $getIP_strings.dn -f $OID.distinguishedName
# Get the linked group.
          $groupDN = $OID."msDS-OIDToGroupLink"
          $group = get-adgroup -Identity $groupDN
          $getIP_strings.InfoName -f $group.Name
          $getIP_strings.InfoDN -f $groupDN
# Analyze the group
          $OIDName = $OID.displayName
    $groupName = $group.Name
          if ($group.groupCategory -ne "Security") {
          $errormsg = $getIP_strings.ErrorNotSecurity -f $OIDName, $groupName
          write-host $errormsg -ForegroundColor Red
          }
          if ($group.groupScope -ne "Universal") {
          $errormsg = $getIP_strings.ErrorNotUniversal -f $OIDName, $groupName
          write-host $errormsg -ForegroundColor Red
          }
          $members = Get-ADGroupMember -Identity $group
          if ($members) {
          $errormsg = $getIP_strings.ErrorHasMembers -f $OIDName, $groupName
          write-host $errormsg -ForegroundColor Red
              foreach ($member in $members) {
                  write-host "          "  $member -ForeGroundColor Red
              }
          }
          write-host ""
      }
    }else{
write-host "There are no issuance policies that are mapped to a group"
    }
    if ($LinkedToGroup -eq "yes") {
        return $LinkedOIDs
        break
    }
}    
if (($LinkedToGroup -eq "no") -or ($LinkedToGroup -eq "all")) {  
    $LDAPFilter = "(&(objectClass=msPKI-Enterprise-Oid)(!(msDS-OIDToGroupLink=*))(flags=2))"
    $NonLinkedOIDs = get-adobject -searchBase $configNCDN -LDAPFilter $LDAPFilter -properties *
    write-host ""    
    write-host "*********************************************************"
    write-host $getIP_strings.NonLinkedIPs
    write-host "*********************************************************"
    write-host ""
    if ($NonLinkedOIDs -ne $null) {
      foreach ($OID in $NonLinkedOIDs) {
# Display basic information about the Issuance Policies
write-host ""
$getIP_strings.displayName -f $OID.displayName
$getIP_strings.Name -f $OID.Name
$getIP_strings.dn -f $OID.distinguishedName
write-host ""
      }
    }else{
write-host "There are no issuance policies which are not mapped to groups"
    }
    if ($LinkedToGroup -eq "no") {
        return $NonLinkedOIDs
        break
    }
}

Примечание.

Если не удается запустить этот сценарий, попробуйте заменить одиночные кавычки после параметра ConvertFrom-StringData.

Сохраните этот файл сценария под именем set-IssuancePolicyToGroupLink.ps1.

#######################################
##     Parameters to be defined      ##
##     by the user                   ##
#######################################
Param (
$IssuancePolicyName,
$groupOU,
$groupName
)
#######################################
##     Strings definitions           ##
#######################################
Data ErrorMsg {
# culture="en-US"
ConvertFrom-StringData -stringdata @'
help1 = This command can be used to set the link between a certificate issuance policy and a universal security group.
help2 = Usage:
help3 = The following parameters are required:
help4 = -IssuancePolicyName:<name or display name of the issuance policy that you want to link to a group>
help5 = -groupName:<name of the group you want to link the issuance policy to>. If no name is specified, any existing link to a group is removed from the Issuance Policy.
help6 = The following parameter is optional:
help7 = -groupOU:<Name of the Organizational Unit dedicated to the groups which are linked to issuance policies>. If this parameter is not specified, the group is looked for or created in the Users container.
help8 = Examples:
help9 = This command will link the issuance policy whose display name is "High Assurance" to the group "HighAssuranceGroup" in the Organizational Unit "OU_FOR_IPol_linked_groups". If the group or the Organizational Unit do not exist, you will be prompted to create them.
help10 = This command will unlink the issuance policy whose name is "402.164959C40F4A5C12C6302E31D5476062" from any group.
MultipleIPs = Error: Multiple Issuance Policies with name or display name "{0}" were found in the subtree of "{1}"
NoIP = Error: no issuance policy with name or display name "{0}" could be found in the subtree of "{1}".
IPFound = An Issuance Policy with name or display name "{0}" was successfully found: {1}
MultipleOUs = Error: more than 1 Organizational Unit with name "{0}" could be found in the subtree of "{1}".
confirmOUcreation = Warning: The Organizational Unit that you specified does not exist. Do you want to create it?
OUCreationSuccess = Organizational Unit "{0}" successfully created.
OUcreationError = Error: Organizational Unit "{0}" could not be created.
OUFoundSuccess = Organizational Unit "{0}" was successfully found.
multipleGroups = Error: More than one group with name "{0}" was found in Organizational Unit "{1}".  
confirmGroupCreation = Warning: The group that you specified does not exist. Do you want to create it?
groupCreationSuccess = Univeral Security group "{0}" successfully created.
groupCreationError = Error: Univeral Security group "{0}" could not be created.
GroupFound = Group "{0}" was successfully found.
confirmLinkDeletion = Warning: The Issuance Policy "{0}" is currently linked to group "{1}". Do you really want to remove the link?
UnlinkSuccess = Certificate issuance policy successfully unlinked from any group.
UnlinkError = Removing the link failed.
UnlinkExit = Exiting without removing the link from the issuance policy to the group.
IPNotLinked = The Certificate issuance policy is not currently linked to any group. If you want to link it to a group, you should specify the -groupName option when starting this script.
ErrorNotSecurity = Error: You cannot link issuance Policy "{0}" to group "{1}" because this group is not of type "Security".
ErrorNotUniversal = Error: You cannot link issuance Policy "{0}" to group "{1}" because the scope of this group is not "Universal".
ErrorHasMembers = Error: You cannot link issuance Policy "{0}" to group "{1}" because it has a non-empty membership. The group has the following members:
ConfirmLinkReplacement = Warning: The Issuance Policy "{0}" is currently linked to group "{1}". Do you really want to update the link to point to group "{2}"?
LinkSuccess = The certificate issuance policy was successfully linked to the specified group.
LinkError = The certificate issuance policy could not be linked to the specified group.
ExitNoLinkReplacement = Exiting without setting the new link.
'@
}
# import-localizeddata ErrorMsg
function Display-Help {
""
write-host $ErrorMsg.help1
""
write-host $ErrorMsg.help2
""
write-host $ErrorMsg.help3
write-host "`t" $ErrorMsg.help4
write-host "`t" $ErrorMsg.help5
""
write-host $ErrorMsg.help6
write-host "`t" $ErrorMsg.help7
""
""
write-host $ErrorMsg.help8
""
write-host $ErrorMsg.help9
".\Set-IssuancePolicyToGroupMapping.ps1 -IssuancePolicyName ""High Assurance"" -groupOU ""OU_FOR_IPol_linked_groups"" -groupName ""HighAssuranceGroup"" "
""
write-host $ErrorMsg.help10
'.\Set-IssuancePolicyToGroupMapping.ps1 -IssuancePolicyName "402.164959C40F4A5C12C6302E31D5476062" -groupName $null '
""
}
# Assumption:  The group to which the Issuance Policy is going
#              to be linked is (or is going to be created) in
#              the domain the user running this script is a member of.
import-module ActiveDirectory
$root = get-adrootdse
$domain = get-addomain -current loggedonuser
if ( !($IssuancePolicyName) ) {
display-Help
break
}
#######################################
##     Find the OID object           ##
##     (aka Issuance Policy)         ##
#######################################
$searchBase = [String]$root.configurationnamingcontext
$OID = get-adobject -searchBase $searchBase -Filter { ((displayname -eq $IssuancePolicyName) -or (name -eq $IssuancePolicyName)) -and (objectClass -eq "msPKI-Enterprise-Oid")} -properties *
if ($OID -eq $null) {
$tmp = $ErrorMsg.NoIP -f $IssuancePolicyName, $searchBase  
write-host $tmp -ForeGroundColor Red
break;
}
elseif ($OID.GetType().IsArray) {
$tmp = $ErrorMsg.MultipleIPs -f $IssuancePolicyName, $searchBase  
write-host $tmp -ForeGroundColor Red
break;
}
else {
$tmp = $ErrorMsg.IPFound -f $IssuancePolicyName, $OID.distinguishedName
write-host $tmp -ForeGroundColor Green
}
#######################################
##  Find the container of the group  ##
#######################################
if ($groupOU -eq $null) {
# default to the Users container
$groupContainer = $domain.UsersContainer
}
else {
$searchBase = [string]$domain.DistinguishedName
$groupContainer = get-adobject -searchBase $searchBase -Filter { (Name -eq $groupOU) -and (objectClass -eq "organizationalUnit")}
if ($groupContainer.count -gt 1) {
$tmp = $ErrorMsg.MultipleOUs -f $groupOU, $searchBase
write-host $tmp -ForegroundColor Red
break;
}
elseif ($groupContainer -eq $null) {
$tmp = $ErrorMsg.confirmOUcreation
write-host $tmp " ( (y)es / (n)o )" -ForegroundColor Yellow -nonewline
$userChoice = read-host
if ( ($userChoice -eq "y") -or ($userChoice -eq "yes") ) {
new-adobject -Name $groupOU -displayName $groupOU -Type "organizationalUnit" -ProtectedFromAccidentalDeletion $true -path $domain.distinguishedName
if ($?){
$tmp = $ErrorMsg.OUCreationSuccess -f $groupOU
write-host $tmp -ForegroundColor Green
}
else{
$tmp = $ErrorMsg.OUCreationError -f $groupOU
write-host $tmp -ForeGroundColor Red
break;
}
$groupContainer = get-adobject -searchBase $searchBase -Filter { (Name -eq $groupOU) -and (objectClass -eq "organizationalUnit")}
}
else {
break;
}
}
else {
$tmp = $ErrorMsg.OUFoundSuccess -f $groupContainer.name
write-host $tmp -ForegroundColor Green
}
}
#######################################
##  Find the group               ##
#######################################
if (($groupName -ne $null) -and ($groupName -ne "")){
##$searchBase = [String]$groupContainer.DistinguishedName
$searchBase = $groupContainer
$group = get-adgroup -Filter { (Name -eq $groupName) -and (objectClass -eq "group") } -searchBase $searchBase
if ($group -ne $null -and $group.gettype().isarray) {
$tmp = $ErrorMsg.multipleGroups -f $groupName, $searchBase
write-host $tmp -ForeGroundColor Red
break;
}
elseif ($group -eq $null) {
$tmp = $ErrorMsg.confirmGroupCreation
write-host $tmp " ( (y)es / (n)o )" -ForegroundColor Yellow -nonewline
$userChoice = read-host
if ( ($userChoice -eq "y") -or ($userChoice -eq "yes") ) {
new-adgroup -samAccountName $groupName -path $groupContainer.distinguishedName -GroupScope "Universal" -GroupCategory "Security"
if ($?){
$tmp = $ErrorMsg.GroupCreationSuccess -f $groupName
write-host $tmp -ForegroundColor Green
}else{
$tmp = $ErrorMsg.groupCreationError -f $groupName
write-host $tmp -ForeGroundColor Red
break
}
$group = get-adgroup -Filter { (Name -eq $groupName) -and (objectClass -eq "group") } -searchBase $searchBase
}
else {
break;
}
}
else {
$tmp = $ErrorMsg.GroupFound -f $group.Name
write-host $tmp -ForegroundColor Green
}
}
else {
#####
## If the group is not specified, we should remove the link if any exists
#####
if ($OID."msDS-OIDToGroupLink" -ne $null) {
$tmp = $ErrorMsg.confirmLinkDeletion -f $IssuancePolicyName, $OID."msDS-OIDToGroupLink"
write-host $tmp " ( (y)es / (n)o )" -ForegroundColor Yellow -nonewline
$userChoice = read-host
if ( ($userChoice -eq "y") -or ($userChoice -eq "yes") ) {
set-adobject -Identity $OID -Clear "msDS-OIDToGroupLink"
if ($?) {
$tmp = $ErrorMsg.UnlinkSuccess
write-host $tmp -ForeGroundColor Green
}else{
$tmp = $ErrorMsg.UnlinkError
write-host $tmp -ForeGroundColor Red
}
}
else {
$tmp = $ErrorMsg.UnlinkExit
write-host $tmp
break
}
}
else {
$tmp = $ErrorMsg.IPNotLinked
write-host $tmp -ForeGroundColor Yellow
}
break;
}
#######################################
##  Verify that the group is         ##
##  Universal, Security, and         ##
##  has no members                   ##
#######################################
if ($group.GroupScope -ne "Universal") {
$tmp = $ErrorMsg.ErrorNotUniversal -f $IssuancePolicyName, $groupName
write-host $tmp -ForeGroundColor Red
break;
}
if ($group.GroupCategory -ne "Security") {
$tmp = $ErrorMsg.ErrorNotSecurity -f $IssuancePolicyName, $groupName
write-host $tmp -ForeGroundColor Red
break;
}
$members = Get-ADGroupMember -Identity $group
if ($members -ne $null) {
$tmp = $ErrorMsg.ErrorHasMembers -f $IssuancePolicyName, $groupName
write-host $tmp -ForeGroundColor Red
foreach ($member in $members) {write-host "   $member.name" -ForeGroundColor Red}
break;
}
#######################################
##  We have verified everything. We  ##
##  can create the link from the     ##
##  Issuance Policy to the group.    ##
#######################################
if ($OID."msDS-OIDToGroupLink" -ne $null) {
$tmp = $ErrorMsg.ConfirmLinkReplacement -f $IssuancePolicyName, $OID."msDS-OIDToGroupLink", $group.distinguishedName
write-host $tmp  "( (y)es / (n)o )" -ForegroundColor Yellow -nonewline
$userChoice = read-host
if ( ($userChoice -eq "y") -or ($userChoice -eq "yes") ) {
$tmp = @{'msDS-OIDToGroupLink'= $group.DistinguishedName}
set-adobject -Identity $OID -Replace $tmp
if ($?) {
$tmp = $Errormsg.LinkSuccess
write-host $tmp -Foreground Green
}else{
$tmp = $ErrorMsg.LinkError
write-host $tmp -Foreground Red
}
} else {
$tmp = $Errormsg.ExitNoLinkReplacement
write-host $tmp
break
}
}
else {
$tmp = @{'msDS-OIDToGroupLink'= $group.DistinguishedName}
set-adobject -Identity $OID -Add $tmp
if ($?) {
$tmp = $Errormsg.LinkSuccess
write-host $tmp -Foreground Green
}else{
$tmp = $ErrorMsg.LinkError
write-host $tmp -Foreground Red
}
}

Примечание.

Если не удается запустить этот сценарий, попробуйте заменить одиночные кавычки после параметра ConvertFrom-StringData.