Préventions supplémentaires
Credential Guard offre des mesures d’atténuation contre les attaques sur les informations d’identification dérivées, empêchant l’utilisation d’informations d’identification volées ailleurs. Toutefois, les appareils peuvent toujours être vulnérables à certaines attaques, même si les informations d’identification dérivées sont protégées par Credential Guard. Ces attaques peuvent inclure l’utilisation abusive de privilèges et l’utilisation d’informations d’identification dérivées directement à partir d’un appareil compromis, la réutilisation des informations d’identification volées avant l’activation de Credential Guard, ainsi que l’utilisation abusive d’outils de gestion et de configurations d’applications faibles. Pour cette raison, une atténuation supplémentaire doit également être déployée pour rendre l’environnement de domaine plus robuste.
Qualifications de sécurité supplémentaires
Tous les appareils qui respectent les protections de base pour le matériel, le microprogramme et les logiciels peuvent utiliser Credential Guard.
Les appareils qui répondent à davantage de qualifications peuvent fournir des protections supplémentaires pour réduire davantage la surface d’attaque.
Le tableau suivant répertorie les qualifications pour une sécurité améliorée. Nous vous recommandons de satisfaire aux qualifications supplémentaires pour renforcer le niveau de sécurité fourni par Credential Guard.
Protection | Conditions préalables | Avantages en matière de sécurité : |
---|---|---|
Configuration et gestion du démarrage sécurisé | - Le mot de passe du BIOS ou l’authentification plus forte doit être pris en charge - Dans la configuration du BIOS, l’authentification DU BIOS doit être définie . L’option BIOS protégée doit être prise en charge pour configurer la liste des périphériques de démarrage autorisés (par exemple, le démarrage uniquement à partir d’un disque dur interne) et l’ordre des appareils de démarrage, en BOOTORDER remplaçant les modifications apportées par le système d’exploitation |
- Empêcher le démarrage d’autres systèmes d’exploitation -Empêcher les modifications apportées aux paramètres du BIOS |
Démarrage sécurisé de la plateforme de confiance rootée sur le matériel | - L’intégrité du démarrage (démarrage sécurisé de la plateforme) doit être prise en charge. Consultez la configuration requise du programme de compatibilité matérielle Windows sous System.Fundamentals.Firmware.CS.UEFISecureBoot.ConnectedStandby - L’interface de test de sécurité matérielle (HSTI) doit être implémentée. Consultez Spécification de testabilité de la sécurité matérielle |
- L’intégrité du démarrage (démarrage sécurisé de plateforme) à partir de la mise sous tension fournit une protection contre les personnes malveillantes physiquement présentes et une protection renforcée contre les programmes malveillants.
- HSTI fournit une garantie de sécurité pour le silicium et la plateforme correctement sécurisés |
Mise à jour du microprogramme via Windows Update | - Le microprogramme doit prendre en charge les mises à jour de champs via Windows Update et la mise à jour de l’encapsulation UEFI | Permet de garantir que les mises à jour de microprogramme sont rapides, sécurisées et fiables. |
Sécurisation de la configuration et de la gestion du démarrage | - Fonctionnalités du BIOS requises : capacité de l’OEM à ajouter un isv, oem ou certificat d’entreprise dans la base de données de démarrage sécurisé au moment de la fabrication - Configurations requises : l’autorité de certification Microsoft UEFI doit être supprimée de la base de données de démarrage sécurisé. La prise en charge des modules UEFI tiers est autorisée, mais doit utiliser des certificats fournis par l’ÉDITEUR de logiciels ou un certificat OEM pour le logiciel UEFI spécifique |
- Les entreprises peuvent choisir d’autoriser l’exécution des pilotes/applications EFI propriétaires . La suppression de l’autorité de certification Microsoft UEFI de la base de données de démarrage sécurisé offre aux entreprises un contrôle total sur les logiciels qui s’exécutent avant le démarrage du système d’exploitation |
Activation VBS de la protection No-Execute (NX) pour les services d’exécution UEFI | - VBS active la protection NX sur le code du service runtime UEFI et les régions de mémoire de données. Le code de service d'exécution UEFI doit prendre en charge les protections de page en lecture seule, et le service d'exécution UEFI ne doit pas être exécutable. Le service runtime UEFI doit répondre aux exigences suivantes : - Implémenter UEFI 2.6 EFI_MEMORY_ATTRIBUTES_TABLE . Toute la mémoire du service d’exécution UEFI (code et données) doit être décrite par ce tableau . Les sections PE doivent être alignées sur la page en mémoire (non obligatoire pour le stockage non volatile). - La table d’attributs de mémoire doit marquer correctement le code et les données comme RO/NX pour la configuration par le système d’exploitation . Toutes les entrées doivent inclure des attributs EFI_MEMORY_RO , EFI_MEMORY_XP , ou les deux.
- Aucune entrée ne peut être laissée avec aucun des attributs ci-dessus, ce qui indique que la mémoire est à la fois exécutable et accessible en écriture. La mémoire doit être lisible et exécutable ou accessible en écriture et non exécutable (VOIR INFORMATIONS IMPORTANTES APRÈS CE TABLEAU) |
- Les vulnérabilités dans le runtime UEFI, le cas échéant, ne sont pas autorisées à compromettre VBS (comme dans des fonctions telles que UpdateCapsule et SetVariable) : réduit la surface d’attaque à VBS à partir du microprogramme système. |
Prise en charge des microprogrammes pour la protection SMM | - La spécification WSMT (Windows SMM Security Mitigations Table) contient les détails d’une table ACPI qui a été créée pour une utilisation avec les systèmes d’exploitation Windows qui prennent en charge les fonctionnalités basées sur la virtualisation Windows. | - Protège contre les vulnérabilités potentielles dans les services d’exécution UEFI, le cas échéant, ne peut pas compromettre VBS (par exemple, dans des fonctions comme UpdateCapsule et SetVariable) - Réduit la surface d’attaque à VBS à partir du microprogramme système - Bloque les attaques de sécurité supplémentaires contre SMM |
Important
En ce qui concerne l’activation VBS de la protection NX pour les services d’exécution UEFI :
- Il s’applique uniquement à la mémoire du service runtime UEFI, et non à la mémoire du service de démarrage UEFI
- La protection est appliquée par VBS sur les tables de pages de système d’exploitation
- N’utilisez pas de sections qui sont à la fois accessibles en écriture et exécutables
- N’essayez pas de modifier directement la mémoire système exécutable
- N’utilisez pas de code dynamique
Restreindre les utilisateurs de domaine à des appareils joints à un domaine spécifique
Les attaques par vol des informations d’identification permettent à la personne malveillante de voler des secrets sur un appareil et les utiliser sur un autre appareil. Si un utilisateur peut se connecter sur plusieurs appareils, tout appareil peut être utilisé pour dérober des informations d’identification. Comment vous assurer que les utilisateurs se connectent uniquement avec les appareils sur lesquels Credential Guard est activé ? En déployant des stratégies d’authentification qui les limitent à des appareils joints à un domaine spécifiques qui ont été configurés avec Credential Guard. Pour que le contrôleur de domaine sache sur quel appareil l’utilisateur est connecté, vous devez utiliser la protection Kerberos.
Protection Kerberos
La protection Kerberos fait partie intégrante de la norme RFC 6113. Quand un appareil prend en charge la protection Kerberos, son ticket d’authentification est utilisé pour protéger la preuve de possession de l’utilisateur, ce qui peut réduire les attaques par dictionnaire hors ligne. La protection Kerberos procure l’avantage supplémentaire des erreurs KDC signées, pour une réduction des falsifications susceptibles de provoquer diverses erreurs, telles que des attaques par rétrogradation.
Pour activer le blindage Kerberos pour limiter les utilisateurs de domaine à des appareils joints à un domaine spécifique :
- Les utilisateurs doivent se trouver dans des domaines qui exécutent Windows Server 2012 R2 ou une version supérieure
- Tous les contrôleurs de domaine de ces domaines doivent être configurés pour prendre en charge la protection Kerberos. Définissez le paramètre de stratégie de groupe prise en charge par KDC pour les revendications, l’authentification composée et le blindage Kerberos sur Pris en charge ou Toujours fournir des revendications
- Tous les appareils avec Credential Guard auxquels les utilisateurs seront limités doivent être configurés pour prendre en charge le blindage Kerberos. Activez la prise en charge du client Kerberos pour les paramètres de stratégie de groupe des revendications, de l’authentification composée et du blindage Kerberos sous Configuration> ordinateurModèles d’administration>Système>Kerberos.
Protéger les secrets d’appareil joints à un domaine
Dans la mesure où les appareils joints au domaine utilisent aussi des secrets partagés pour l’authentification, les personnes malveillantes peuvent également voler ces secrets. En déployant des certificats d’appareil avec Credential Guard, vous pouvez protéger la clé privée. Ensuite, les stratégies d’authentification peuvent exiger que les utilisateurs se connectent aux appareils qui s’authentifient à l’aide de ces certificats. Cela empêche le vol des secrets partagés de l’appareil, qui seraient utilisés avec les informations d’identification utilisateurs volées pour se connecter en tant qu’utilisateur.
L’authentification par certificat d’appareil joint au domaine présente les exigences suivantes :
- Les comptes d’appareils se trouvent au niveau fonctionnel du domaine Windows Server 2012 ou à des domaines supérieurs.
- Tous les contrôleurs de domaine de ces domaines ont des certificats KDC qui répondent à des exigences strictes de certificat de validation KDC :
- Utilisation améliorée de la clé KDC présente
- Le nom de domaine DNS correspond à la valeur du champ DNSName de l’extension SubjectAltName (SAN)
- Les appareils Windows ont l’autorité de certification émettrice des certificats de contrôleur de domaine dans le magasin d’entreprise.
- Un processus est établi pour garantir l’identité et la fiabilité de l’appareil, de la même manière que vous établiriez l’identité et la fiabilité d’un utilisateur avant d’émettre une carte à puce.
Déployer des certificats d’appareil joints à un domaine
Pour garantir que les certificats avec la stratégie d’émission requise ne sont installés que sur les appareils devant être utilisés par ces utilisateurs, ils doivent être déployés manuellement sur chaque appareil. Les mêmes procédures de sécurité utilisées pour l’émission de cartes à puce destinées aux utilisateurs doivent être appliquées pour les certificats d’appareil.
Par exemple, imaginons que vous souhaitiez utiliser la stratégie d’assurance élevée uniquement sur ces appareils. À l’aide de l’autorité de certification Windows Server Enterprise, vous créez un modèle.
Créer un modèle de certificat
- Dans la console Certificate Manager, cliquez avec le bouton droit sur Gérer les modèles de > certificats
- Cliquez avec le bouton droit sur Modèle d’authentification > de station de travail en double
- Cliquez avec le bouton droit sur le nouveau modèle, puis sélectionnez Propriétés
- Sous l’onglet Extensions, sélectionnez Modifier les stratégies d’application >
- Sélectionnez Authentification client, puis Supprimer
- Ajoutez l’EKU ID-PKInit-KPClientAuth. Sélectionnez Ajouter nouveau>, puis spécifiez les valeurs suivantes :
- Nom : Kerberos Client Auth
- Identificateur d’objet : 1.3.6.1.5.2.3.4
- Sous l’onglet Extensions, sélectionnez Modifier les stratégies d’émission >
- Sous Stratégies d’émission, sélectionnez Haute assurance.
- Sous l’onglet Nom de l’objet, décochez la case Nom DNS, puis cochez la case Nom d’utilisateur principal (UPN)
Ensuite, sur les appareils qui exécutent Credential Guard, inscrivez-les à l’aide du certificat que vous avez créé.
Inscrire des appareils dans un certificat
Exécutez la commande suivante :
CertReq -EnrollCredGuardCert MachineAuthentication
Remarque
Vous devez redémarrer l’appareil après l’inscription du certificat d’authentification d’ordinateur.
Utilisation d’une stratégie d’émission de certificat pour le contrôle d’accès
À partir du niveau fonctionnel Windows Server 2008 R2, la prise en charge des contrôleurs de domaine pour l’assurance du mécanisme d’authentification constitue un moyen de mapper les OID de la stratégie d’émission de certificat sur des groupes de sécurité universels. Les contrôleurs de domaine Windows Server 2012 avec une prise en charge des réclamations peuvent les mapper sur les réclamations. Pour plus d’informations sur l’assurance du mécanisme d’authentification, consultez la section Guide détaillé de l’assurance du mécanisme d’authentification pour AD DS dans Windows Server 2008 R2 sur TechNet.
Pour consulter les stratégies d’émission disponibles
-
get-IssuancePolicy.ps1 montre toutes les stratégies d’émission disponibles sur l’autorité de certification.
Dans une invite de commandes Windows PowerShell, exécutez la commande suivante :
.\get-IssuancePolicy.ps1 -LinkedToGroup:All
Pour lier une stratégie d’émission à un groupe de sécurité universel
-
set-IssuancePolicyToGroupLink.ps1 crée un groupe de sécurité universel, une unité d’organisation et lie la stratégie d’émission à ce groupe de sécurité universel.
Dans une invite de commandes Windows PowerShell, exécutez la commande suivante :
.\set-IssuancePolicyToGroupLink.ps1 -IssuancePolicyName:"<name of issuance policy>" -groupOU:"<Name of OU to create>" -groupName:"<name of Universal security group to create>"
Restreindre l’authentification de l’utilisateur
Ainsi, nous avons achevé les actions suivantes :
- Création d’une stratégie d’émission des certificats pour identifier les appareils qui satisfont les critères de déploiement requis pour l’authentification de l’utilisateur
- Mappage de cette stratégie sur un groupe de sécurité universel ou sur une réclamation
- A fourni un moyen pour les contrôleurs de domaine d’obtenir les données d’autorisation de l’appareil lors de l’authentification utilisateur à l’aide du blindage Kerberos. de manière à ce qu’il ne vous reste plus qu’à configurer le contrôle d’accès sur les contrôleurs de domaine. Cette opération est effectuée à l’aide de stratégies d’authentification
Les stratégies d’authentification présentent les exigences suivantes :
- Les comptes d’utilisateur se trouvent dans un domaine Windows Server 2012 de niveau fonctionnel ou supérieur
Créer une stratégie d’authentification limitant les utilisateurs au groupe de sécurité universel spécifique
- Ouvrir le Centre d’administration Active Directory
- Sélectionnez Authentification > Nouvelle > stratégie d’authentification
- Dans la zone Nom d’affichage , entrez un nom pour cette stratégie d’authentification
- Sous le titre Comptes , sélectionnez Ajouter
- Dans la boîte de dialogue Sélectionner des utilisateurs, des ordinateurs ou des comptes de service, tapez le nom du compte d’utilisateur que vous souhaitez restreindre, puis sélectionnez OK.
- Sous l’en-tête Authentification de l’utilisateur, sélectionnez le bouton Modifier
- Sélectionnez Ajouter une condition.
- Dans la zone Modifier les conditions de contrôle d’accès, vérifiez qu’il lit membre du groupe > d’utilisateurs > de chaque > valeur, puis sélectionnez Ajouter des éléments
- Dans la boîte de dialogue Sélectionner des utilisateurs, des ordinateurs ou des comptes de service, tapez le nom du groupe de sécurité universel que vous avez créé avec le script set-IssuancePolicyToGroupLink, puis sélectionnez OK.
- Sélectionnez OK pour fermer la zone Modifier les conditions de contrôle d’accès
- Sélectionnez OK pour créer la stratégie d’authentification.
- Sélectionner le Centre d’administration Active Directory
Remarque
Lorsque la stratégie d’authentification applique des restrictions de stratégie, les utilisateurs ne pourront pas se connecter à l’aide d’appareils qui ne disposent pas de certificat avec la stratégie d’émission appropriée déployée. Cela s’applique aux scénarios d’ouverture de session locale et distante. Par conséquent, il est fortement recommandé de n’auditer, dans un premier temps, que les restrictions de stratégie afin de vous assurer que vous n’avez pas d’échecs inattendus.
Découvrir les échecs d’authentification dus aux stratégies d’authentification
Pour simplifier le suivi des échecs d’authentification dus aux stratégies d’authentification, un journal opérationnel comportant uniquement ces événements existe. Pour activer les journaux sur les contrôleurs de domaine, dans l’Observateur d’événements, accédez à Journaux des applications et des services\Microsoft\Windows\Authentication, cliquez avec le bouton droit sur AuthenticationPolicyFailures-DomainController, puis sélectionnez Activer le journal.
Pour en savoir plus sur les événements de stratégie d’authentification, consultez la section Stratégies d’authentification et silos de stratégies d’authentification.
Annexe : Scripts
Voici la liste des scripts mentionnés dans cet article.
Obtenir les stratégies d’émission disponibles sur l’autorité de certification
Enregistrez ce fichier de script sous 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
}
}
Remarque
Si vous ne parvenez pas à exécuter ce script, essayez de remplacer l’apostrophe après le paramètre ConvertFrom-StringData.
Lier une stratégie d’émission à un groupe
Enregistrez le fichier de script sous 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
}
}
Remarque
Si vous ne parvenez pas à exécuter ce script, essayez de remplacer l’apostrophe après le paramètre ConvertFrom-StringData.