Weitere Risikominderungen

Credential Guard bietet Gegenmaßnahmen gegen Angriffe auf abgeleitete Anmeldeinformationen und verhindert die Verwendung gestohlener Anmeldeinformationen an anderer Stelle. Geräte können jedoch weiterhin anfällig für bestimmte Angriffe sein, auch wenn die abgeleiteten Anmeldeinformationen durch Credential Guard geschützt sind. Diese Angriffe können den Missbrauch von Berechtigungen und die Verwendung abgeleiteter Anmeldeinformationen direkt von einem kompromittierten Gerät, die erneute Verwendung gestohlener Anmeldeinformationen vor der Aktivierung von Credential Guard sowie den Missbrauch von Verwaltungstools und schwachen Anwendungskonfigurationen umfassen. Aus diesem Gründen muss auch eine zusätzliche Entschärfung bereitgestellt werden, um die Domänenumgebung stabiler zu machen.

Zusätzliche Sicherheitsqualifikationen

Alle Geräte, die den grundlegenden Schutz für Hardware, Firmware und Software erfüllen, können Credential Guard verwenden.
Geräte, die mehr Qualifikationen erfüllen, können zusätzlichen Schutz bieten, um die Angriffsfläche weiter zu reduzieren.

In der folgenden Tabelle sind die Qualifikationen für verbesserte Sicherheit aufgeführt. Es wird empfohlen, die zusätzlichen Qualifikationen zu erfüllen, um das Sicherheitsniveau zu erhöhen, das Credential Guard bieten kann.

Schutz Anforderungen Sicherheitsvorteile
Konfiguration und Verwaltung des sicheren Starts – BIOS-Kennwort oder stärkere Authentifizierung muss unterstützt
werden. In der BIOS-Konfiguration muss die BIOS-Authentifizierung festgelegt
werden. Es muss Unterstützung für die geschützte BIOS-Option vorhanden sein, um die Liste der zulässigen Startgeräte (z. B. Nur von der internen Festplatte starten) und die Startgerätereihenfolge zu konfigurieren, wobei änderungen durch das Betriebssystem außer Kraft gesetzt BOOTORDER werden.
– Verhindern, dass andere Betriebssysteme gestartet werden
- Verhindern von Änderungen an den BIOS-Einstellungen
Sicherer Start der Hardwareroot Trust Platform – Startintegrität (Platform Secure Boot) muss unterstützt werden. Weitere Informationen finden Sie in den Anforderungen des Windows-Hardwarekompatibilitätsprogramms unter System.Fundamentals.Firmware.CS.UEFISecureBoot.ConnectedStandby
– Hardware Security Test Interface (HSTI) muss implementiert werden. Weitere Informationen finden Sie unter Hardwaresicherheitstestbarkeitsspezifikation.
– Startintegrität (sicherer Plattformstart) nach dem Einschalten bietet Schutzmaßnahmen vor physisch anwesenden Angreifern und eine tiefengestaffelte Verteidigung gegen Schadsoftware.
- HSTI bietet Sicherheit für korrekt gesichertes Silizium und Plattform
Firmwareupdate über Windows Update - Firmware muss Feldupdates über Windows Update- und UEFI-Kapselungsupdates unterstützen Stellt sicher, dass Firmwareupdates schnell, sicher und zuverlässig sind.
Sichern von Startkonfiguration und -verwaltung - Erforderliche BIOS-Funktionen: Fähigkeit des OEM zum Hinzufügen eines ISV-, OEM- oder Enterprise-Zertifikats in der Datenbank für den sicheren Start zur Herstellungszeit
: Erforderliche Konfigurationen: Microsoft UEFI-Zertifizierungsstelle muss aus der Datenbank für den sicheren Start entfernt werden. Die Unterstützung für UEFI-Module von Drittanbietern ist zulässig, sollte jedoch von ISV bereitgestellte Zertifikate oder OEM-Zertifikate für die spezifische UEFI-Software verwenden.
- Unternehmen können die Ausführung
proprietärer EFI-Treiber/-Anwendungen zulassen: Durch das Entfernen der Microsoft UEFI-Zertifizierungsstelle aus der Datenbank für den sicheren Start erhalten Unternehmen vollständige Kontrolle über Software, die ausgeführt wird, bevor das Betriebssystem gestartet wird.
VBS-Aktivierung des No-Execute (NX)-Schutzes für UEFI-Laufzeitdienste – VBS aktiviert NX-Schutz für UEFI-Laufzeitdienstcode und Datenspeicherregionen. UEFI-Laufzeitdienstcode muss Maßnahmen für den schreibgeschützten Seitenschutz unterstützen, und UEFI-Laufzeitdienstdaten dürfen nicht ausführbar sein. Der UEFI-Laufzeitdienst muss die folgenden Anforderungen erfüllen:
– Implementieren von UEFI 2.6 EFI_MEMORY_ATTRIBUTES_TABLE. Der gesamte Arbeitsspeicher des UEFI-Laufzeitdiensts (Code und Daten) muss in dieser Tabelle
beschrieben werden. PE-Abschnitte müssen im Arbeitsspeicher seitenbündig ausgerichtet sein (für nicht flüchtigen Speicher nicht erforderlich).
– Die Tabelle mit den Arbeitsspeicherattributen muss Code und Daten ordnungsgemäß als RO/NX für die Konfiguration durch das Betriebssystem
kennzeichnen. Alle Einträge müssen Attribute EFI_MEMORY_RO, EFI_MEMORY_XPoder beides enthalten.
– Keines der oben genannten Attribute darf keines der Einträge erhalten, was auf Arbeitsspeicher hinweist, der sowohl ausführbare als auch schreibbar ist. Der Arbeitsspeicher muss entweder lesbar und ausführbar oder schreibbar und nicht ausführbar
sein (SIEHE WICHTIGE INFORMATIONEN NACH DIESER TABELLE).
– Sicherheitsrisiken in der UEFI-Runtime werden ggf. vor einer Kompromittierung von VBS blockiert (z. B. in Funktionen wie UpdateCapsule und SetVariable):
Reduziert die Angriffsfläche für VBS von der Systemfirmware.
Firmwareunterstützung für SMM-Schutz – Die WSMT-Spezifikation (Windows SMM Security Mitigations Table) enthält Details zu einer ACPI-Tabelle, die für die Verwendung mit Windows-Betriebssystemen erstellt wurde, die virtualisierungsbasierte Windows-Features unterstützen. – Schützt vor potenziellen Sicherheitsrisiken in UEFI-Laufzeitdiensten, falls vorhanden, wird verhindert, dass VBS kompromittiert wird (z. B. in Funktionen wie UpdateCapsule und SetVariable).
– Reduziert die Angriffsfläche für VBS von der Systemfirmware
– Blockiert zusätzliche Sicherheitsangriffe auf SMM

