Share via


Opzioni aggiuntive di attenuazione dei rischi

Credential Guard offre mitigazioni contro gli attacchi alle credenziali derivate, impedendo l'uso di credenziali rubate altrove. Tuttavia, i dispositivi possono comunque essere vulnerabili a determinati attacchi, anche se le credenziali derivate sono protette da Credential Guard. Questi attacchi possono includere l'abuso di privilegi e l'uso di credenziali derivate direttamente da un dispositivo compromesso, il riutilizzo delle credenziali rubate prima dell'abilitazione di Credential Guard e l'uso improprio di strumenti di gestione e configurazioni di applicazioni deboli. Per questo motivo, è necessario distribuire anche una mitigazione aggiuntiva per rendere l'ambiente di dominio più affidabile.

Qualifiche di sicurezza aggiuntive

Tutti i dispositivi che soddisfano le protezioni di base per hardware, firmware e software possono usare Credential Guard.
I dispositivi che soddisfano più qualifiche possono fornire protezioni aggiuntive per ridurre ulteriormente la superficie di attacco.

Nella tabella seguente sono elencate le qualifiche per una maggiore sicurezza. È consigliabile soddisfare le qualifiche aggiuntive per rafforzare il livello di sicurezza che Credential Guard può fornire.

Protezione Requisiti Vantaggi di sicurezza
Configurazione e gestione dell'avvio sicuro - È necessario supportare la password del BIOS o l'autenticazione più avanzata
- Nella configurazione del BIOS è necessario impostare
l'autenticazione DEL BIOS- È necessario il supporto per l'opzione BIOS protetta per configurare l'elenco dei dispositivi di avvio consentiti (ad esempio, Avvio solo dal disco rigido interno) e l'ordine del dispositivo di avvio, ignorando BOOTORDER le modifiche apportate dal sistema operativo
- Impedire l'avvio di altri sistemi operativi
-Impedisci modifiche alle impostazioni del BIOS
Avvio protetto della piattaforma di attendibilità rooted hardware - L'integrità di avvio (avvio protetto della piattaforma) deve essere supportata. Vedere i requisiti del programma di compatibilità hardware Windows in System.Fundamentals.Firmware.CS.UEFISecureBoot.ConnectedStandby
- Hardware Security Test Interface (HSTI) deve essere implementato. Vedere Specifica di testability della sicurezza hardware
- L'integrità di avvio (avvio protetto della piattaforma) dal momento dell'accensione fornisce protezioni dagli autori degli attacchi fisicamente presenti e una difesa in profondità dal malware.
- HSTI garantisce la sicurezza per il silicio e la piattaforma correttamente protetti
Aggiornamento del firmware tramite Windows Update - Il firmware deve supportare gli aggiornamenti dei campi tramite Windows Update e l'aggiornamento dell'incapsulamento UEFI Garantisce aggiornamenti del firmware veloci, sicuri e affidabili.
Protezione della configurazione e della gestione dell'avvio - Funzionalità del BIOS necessarie: capacità dell'OEM di aggiungere isv, OEM o certificato enterprise nel database di avvio protetto in fase
di produzione- Configurazioni necessarie: la CA UEFI Microsoft deve essere rimossa dal database di avvio protetto. Il supporto per i moduli UEFI di terze parti è consentito, ma deve usare certificati forniti da ISV o un certificato OEM per il software UEFI specifico
- Le aziende possono scegliere di consentire l'esecuzione
di driver/applicazioni EFI proprietari - La rimozione di Microsoft UEFI CA dal database di avvio protetto offre alle aziende il controllo completo sul software eseguito prima dell'avvio del sistema operativo
Abilitazione vbs della protezione No-Execute (NX) per i servizi di runtime UEFI - VBS abilita la protezione NX nelle aree di memoria dei dati e del codice del servizio di runtime UEFI. Il codice del servizio di runtime UEFI deve supportare le protezioni di pagina di sola lettura e i dati del servizio di runtime UEFI non devono essere eseguibili. Il servizio di runtime UEFI deve soddisfare i requisiti seguenti:
- Implementare UEFI 2.6 EFI_MEMORY_ATTRIBUTES_TABLE. Tutta la memoria del servizio di runtime UEFI (codice e dati) deve essere descritta da questa tabella
: le sezioni PE devono essere allineate alla pagina in memoria (non necessarie per l'archiviazione non volatile).
- La tabella attributi di memoria deve contrassegnare correttamente il codice e i dati come RO/NX per la configurazione dal sistema
operativo: tutte le voci devono includere attributi EFI_MEMORY_RO, EFI_MEMORY_XPo entrambi.
- Nessuna voce può essere lasciata con nessuno degli attributi precedenti, che indica la memoria eseguibile e scrivibile. La memoria deve essere leggibile ed eseguibile o scrivibile e non eseguibile
(VEDERE INFORMAZIONI IMPORTANTI DOPO QUESTA TABELLA)
- Le vulnerabilità nel runtime UEFI, se presenti, sono bloccate dal compromettere vbs (ad esempio in funzioni come UpdateCapsule e SetVariable)
- Riduce la superficie di attacco a VBS dal firmware di sistema.
Supporto del firmware per la protezione SMM - La specifica WSMT (Security Mitigations Table) di Windows SMM contiene i dettagli di una tabella ACPI creata per l'uso con sistemi operativi Windows che supportano le funzionalità basate sulla virtualizzazione di Windows. - Protegge da potenziali vulnerabilità nei servizi di runtime UEFI, se presenti, verrà impedito di compromettere vbs (ad esempio in funzioni come UpdateCapsule e SetVariable)
- Riduce la superficie di attacco a VBS dal firmware di sistema
- Blocca altri attacchi di sicurezza contro SMM

Importante

Per quanto riguarda l'abilitazione vbs della protezione NX per i servizi di runtime UEFI:

  • Si applica solo alla memoria del servizio di runtime UEFI e non alla memoria del servizio di avvio UEFI
  • La protezione viene applicata da VBS nelle tabelle delle pagine del sistema operativo
  • Non usare sezioni sia scrivibili che eseguibili
  • Non tentare di modificare direttamente la memoria del sistema eseguibile
  • Non usare codice dinamico

Limitare gli utenti di dominio a dispositivi specifici aggiunti a un dominio

Gli attacchi di furto delle credenziali permettono a utenti malintenzionati di rubare segreti da un dispositivo e usarli su un altro dispositivo. Se un utente può effettuare l'accesso a più dispositivi, qualsiasi dispositivo potrebbe essere usato per sottrarre le credenziali. Come si garantisce che gli utenti accedono solo con i dispositivi con Credential Guard abilitato? Distribuendo criteri di autenticazione che li limitano a specifici dispositivi aggiunti a un dominio configurati con Credential Guard. Per fare in modo che il controller di dominio sappia da quale dispositivo l'utente sta effettuando l'accesso, deve essere usata la blindatura Kerberos.

Blindatura Kerberos

La blindatura Kerberos fa parte della RFC 6113. Quando un dispositivo supporta la blindatura Kerberos, il relativo ticket di concessione ticket (TGT) viene usato per proteggere la prova del possesso da parte dell'utente in modo da prevenire eventuali attacchi con dizionario offline. La blindatura Kerberos assicura inoltre l'ulteriore vantaggio degli errori KDC firmati, riducendo la possibilità di intromissioni che potrebbero comportare attacchi di downgrade.

Per abilitare la blindatura Kerberos per limitare gli utenti di dominio a dispositivi specifici aggiunti a un dominio:

  • Gli utenti devono trovarsi in domini che eseguono Windows Server 2012 R2 o versione successiva
  • Tutti i controller di dominio in questi domini devono essere configurati per il supporto della blindatura Kerberos. Imposta l'opzione di Criteri di gruppo Supporto KDC per attestazioni, autenticazione composta e blindatura Kerberos su Supportato o Fornisci sempre attestazioni.
  • Tutti i dispositivi con Credential Guard a cui gli utenti saranno limitati devono essere configurati per supportare la blindatura Kerberos. Abilitare il supporto client Kerberos per attestazioni, autenticazione composta e blindatura Kerberos Criteri di gruppo impostazioni in Configurazione computer ->Modelli amministrativi ->Sistema ->Kerberos.

Proteggere i segreti dei dispositivi aggiunti a un dominio

Poiché i dispositivi aggiunti a un dominio usano anche segreti condivisi per l'autenticazione, questi segreti possono comunque essere rubati. Attraverso la distribuzione di certificati del dispositivo con Credential Guard, la chiave privata può essere protetta. I criteri di autenticazione possono quindi richiedere agli utenti di accedere ai dispositivi che eseguono l'autenticazione usando tali certificati. In questo modo, si impedisce che segreti condivisi rubati dal dispositivo vengano usati con credenziali utente rubate per accedere al posto dell'utente.

L'autenticazione dei certificati del dispositivo aggiunto al dominio impone i requisiti seguenti:

  • Gli account dei dispositivi si trovano al livello di funzionalità del dominio Windows Server 2012 o superiore.
  • Tutti i controller di dominio in questi domini hanno certificati KDC che soddisfano i rigorosi requisiti dei certificati per la convalida KDC:
    • EKU per KDC presente
    • Nome di dominio DNS corrispondente al campo DNSName dell'estensione SubjectAltName (SAN)
  • I dispositivi Windows hanno la CA che rilascia i certificati del controller di dominio nell'archivio aziendale.
  • Viene stabilito un processo per garantire l'identità e l'affidabilità del dispositivo in modo analogo a quello con cui si stabilisce l'identità e l'affidabilità di un utente prima di emettere una smart card a suo nome.

Distribuire certificati per dispositivi aggiunti a un dominio

Per garantire che i certificati con il criterio di rilascio necessario siano solo installati sui dispositivi che questi utenti devono usare, devono essere distribuiti manualmente su ogni dispositivo. Le stesse procedure di sicurezza usate per il rilascio di smart card per gli utenti devono essere applicate ai certificati dei dispositivi.

Supponiamo, ad esempio, di voler usare il criterio Garanzia elevata solo su questi dispositivi. Usando un'Autorità di certificazione di Windows Server Enterprise, puoi creare un nuovo modello.

Creare un nuovo modello di certificato

  1. Dalla console di Gestione certificati fare clic con il pulsante destro del mouse su Gestione modelli di > certificato
  2. Fare clic con il pulsante destro del mouse su Modello duplicato di autenticazione > della workstation
  3. Fare clic con il pulsante destro del mouse sul nuovo modello e quindi scegliere Proprietà
  4. Nella scheda Estensioni selezionare Modifica criteri > applicazione
  5. Selezionare Autenticazione client e quindi Rimuovi
  6. Aggiungi l'EKU ID-PKInit-KPClientAuth. Selezionare Aggiungi > nuovo e quindi specificare i valori seguenti:
    • Nome: Autenticazione client Kerberos
    • Identificatore oggetto: 1.3.6.1.5.2.3.4
  7. Nella scheda Estensioni selezionare Modifica criteri di > rilascio
  8. In Criteri di rilascio selezionare Alta garanzia
  9. Nella scheda Nome soggetto deselezionare la casella di controllo Nome DNS e quindi selezionare la casella di controllo Nome entità utente (UPN)

Quindi nei dispositivi che eseguono Credential Guard registra i dispositivi usando il certificato che hai appena creato.

Registrare i dispositivi in un certificato

Eseguire il comando seguente:

CertReq -EnrollCredGuardCert MachineAuthentication

Nota

Dopo aver registrato il certificato di autenticazione della macchina, devi riavviare il dispositivo.

Come usare un criterio di rilascio di un certificato per il controllo dell'accesso

A partire dal livello di funzionalità dominio Windows Server 2008 R2, il supporto dei controller di dominio per la funzionalità di verifica dell'autenticazione consente di associare gli identificatori di oggetto (OID) del criterio di rilascio di un certificato ai gruppi di sicurezza universali. I controller di dominio Windows Server 2012 con supporto per le attestazioni possono associarli alle attestazioni. Per altre informazioni sulla funzionalità di verifica dell'autenticazione, vedi Guida dettagliata alla funzionalità di verifica dell'autenticazione per Servizi di dominio Active Directory in Windows Server 2008 R2 nel sito TechNet.

Per vedere i criteri di rilascio disponibili

  • Lo script get-IssuancePolicy.ps1 mostra tutti i criteri di rilascio disponibili nell'Autorità di certificazione.
    Nel prompt dei comandi di Windows PowerShell esegui questo comando:
.\get-IssuancePolicy.ps1 -LinkedToGroup:All

Per collegare un criterio di rilascio a un gruppo di sicurezza universale

  • Lo script set-IssuancePolicyToGroupLink.ps1 crea un gruppo di sicurezza universale, crea un'unità organizzativa e collega il criterio di rilascio al gruppo di sicurezza universale.
    Nel prompt dei comandi di Windows PowerShell esegui questo comando:
.\set-IssuancePolicyToGroupLink.ps1 -IssuancePolicyName:"<name of issuance policy>" -groupOU:"<Name of OU to create>" -groupName:"<name of Universal security group to create>"

Limitare l'accesso utente

Abbiamo ora completato quanto segue:

  • È stato creato uno speciale criterio di rilascio per un certificato per identificare i dispositivi che soddisfano i criteri di distribuzione richiesti per l'accesso utente.
  • Il criterio è stato collegato a un gruppo di sicurezza universale o a un'attestazione.
  • È stato fornito un modo per i controller di dominio di ottenere i dati di autorizzazione del dispositivo durante l'accesso utente usando la blindatura Kerberos. Rimane da configurare il controllo dell'accesso sui controller di dominio. Questa operazione viene effettuata usando i criteri di autenticazione.

I criteri di autenticazione hanno i requisiti seguenti:

  • Gli account utente si trovano al livello di funzionalità del dominio Windows Server 2012 o in un dominio superiore.

Creazione di un criterio di autenticazione che limita gli utenti allo specifico gruppo di sicurezza universale

  1. Aprire il Centro di amministrazione di Active Directory
  2. Selezionare Authentication New > Authentication Policy (Nuovo criterio di autenticazione)>
  3. Nella casella Nome visualizzato immettere un nome per questo criterio di autenticazione
  4. Nell'intestazione Account selezionare Aggiungi
  5. Nella finestra di dialogo Seleziona utenti, computer o account di servizio digitare il nome dell'account utente da limitare e quindi selezionare OK
  6. Sotto l'intestazione User Sign On (Accesso utente) selezionare il pulsante Modifica
  7. Selezionare Aggiungi una condizione
  8. Nella casella Modifica condizioni Controllo di accesso assicurarsi di leggere Il membro del gruppo > di > utenti di ogni > valore e quindi selezionare Aggiungi elementi
  9. Nella finestra di dialogo Seleziona utenti, computer o account di servizio digitare il nome del gruppo di sicurezza universale creato con lo script set-IssuancePolicyToGroupLink e quindi selezionare OK
  10. Selezionare OK per chiudere la casella Modifica condizioni Controllo di accesso
  11. Selezionare OK per creare i criteri di autenticazione
  12. Selezionare Centro di amministrazione di Active Directory

Nota

Quando il criterio di autenticazione applica le restrizioni del criterio, gli utenti non saranno in grado di eseguire l'accesso usando dispositivi che non dispongono di un certificato con il criterio di rilascio appropriato distribuito. Questa regola si applica sia agli scenari di accesso locale sia a quelli di accesso remoto. Pertanto, è consigliabile controllare prima di tutto solo le restrizioni dei criteri per garantire che non si verifichino errori imprevisti.

Individuare gli errori di autenticazione dovuti ai criteri di autenticazione

Per semplificare il monitoraggio degli errori di autenticazione causati dai criteri di autenticazione, esiste un registro operativo contenente esclusivamente questi eventi. Per abilitare i log nei controller di dominio, in Visualizzatore eventi passare a Registri applicazioni e servizi\Microsoft\Windows\Authentication, fare clic con il pulsante destro del mouse su AuthenticationPolicyFailures-DomainController e quindi selezionare Abilita log.

Per altre informazioni sugli eventi dei criteri di autenticazione, vedi l'argomento relativo ai criteri di autenticazione e silo dei criteri di autenticazione.

Appendice: Script

Ecco un elenco degli script citati in questo argomento.

Ottenere i criteri di rilascio disponibili nell'Autorità di certificazione

Salva questo file script come 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

In caso di problemi a eseguire lo script, prova a sostituire la virgoletta singola dopo il parametro ConvertFrom-StringData.

Salva il file script come 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

In caso di problemi a eseguire lo script, prova a sostituire la virgoletta singola dopo il parametro ConvertFrom-StringData.