Mitigaciones adicionales
Credential Guard ofrece mitigaciones frente a ataques en credenciales derivadas, lo que impide el uso de credenciales robadas en otro lugar. Sin embargo, los dispositivos pueden seguir siendo vulnerables a determinados ataques, incluso si las credenciales derivadas están protegidas por Credential Guard. Estos ataques pueden incluir el abuso de privilegios y el uso de credenciales derivadas directamente desde un dispositivo en peligro, el reutilización de credenciales robadas antes de habilitar Credential Guard y el abuso de herramientas de administración y configuraciones de aplicaciones débiles. Por este motivo, también se debe implementar una mitigación adicional para que el entorno de dominio sea más sólido.
Calificaciones de seguridad adicionales
Todos los dispositivos que cumplen las protecciones de línea base para hardware, firmware y software pueden usar Credential Guard.
Los dispositivos que cumplen más calificaciones pueden proporcionar protecciones adicionales para reducir aún más la superficie expuesta a ataques.
En la tabla siguiente se enumeran las calificaciones para mejorar la seguridad. Se recomienda cumplir las calificaciones adicionales para reforzar el nivel de seguridad que Credential Guard puede proporcionar.
Protección | Requisitos | Ventajas de seguridad |
---|---|---|
Configuración y administración de arranque seguro | - Se debe admitir la contraseña del BIOS o la autenticación más segura: en la configuración del BIOS, se debe establecer la autenticación del BIOS: debe haber compatibilidad con la opción de BIOS protegida para configurar la lista de dispositivos de arranque permitidos (por ejemplo, arranque solo desde disco duro interno) y el orden del dispositivo de arranque, invalidando BOOTORDER la modificación realizada por el sistema operativo. |
- Impedir que se inicien otros sistemas operativos -Impedir cambios en la configuración del BIOS |
Arranque seguro de la plataforma de confianza con raíz de hardware | - Se debe admitir la integridad de arranque (arranque seguro de la plataforma). Consulta los requisitos del Programa de compatibilidad de hardware de Windows en System.Fundamentals.Firmware.CS.UEFISecureBoot.ConnectedStandby - Interfaz de prueba de seguridad de hardware (HSTI) debe implementarse. Consulte Especificación de estabilidad de seguridad de hardware |
- La integridad del arranque (arranque seguro de plataforma) desde el encendido proporciona protección contra los atacantes físicamente presentes y una defensa exhaustiva contra el malware.
- HSTI proporciona garantía de seguridad para el silicio y la plataforma correctamente protegidos |
Actualización de firmware a través de Windows Update | - El firmware debe admitir actualizaciones de campo a través de Windows Update y la actualización de encapsulación UEFI | Ayuda a garantizar que las actualizaciones de firmware sean rápidas, seguras y fiables. |
Protección de la configuración y administración de arranque | - Funcionalidades necesarias del BIOS: capacidad del OEM para agregar ISV, OEM o certificado empresarial en la base de datos de arranque seguro en el momento de la fabricación: configuraciones necesarias: la CA UEFI de Microsoft debe quitarse de la base de datos de arranque seguro. Se permite la compatibilidad con módulos UEFI de terceros, pero debe usar certificados proporcionados por ISV o certificado OEM para el software UEFI específico. |
- Las empresas pueden optar por permitir la ejecución de aplicaciones o controladores EFI propietarios: la eliminación de la CA UEFI de Microsoft de la base de datos de arranque seguro proporciona control total a las empresas sobre el software que se ejecuta antes de que se inicie el sistema operativo. |
Habilitación de VBS de la protección de No-Execute (NX) para los servicios en tiempo de ejecución de UEFI | - VBS habilita la protección nx en el código de servicio en tiempo de ejecución UEFI y las regiones de memoria de datos. El código de servicio en tiempo de ejecución de UEFI debe admitir la protección de páginas de solo lectura, y los datos del servicio en tiempo de ejecución de UEFI no deben ser ejecutables. El servicio en tiempo de ejecución UEFI debe cumplir los siguientes requisitos: - Implemente UEFI 2.6 EFI_MEMORY_ATTRIBUTES_TABLE . Esta tabla debe describir toda la memoria del servicio en tiempo de ejecución de UEFI (código y datos): las secciones pe deben estar alineadas en la página en memoria (no es necesario para el almacenamiento no volátil). - La tabla De atributos de memoria debe marcar correctamente el código y los datos en cuanto RO/NX a la configuración por parte del sistema operativo : todas las entradas deben incluir atributos EFI_MEMORY_RO , EFI_MEMORY_XP o ambos.
- No se puede dejar ninguna entrada con ninguno de los atributos anteriores, lo que indica la memoria que es ejecutable y grabable. La memoria debe ser legible y ejecutable o grabable y no ejecutable (VEA INFORMACIÓN IMPORTANTE DESPUÉS DE ESTA TABLA) |
- Las vulnerabilidades en tiempo de ejecución de UEFI, si las hubiera, se bloquean para poner en peligro VBS (por ejemplo, en funciones como UpdateCapsule y SetVariable): reduce la superficie de ataque a VBS desde el firmware del sistema. |
Compatibilidad con firmware para la protección de SMM | - La especificación de la tabla de mitigaciones de seguridad de Windows SMM (WSMT) contiene detalles de una tabla ACPI que se creó para su uso con sistemas operativos Windows que admiten características basadas en la virtualización de Windows. | - Protege contra posibles vulnerabilidades en los servicios en tiempo de ejecución de UEFI, si existen, se bloqueará para poner en peligro VBS (por ejemplo, en funciones como UpdateCapsule y SetVariable) - Reduce la superficie expuesta a ataques a VBS desde el firmware del sistema. - Bloquea ataques de seguridad adicionales contra SMM |
Importante
Con respecto a la habilitación de VBS de la protección NX para los servicios en tiempo de ejecución UEFI:
- Solo se aplica a la memoria del servicio en tiempo de ejecución UEFI y no a la memoria del servicio de arranque UEFI.
- VBS aplica la protección en las tablas de página del sistema operativo
- No use secciones que sean grabables y ejecutables.
- No intente modificar directamente la memoria del sistema ejecutable
- No usar código dinámico
Restricción de usuarios de dominio a dispositivos específicos unidos a un dominio
Los ataques de robo de credenciales permiten al atacante robar secretos de un dispositivo y usarlos en otro dispositivo. Si un usuario puede iniciar sesión en varios dispositivos, podría usarse cualquier dispositivo para robar las credenciales. ¿Cómo se asegura de que los usuarios solo inicien sesión con dispositivos que tengan habilitado Credential Guard? Mediante la implementación de directivas de autenticación que las restringen a dispositivos específicos unidos a un dominio que se han configurado con Credential Guard. Para que el controlador de dominio sepa desde qué dispositivo está iniciando sesión un usuario, se debe utilizar la protección de Kerberos.
Protección de Kerberos
La protección de Kerberos forma parte de RFC 6113. Cuando un dispositivo admite la protección de Kerberos, su TGT se usa para proteger la prueba de posesión del usuario que puede mitigar los ataques de diccionario sin conexión. La protección de Kerberos también proporciona la ventaja adicional de los errores de KDC firmados. Esto mitiga la manipulación que puede ayudar a degradar los ataques.
Para habilitar la protección de Kerberos para restringir los usuarios de dominio a dispositivos específicos unidos a un dominio:
- Los usuarios tienen que estar en dominios que ejecuten Windows Server 2012 R2 o superior.
- Todos los controladores de dominio de estos dominios deben estar configurados para admitir la protección de Kerberos. Establezca la opción De compatibilidad con KDC para notificaciones, autenticación compuesta y directiva de grupo de protección de Kerberos en Compatible o Proporcionar siempre notificaciones.
- Todos los dispositivos con Credential Guard a los que estarán restringidos los usuarios deben configurarse para admitir la protección kerberos. Habilite la compatibilidad del cliente kerberos con notificaciones, autenticación compuesta y configuración de directiva de grupo de protección de Kerberos en Configuración del equipo>Plantillas> administrativasSistema>Kerberos.
Protección de secretos de dispositivo unidos a un dominio
Dado que los dispositivos unidos a un dominio también usan secretos compartidos para la autenticación, los atacantes también pueden robar esos secretos. Al implementar los certificados de dispositivo con Credential Guard, se puede proteger la clave privada. A continuación, las directivas de autenticación pueden requerir que los usuarios inicien sesión en dispositivos que se autentiquen mediante esos certificados. Esto impide que los secretos compartidos robados en los dispositivos se usen con las credenciales de usuario para iniciar sesión como tal.
La autenticación de certificado de dispositivos unidos a un dominio tiene los siguientes requisitos:
- Las cuentas de los dispositivos están ejecutando el nivel funcional de dominio de Windows Server 2012 o un nivel superior.
- Todos los controladores de dominio de esos dominios tienen certificados KDC que cumplen requisitos estrictos de certificado de validación de KDC:
- EKU de KDC presente
- El nombre de dominio DNS coincide con el campo DNSName de la extensión SubjectAltName (SAN).
- Los dispositivos Windows tienen la entidad de certificación que emite los certificados de controlador de dominio en el almacén empresarial.
- Se establece un proceso para garantizar la identidad y la confiabilidad del dispositivo de una manera similar a la que establecerías la identidad y la confiabilidad de un usuario antes de emitirle una tarjeta inteligente.
Implementación de certificados de dispositivo unidos a un dominio
Para garantizar que los certificados con la directiva de emisión necesaria se instalen únicamente en los dispositivos que los usuarios deben utilizar, deberán implementarse de forma manual en cada dispositivo. Para los certificados del dispositivo, deben aplicarse los mismos procedimientos de seguridad que se usan para emitir tarjetas inteligentes a los usuarios.
Por ejemplo, supongamos que desea usar la directiva de seguridad alta solamente en estos dispositivos. Con una entidad de certificación de Windows Server Enterprise puedes crear una nueva plantilla.
Creación de una plantilla de certificado
- En la consola del Administrador de certificados, haga clic con el botón derecho en Administrar plantillas de > certificado
- Haga clic con el botón derecho en Plantilla duplicada de autenticación de > estación de trabajo
- Haga clic con el botón derecho en la nueva plantilla y, a continuación, seleccione Propiedades.
- En la pestaña Extensiones, seleccione Editar directivas de > aplicación.
- Seleccione Autenticación de cliente y, a continuación, seleccione Quitar.
- Agrega el EKU ID-PKInit-KPClientAuth. Seleccione Agregar > nuevo y, a continuación, especifique los siguientes valores:
- Nombre: Autenticación de cliente Kerberos
- Identificador de objeto: 1.3.6.1.5.2.3.4
- En la pestaña Extensiones, seleccione Edición de directivas de > emisión.
- En Directivas de emisión, seleccione Alta garantía.
- En la pestaña Nombre del firmante, desactive la casilla Nombre DNS y, a continuación, active la casilla Nombre principal de usuario (UPN)
A continuación, en los dispositivos que ejecutan Credential Guard, inscriba los dispositivos mediante el certificado que creó.
Inscripción de dispositivos en un certificado
Ejecuta el siguiente comando:
CertReq -EnrollCredGuardCert MachineAuthentication
Nota
Debes reiniciar el dispositivo después de realizar la inscripción del certificado de autenticación de equipo.
Cómo una directiva de emisión de certificados puede usarse para el control de acceso
A partir del nivel funcional de dominio de Windows Server 2008 R2, la compatibilidad de los controladores de dominio para la seguridad del mecanismo de autenticación proporciona una manera de asignar los OID de la directiva de emisión de certificados a grupos de seguridad universal. Los controladores de dominio de Windows Server 2012 con soporte de notificación pueden asignarles estas notificaciones. Para obtener más información sobre el mecanismo de autenticación, consulta Comprobación del mecanismo de autenticación de AD DS en la Guía paso a paso de Windows Server 2008 R2 en TechNet.
Ver las directivas de emisión disponibles
-
get-IssuancePolicy.ps1 muestra todas las directivas de emisión que están disponibles en la entidad de certificación.
En el símbolo del sistema de Windows PowerShell, ejecuta el siguiente comando:
.\get-IssuancePolicy.ps1 -LinkedToGroup:All
Vincular una directiva de emisión a un grupo de seguridad universal
-
set-IssuancePolicyToGroupLink.ps1 crea un grupo de seguridad universal, crea una unidad organizativa y vincula la directiva de emisión a ese grupo de seguridad universal.
En el símbolo del sistema de Windows PowerShell, ejecuta el siguiente comando:
.\set-IssuancePolicyToGroupLink.ps1 -IssuancePolicyName:"<name of issuance policy>" -groupOU:"<Name of OU to create>" -groupName:"<name of Universal security group to create>"
Restricción del inicio de sesión de usuario
Por ahora hemos completado lo siguiente:
- Se ha creado una directiva de emisión de certificados especial para identificar aquello que reúne los criterios de implementación necesarios para que el usuario pueda iniciar sesión.
- Se ha asignado esa directiva a un grupo o notificación de seguridad universal.
- Se proporciona una manera para que los controladores de dominio obtengan los datos de autorización del dispositivo durante el inicio de sesión del usuario mediante la protección de Kerberos. Ahora lo que falta aún por hacer es configurar la comprobación de acceso en los controladores de dominio. Esto se hace mediante directivas de autenticación
Las directivas de autenticación deben cumplir los siguientes requisitos:
- Las cuentas de usuario están en un nivel funcional de dominio de Windows Server 2012 o en un dominio superior
Creación de una directiva de autenticación que restrinja a los usuarios al grupo de seguridad universal específico
- Apertura del Centro de administración de Active Directory
- Seleccione Autenticación > Nueva > directiva de autenticación
- En el cuadro Nombre para mostrar , escriba un nombre para esta directiva de autenticación.
- En el encabezado Cuentas, seleccione Agregar.
- En el cuadro de diálogo Seleccionar usuarios, equipos o cuentas de servicio, escriba el nombre de la cuenta de usuario que desea restringir y, a continuación, seleccione Aceptar.
- En el encabezado Inicio de sesión de usuario , seleccione el botón Editar .
- Seleccione Agregar una condición.
- En el cuadro Editar condiciones de control de acceso , asegúrese de que lee El > miembro del grupo > de usuarios de cada > valor y, a continuación, seleccione Agregar elementos.
- En el cuadro de diálogo Seleccionar usuarios, equipos o cuentas de servicio, escriba el nombre del grupo de seguridad universal que creó con el script set-IssuancePolicyToGroupLink y, a continuación, seleccione Aceptar.
- Seleccione Aceptar para cerrar el cuadro Editar condiciones de control de acceso
- Seleccione Aceptar para crear la directiva de autenticación.
- Seleccione Centro de administración de Active Directory.
Nota
Cuando la directiva de autenticación aplica las restricciones de la directiva, los usuarios no podrán iniciar sesión en dispositivos que no tengan un certificado con la directiva de emisión implementada correcta. Esto se aplica en escenarios de inicio de sesión local y remoto. Por lo tanto, se recomienda encarecidamente auditar en primer lugar solo las restricciones de directiva para que no ocurran errores inesperados.
Detección de errores de autenticación debidos a directivas de autenticación
Para realizar un seguimiento más fácil de los errores de autenticación debido a directivas de autenticación, existe un registro operativo únicamente con esos eventos. Para habilitar los registros en los controladores de dominio, en el Visor de eventos, vaya a Registros de aplicaciones y servicios\Microsoft\Windows\Authentication, haga clic con el botón derecho en AuthenticationPolicyFailures-DomainController y, a continuación, seleccione Habilitar registro.
Para obtener más información sobre los eventos de la directiva de autenticación, consulta Directivas de autenticación y silos de directivas de autenticación.
Apéndice: scripts
Esta es una lista de scripts que se mencionan en este artículo.
Obtener las directivas de emisión disponibles en la entidad de certificación
Guarda este archivo de script como 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
}
}
Nota
Si tienes problemas para ejecutar este script, prueba a reemplazar la comilla simple después del parámetro ConvertFrom-StringData.
Vincular una directiva de emisión a un grupo
Guarda el archivo de script como 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
}
}
Nota
Si tienes problemas para ejecutar este script, prueba a reemplazar la comilla simple después del parámetro ConvertFrom-StringData.