Wichtig

Zur VBS-Aktivierung des NX-Schutzes für UEFI-Laufzeitdienste:

  • Dies gilt nur für den Arbeitsspeicher des UEFI-Laufzeitdiensts und nicht für den Arbeitsspeicher des UEFI-Startdiensts.
  • Der Schutz wird von VBS auf Betriebssystemseitentabellen angewendet.
  • Verwenden Sie keine Abschnitte, die sowohl beschreibbar als auch ausführbar sind.
  • Versuchen Sie nicht, den ausführbaren Systemspeicher direkt zu ändern.
  • Keinen dynamischen Code verwenden

Einschränken von Domänenbenutzern auf bestimmte in die Domäne eingebundene Geräte

Angriffe mit dem Ziel des Diebstahls von Anmeldeinformationen ermöglichen es dem Angreifer, geheime Schlüssel von einem Gerät zu stehlen und auf einem anderen Gerät zu verwenden. Wenn sich ein Benutzer auf mehreren Geräten anmelden kann, können von jedem dieser Geräte Anmeldeinformationen gestohlen werden. Wie stellen Sie sicher, dass sich Benutzer nur mit Geräten anmelden, auf denen Credential Guard aktiviert ist? Durch Die Bereitstellung von Authentifizierungsrichtlinien, die sie auf bestimmte in die Domäne eingebundene Geräte beschränken, die mit Credential Guard konfiguriert wurden. Damit der Domänencontroller weiß, von welchem Gerät sich ein Benutzer anmeldet, muss der Kerberos-Schutz verwendet werden.

Kerberos-Schutz

Der Kerberos-Schutz ist Teil des Standards RFC 6113. Wenn der Kerberos-Schutz von einem Gerät unterstützt wird, wird der Besitzernachweis des Benutzers mittels TGT geschützt, um Angriffe auf das Offlinewörterbuch abzuwehren. Der Kerberos-Schutz bietet als weiteren Vorteil signierte KDC-Fehler. Dadurch können Manipulationen abgewehrt werden, die möglicherweise zu Downgradeangriffen führen.

So aktivieren Sie kerberos armoring zum Einschränken von Domänenbenutzern auf bestimmte in die Domäne eingebundene Geräte:

  • Benutzer müssen Domänen angehören, in denen Windows Server 2012 R2 oder höher ausgeführt wird.
  • Alle Domänencontroller in diesen Domänen müssen für die Unterstützung des Kerberos-Schutzes konfiguriert werden. Legen Sie die Gruppenrichtlinieneinstellung Unterstützung des Kerberos-Domänencontrollers für Ansprüche, Verbundauthentifizierung und Kerberos-Schutz auf Unterstützt oder Immer Ansprüche liefern fest.
  • Alle Geräte mit Credential Guard, auf die die Benutzer beschränkt werden, müssen so konfiguriert werden, dass sie kerberos armoring unterstützen. Aktivieren Sie die Kerberos-Clientunterstützung für Ansprüche, Verbundauthentifizierung und Kerberos Armoring Gruppenrichtlinie Einstellungen unter Computerkonfiguration ->Administrative Vorlagen ->System ->Kerberos.

Schützen von in die Domäne eingebundenen Gerätegeheimnissen

Da in die Domäne eingebundene Geräte zudem gemeinsame geheime Schlüssel für die Authentifizierung verwenden, können Angreifer diese geheimen Schlüssel auch stehlen. Durch die Bereitstellung von Gerätezertifikaten mit Credential Guard kann der private Schlüssel geschützt werden. Dann können Authentifizierungsrichtlinien erfordern, dass sich Benutzer bei Geräten anmelden, die sich mit diesen Zertifikaten authentifizieren. Dies verhindert, dass gemeinsame vom Gerät gestohlene, geheime Schlüssel mit gestohlenen Benutzeranmeldeinformationen verwendet werden, um eine Benutzeranmeldung vorzunehmen.

Für die Zertifikatauthentifizierung eines in die Domäne eingebundenen Geräts ist Folgendes erforderlich:

  • Die Gerätekonten müssen mindestens Windows Server 2012 als Domänenfunktionsebene aufweisen.
  • Alle Domänencontroller dieser Domänen müssen über KDC-Zertifikate verfügen, die strenge Zertifikatanforderungen bei der KDC-Überprüfung erfüllen:
    • Die erweiterte Schlüsselverwendung für das KDC muss vorhanden sein.
    • Der DNS-Domänenname muss dem DNSName-Feld der Erweiterung SubjectAltName (SAN) entsprechen.
  • Windows-Geräte verfügen über die Zertifizierungsstelle, die die Domänencontrollerzertifikate im Unternehmensspeicher ausstellt.
  • Ein Prozess wird eingerichtet, um die Identität und die Vertrauenswürdigkeit des Geräts auf ähnliche Weise sicherzustellen, wie Sie die Identität und Vertrauenswürdigkeit eines Benutzers feststellen würden, bevor Sie ihm eine Smartcard zuweisen.

Bereitstellen von in die Domäne eingebundenen Gerätezertifikaten

Um sicherzustellen, dass nur Zertifikate mit der erforderlichen Ausstellungsrichtlinie auf den für die Benutzer vorgesehenen Geräten installiert werden, müssen die Zertifikate auf jedem Gerät manuell bereitgestellt werden. Die Sicherheitsverfahren, die für das Ausstellen von Smartcards für Benutzer gelten, sollten auch auf Gerätezertifikate angewendet werden.

Nehmen wir beispielsweise an, Sie möchten die Richtlinie "Hohe Zusicherung" nur auf diesen Geräten verwenden. Sie würden dann mithilfe einer Windows Server Enterprise-Zertifizierungsstelle eine neue Vorlage erstellen.

Erstellen einer neuen Zertifikatvorlage

  1. Klicken Sie in der Zertifikat-Manager-Konsole mit der rechten Maustaste auf Zertifikatvorlagen > verwalten.
  2. Klicken Sie mit der rechten Maustaste auf Die Vorlage "Arbeitsstationsauthentifizierung > duplizieren"
  3. Klicken Sie mit der rechten Maustaste auf die neue Vorlage, und wählen Sie dann Eigenschaften aus.
  4. Wählen Sie auf der Registerkarte Erweiterungendie Option Anwendungsrichtlinien > bearbeiten aus.
  5. Wählen Sie Clientauthentifizierung und dann Entfernen aus.
  6. Fügen Sie die ID-PKInit-KPClientAuth EKU hinzu. Wählen Sie Neu hinzufügen >aus, und geben Sie dann die folgenden Werte an:
    • Name: Kerberos Client Auth
    • Objekt-ID: 1.3.6.1.5.2.3.4
  7. Wählen Sie auf der Registerkarte Erweiterungendie Option Ausstellungsrichtlinien > bearbeiten aus.
  8. Wählen Sie unter Ausstellungsrichtlinien die Option Hohe Sicherheit aus.
  9. Deaktivieren Sie auf der Registerkarte Antragstellername das Kontrollkästchen DNS-Name, und aktivieren Sie dann das Kontrollkästchen Benutzerprinzipalname (UPN)

Registrieren Sie dann auf Geräten, auf denen Credential Guard ausgeführt wird, die Geräte mithilfe des soeben erstellten Zertifikats.

Registrieren von Geräten in einem Zertifikat

Führen Sie den folgenden Befehl aus:

CertReq -EnrollCredGuardCert MachineAuthentication

Hinweis

Sie müssen das Gerät nach der Registrierung des Computerauthentifizierungszertifikats neu starten.

Verwenden einer Zertifikatausstellungsrichtlinie für die Zugriffssteuerung

Ab der Domänenfunktionsebene Windows Server 2008 R2 bietet die Domänencontrollerunterstützung zur Authentifizierungsmechanismussicherung eine Möglichkeit, um OIDs der Zertifikatausstellungsrichtlinie und universelle Sicherheitsgruppen einander zuzuordnen. Windows Server 2012-Domänencontroller, die Ansprüche unterstützen, ermöglichen die Zuordnung zu Ansprüchen. Informationen zur Authentifizierungsmechanismussicherung finden Sie unter Schrittweise Anleitung zur Authentifizierungsmechanismussicherung für AD DS unter Windows Server 2008 R2 auf TechNet.

So zeigen Sie die verfügbaren Ausstellungsrichtlinien an

  • Das Skript get-IssuancePolicy.ps1 zeigt alle Ausstellungsrichtlinien, die für die Zertifizierungsstelle verfügbar sind.
    Führen Sie an der Windows PowerShell-Eingabeaufforderung den folgenden Befehl aus:
.\get-IssuancePolicy.ps1 -LinkedToGroup:All

So verknüpfen Sie eine Ausstellungsrichtlinie mit einer universellen Sicherheitsgruppe

  • Das Skript set-IssuancePolicyToGroupLink.ps1 erstellt eine universelle Sicherheitsgruppe sowie eine Organisationseinheit und verknüpft die Ausstellungsrichtlinie mit dieser universellen Sicherheitsgruppe.
    Führen Sie an der Windows PowerShell-Eingabeaufforderung den folgenden Befehl aus:
.\set-IssuancePolicyToGroupLink.ps1 -IssuancePolicyName:"<name of issuance policy>" -groupOU:"<Name of OU to create>" -groupName:"<name of Universal security group to create>"

Benutzeranmeldung einschränken

Bisher haben wir folgende Schritte ausgeführt:

  • Es wurde eine spezielle Zertifikatausstellungsrichtlinie zur Identifizierung der Geräte erstellt, die die Bereitstellungskriterien erfüllen, die für die Benutzeranmeldung erforderlich sind.
  • Die Richtlinie wurde einer universellen Sicherheitsgruppe oder einem Anspruch zugeordnet.
  • Es wurde eine Möglichkeit für Domänencontroller bereitgestellt, die Geräteautorisierungsdaten während der Benutzeranmeldung mithilfe von Kerberos Armoring abzurufen. Als letzter Schritt muss jetzt nur noch die Zugriffsprüfung für Domänencontroller konfiguriert werden. Dies erfolgt mithilfe von Authentifizierungsrichtlinien.

Für Authentifizierungsrichtlinien gelten folgende Anforderungen:

  • Die Benutzerkonten müssen mindestens die Domänenfunktionsebene Windows Server 2012 aufweisen.

Erstellen einer Authentifizierungsrichtlinie, die Benutzer auf die spezifische universelle Sicherheitsgruppe beschränkt

  1. Öffnen des Active Directory-Verwaltungscenters
  2. Wählen Sie Authentifizierung > Neue > Authentifizierungsrichtlinie aus.
  3. Geben Sie im Feld Anzeigename einen Namen für diese Authentifizierungsrichtlinie ein.
  4. Wählen Sie unter der Überschrift Konten die Option Hinzufügen aus.
  5. Geben Sie im Dialogfeld Benutzer, Computer oder Dienstkonten auswählen den Namen des Benutzerkontos ein, das Sie einschränken möchten, und wählen Sie dann OK aus.
  6. Wählen Sie unter der Überschrift Benutzeranmeldung die Schaltfläche Bearbeiten aus.
  7. Wählen Sie Bedingung hinzufügen aus.
  8. Stellen Sie im Feld Access Control Bedingungen bearbeiten sicher, dass benutzergruppenmitglied >> jedes > Werts angezeigt wird, und wählen Sie dann Elemente hinzufügen aus.
  9. Geben Sie im Dialogfeld Benutzer, Computer oder Dienstkonten auswählen den Namen der universellen Sicherheitsgruppe ein, die Sie mit dem Skript set-IssuancePolicyToGroupLink erstellt haben, und wählen Sie dann OK aus.
  10. Wählen Sie OK aus, um das Feld Access Control Bedingungen bearbeiten zu schließen.
  11. Wählen Sie OK aus, um die Authentifizierungsrichtlinie zu erstellen.
  12. Active Directory-Verwaltungscenter auswählen

Hinweis

Wenn Richtlinieneinschränkungen von der Authentifizierungsrichtlinie erzwungen werden, sind die Benutzer nicht in der Lage, sich über Geräte anzumelden, für die kein Zertifikat mit der entsprechenden Ausstellungsrichtlinie bereitgestellt wurde. Dies Gilt für: die lokale und die Remoteanmeldung. Daher wird dringend empfohlen, zunächst nur Richtlinieneinschränkungen zu überprüfen, damit keine unerwarteten Fehler auftreten.

Ermitteln von Authentifizierungsfehlern aufgrund von Authentifizierungsrichtlinien

Wenn Sie die Nachverfolgung von Authentifizierungsfehlern aufgrund von Authentifizierungsrichtlinien vereinfachen möchten, können Sie ein Betriebsprotokoll verwenden, das nur diese Ereignisse enthält. Navigieren Sie zum Aktivieren der Protokolle auf den Domänencontrollern in Ereignisanzeige zu Anwendungs- und Dienstprotokolle\Microsoft\Windows\Authentication, klicken Sie mit der rechten Maustaste auf AuthenticationPolicyFailures-DomainController, und wählen Sie dann Protokoll aktivieren aus.

Weitere Informationen zu Ereignissen von Authentifizierungsrichtlinien finden Sie unter Authentifizierungsrichtlinien und Authentifizierungsrichtliniensilos.

Anhang: Skripts

Im Folgenden finden Sie eine Liste von Skripts, die in diesem Thema beschrieben werden.

Abrufen der verfügbaren Ausstellungsrichtlinien für die Zertifizierungsstelle

Speichern Sie diese Skriptdatei unter dem Namen 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
    }
}

Hinweis

Wenn bei der Ausführung dieses Skripts Probleme auftreten, ersetzen Sie das einfache Anführungszeichen nach dem Parameter ConvertFrom-StringData.

Speichern Sie die Skriptdatei unter dem Namen 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
}
}

Hinweis

Wenn bei der Ausführung dieses Skripts Probleme auftreten, sollten Sie das einfache Anführungszeichen nach dem Parameter ConvertFrom-StringData ersetzen.