colinardo
Goto Top

Erstellen eines neuen Attributes für Benutzerobjekte im Active Directory Schema


back-to-topEinleitung

Da immer mal wieder die Frage kommt wie man ein neues AD-Attribut dem AD-Schema hinzufügen kann, habe ich dazu mal die nötigen Schritte in einer Schritt für Schritt-Anleitung zusammengefasst.
Diese Anleitung vermittelt die nötigen Schritte welche nötig sind um ein benutzerdefiniertes Attribut dem Active Directory Schema hinzuzufügen. In diesem Beispiel wird dieses Attribut der Benutzer-Klasse im AD zugewiesen und kann dann in jedem Benutzerobjekt verwendet werden.

back-to-top1. Registrieren des Schema-Management Plugins für die Verwaltung mit der MMC

Dazu öffnen wir eine Administrative Konsole und geben folgenden Befehl ein:
regsvr32 schmmgmt.dll
Die erfolgreiche Registrierung wird uns mit einem Dialog bestätigt.

back-to-top2. Öffnen einer MMC Konsole und Hinzufügen des AD-Schema Verwaltungs-SnapIns

Wichtiger Hinweis: Bevor wir fortfahren solltet Ihr sicherstellen das der genutzte Account über genügend Rechte zum Bearbeiten des AD-Schemas verfügt. Der Account sollte Mitglied der Schema-Admins Gruppe sein und die MMC muss mit dem DC verbunden sein der die Schema-Master Rolle inne hat.

Wir öffnen nun eine neue leere MMC mit dem Befehl mmc.exe, und fügen das Schema-Plugin wie im Bild zu sehen ist hinzu.

1c990d1de2e641d962aaa7040ebab280

back-to-top3. Erstellen des neuen Attributes

Jetzt navigieren wir im Schema zum Knoten Attribute und erstellen mit einem Rechtsklick auf diesen und Attribut erstellen ein neues Attribut:

da8f7d0f71216084226d7acc1b928b54

Es kommt nun der wichtige Hinweis das das Erstellen eines Attributes nicht rückgängig gemacht werden kann und dieses auch nicht mehr aus dem Schema gelöscht, sondern höchstens deaktiviert werden kann!

Diesen Dialog bestätigen wir mit Weiter.

back-to-top3.1 Generieren einer eindeutigen OID für unser Attribut

Bevor wir jetzt im nächsten Dialog weiter machen, müssen wir uns eine eindeutige ID (OID) für das Attribut generieren. Dazu gibt es einige Möglichkeiten ich zeige hier zwei mögliche mit Powershell und VBS:

back-to-top3.1.a Powershell-Variante

[regex]::match([guid]::NewGuid().GUID,'^(.{4})(.{4})-(.{4})-(.{4})-(.{4})-(.{6})(.{6})$') | %{"1.2.840.113556.1.8000.2554.$(($_.Groups[1..6] | %{[convert]::ToUInt64($_,16)}) -join '.')"}  

back-to-top3.1.b VBS-Variante

Das VBS-Script stammt von der Technet-Seite)
' oidgen.vbs   
'    
' THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED    
' OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR    
' FITNESS FOR A PARTICULAR PURPOSE.   
'   
' Copyright (c) Microsoft Corporation. All rights reserved   
'   
' This script is not supported under any Microsoft standard support program or service.    
' The script is provided AS IS without warranty of any kind. Microsoft further disclaims all   
' implied warranties including, without limitation, any implied warranties of merchantability   
' or of fitness for a particular purpose. The entire risk arising out of the use or performance   
' of the scripts and documentation remains with you. In no event shall Microsoft, its authors,   
' or anyone else involved in the creation, production, or delivery of the script be liable for    
' any damages whatsoever (including, without limitation, damages for loss of business profits,    
' business interruption, loss of business information, or other pecuniary loss) arising out of    
' the use of or inability to use the script or documentation, even if Microsoft has been advised    
' of the possibility of such damages.   
' ----------------------------------------------------------------------   
Function GenerateOID() 
    'Initializing Variables   
    Dim guidString, oidPrefix 
    Dim guidPart0, guidPart1, guidPart2, guidPart3, guidPart4, guidPart5, guidPart6 
    Dim oidPart0, oidPart1, oidPart2, oidPart3, oidPart4, oidPart5, oidPart6 
    On Error Resume Next 
    'Generate GUID   
    Set TypeLib = CreateObject("Scriptlet.TypeLib")   
    guidString = TypeLib.Guid 
    'If no network card is available on the machine then generating GUID can result with an error.   
    If Err.Number <> 0 Then 
        Wscript.Echo "ERROR: Guid could not be generated, please ensure machine has a network card."   
        Err.Clear 
        WScript.Quit 
    End If 
    'Stop Error Resume Next   
    On Error GoTo 0 
    'The Microsoft OID Prefix used for the automated OID Generator   
    oidPrefix = "1.2.840.113556.1.8000.2554"   
    'Split GUID into 6 hexadecimal numbers   
    guidPart0 = Trim(Mid(guidString, 2, 4)) 
    guidPart1 = Trim(Mid(guidString, 6, 4)) 
    guidPart2 = Trim(Mid(guidString, 11, 4)) 
    guidPart3 = Trim(Mid(guidString, 16, 4)) 
    guidPart4 = Trim(Mid(guidString, 21, 4)) 
    guidPart5 = Trim(Mid(guidString, 26, 6)) 
    guidPart6 = Trim(Mid(guidString, 32, 6)) 
    'Convert the hexadecimal to decimal   
    oidPart0 = CLng("&H" & guidPart0)   
    oidPart1 = CLng("&H" & guidPart1)   
    oidPart2 = CLng("&H" & guidPart2)   
    oidPart3 = CLng("&H" & guidPart3)   
    oidPart4 = CLng("&H" & guidPart4)   
    oidPart5 = CLng("&H" & guidPart5)   
    oidPart6 = CLng("&H" & guidPart6)   
    'Concatenate all the generated OIDs together with the assigned Microsoft prefix and return   
    GenerateOID = oidPrefix & "." & oidPart0 & "." & oidPart1 & "." & oidPart2 & "." & oidPart3 & _   
        "." & oidPart4 & "." & oidPart5 & "." & oidPart6   
End Function 
'Output the resulted OID with best practice info   
Wscript.Echo "Your root OID is: " & VBCRLF & GenerateOID & VBCRLF & VBCRLF & VBCRLF & _   
    "This prefix should be used to name your schema attributes and classes. For example: " & _   
    "if your prefix is ""Microsoft"", you should name schema elements like ""microsoft-Employee-ShoeSize"". " & _   
    "For more information on the prefix, view the Schema Naming Rules in the server " & _    
    "Application Specification (http://www.microsoft.com/windowsserver2003/partners/isvs/appspec.mspx)." & _   
    VBCRLF & VBCRLF & _ 
    "You can create subsequent OIDs for new schema classes and attributes by appending a .X to the OID where X may " & _   
    "be any number that you choose.  A common schema extension scheme generally uses the following structure:" & VBCRLF & _   
    "If your assigned OID was: 1.2.840.113556.1.8000.2554.999999" & VBCRLF & VBCRLF & _   
    "then classes could be under: 1.2.840.113556.1.8000.2554.999999.1 " & VBCRLF & _    
    "which makes the first class OID: 1.2.840.113556.1.8000.2554.999999.1.1" & VBCRLF & _   
    "the second class OID: 1.2.840.113556.1.8000.2554.999999.1.2     etc..." & VBCRLF & VBCRLF & _   
    "Using this example attributes could be under: 1.2.840.113556.1.8000.2554.999999.2 " & VBCRLF & _   
    "which makes the first attribute OID: 1.2.840.113556.1.8000.2554.999999.2.1 " & VBCRLF & _   
    "the second attribute OID: 1.2.840.113556.1.8000.2554.999999.2.2     etc..." & VBCRLF & VBCRLF & _   
     "Here are some other useful links regarding AD schema:" & VBCRLF & _   
    "Understanding AD Schema" & VBCRLF & _   
    "http://technet2.microsoft.com/WindowsServer/en/Library/b7b5b74f-e6df-42f6-a928-e52979a512011033.mspx " & _   
    VBCRLF & VBCRLF & _ 
    "Developer documentation on AD Schema:" & VBCRLF & _   
    "http://msdn2.microsoft.com/en-us/library/ms675085.aspx " & VBCRLF & VBCRLF & _   
    "Extending the Schema" & VBCRLF & _   
    "http://msdn2.microsoft.com/en-us/library/ms676900.aspx " & VBCRLF & VBCRLF & _   
    "Step-by-Step Guide to Using Active Directory Schema and Display Specifiers " & VBCRLF & _   
    "http://www.microsoft.com/technet/prodtechnol/windows2000serv/technologies/activedirectory/howto/adschema.mspx " & _   
    VBCRLF & VBCRLF & _ 
    "Troubleshooting AD Schema " & VBCR & _   
    "http://technet2.microsoft.com/WindowsServer/en/Library/6008f7bf-80de-4fc0-ae3e-51eda0d7ab651033.mspx  " & _   
    VBCRLF & VBCRLF 
Wir starten das Script und erhalten einen Dialog in dem ganz oben die generierte ID steht. Diese ID notieren wir uns für den nächsten Schritt.

c9b885de02950acbb73aa696a0c6ecac

back-to-top3.2 Attribut-Eigenschaften festlegen
Jetzt springen wir wieder zurück zum Dialog für das neue Attribut und geben dort die benötigten Informationen ein:
Feld Einzufügender Wert
Allgemeiner Name Kann frei gewählt werden
LDAP Anzeigename Wird aus "Allgemeiner Name" generiert, kann angepasst werden, darf aber keine Leerzeichen beinhalten.
Eindeutige X500-OID Hier fügen wir die gerade eben generierte OID ein.
Beschreibung(Optional) Optionale Beschreibung unseres Atttributes
Syntax Hier wählen wir den Typ des Attributes aus (Text/Zahl/ etc.)
Minimum und Maximum(Optional) Hier können wir im Falle vom Typ Unicode-Zeichenfolge die minimale und maximale Länge des Textes in Zeichen angeben die das Attribut haben darf.

50dfd7b64fc3a2421afd2e6c79d1942d

Zum Schluss schließen wir den Dialog mit OK und überprüfen ob unser Attribut auch in der Liste auftaucht:

7eaaad3bd0ae7bfeb67c8f051f8c2657

back-to-top4. Hinzufügen des Attributes zum Klassen-Objekt

Damit das Attribut nun bei unseren Usern verfügbar wird, muss es noch der User-Klasse im Schema zugeordnet werden:

8ce6b01f6a8815124ad74cd527c531c9

back-to-top5. Neustarten des Dienstes "Active Directory-Domänendienste"

Damit die Änderungen übernommen werden müssen wir den Dienst "Active Directory-Domänendienste" und dessen abhängige Dienste neu starten:

91aabbe84995a41312d9e472ec3c5aee

95d5f4fc08023d915021b907a6ea8116

back-to-top6. Überprüfen des neuen Attributes


Dazu öffnen wir Active Directory-Benutzer und -Computers und aktivieren im Menü Ansicht die Option Erweiterte Features, damit der Tab Attribut-Editor in unsererm User-Objekt sichtbar wird:
(Hinweis: Falls die MMC-Konsole bereits offen war als wir die Dienste neu gestartet haben muss die Konsole einmal geschlossen und wieder neu geöffnet werden, sonst ist das neue Attribut nicht sichtbar)

205e2733aa5dd15071017eaf431b3446

Eventuell müsst Ihr mit dem Button Filter das Häkchen bei Nur Attribute mit Werten anzeigen entfernen damit Ihr das neue Attribut sehen könnt.

back-to-top7. Powershell-Funktion für das gesamte Automatisieren des Vorganges

Zur Vereinfachung des gesamten Vorgangs von oben, hier noch ein Powershell-Skript das den ganzen Vorgang in einer Funktion Add-ADSchemaUserAttribute zusammenfasst. Zusätzlich führt es abschließend einen Refresh des Schema-Caches auf dem Schema-Master durch womit das Attribut schneller überall nutzbar wird. Bitte beachten das für den Vorgang natürlich Enterprise-Admin Rechte erforderlich sind.
function Add-ADSchemaUserAttribute {
    param(
        [Parameter(Mandatory=$true)][string]$Name,
        [Parameter(Mandatory=$true)][ValidateSet('Object(DN-DN)','String(Object-Identifier)','Case-Sensitive String','CaseIgnoreString(Teletex)','String(Printable)','String(IA5)','String(Numeric)','Object(DN-Binary)','Boolean','Integer','Integer Enumeration','String(Octet)','String(UTC-Time)','String(Generalized-Time)','String(Unicode)','Object(Presentation-Address)','Object(DN-String)','String(NT-Sec-Desc)','LargeInteger','String(Sid)')][string]$DataType,  
        [Parameter(Mandatory=$true)][string]$Description,
        [Parameter(Mandatory=$false)][bool]$IsSingleValued = $true,
        [Parameter(Mandatory=$false)][int32]$searchflags = 1,
        [Parameter(Mandatory=$false)][int]$rangeLower,
        [Parameter(Mandatory=$false)][int]$rangeUpper,
        [Parameter(Mandatory=$false)][bool]$extendedCharsAllowed

    )
    Import-Module ActiveDirectory
    
    # Funktion um neue OID zu generieren
    $getnewoid = {"1.2.840.113556.1.8000.2554.$(([regex]::Match([System.Guid]::NewGuid().ToString(),'(.{4})(.{4})-(.{4})-(.{4})-(.{4})-(.{6})(.{6})').Groups | select -skip 1 | %{[Convert]::ToUInt64($_.Value,16)}) -join '.')"}  
    
    # DataTypes :https:{{comment_single_line_double_slash:0}}
    $datatype_map = @{
        'Object(DN-DN)' = @{o=127;a='2.5.5.1'}  
        'String(Object-Identifier)' = @{o=6;a='2.5.5.2'}  
        'Case-Sensitive String' = @{o=27;a='2.5.5.3'}  
        'CaseIgnoreString(Teletex)' = @{o=20;a='2.5.5.4'}  
        'String(Printable)' = @{o=19;a='2.5.5.5'}  
        'String(IA5)' = @{o=22;a='2.5.5.5'}  
        'String(Numeric)' = @{o=18;a='2.5.5.6'}  
        'Object(DN-Binary)' = @{o=127;a='2.5.5.7'}  
        'Boolean' = @{o=1;a='2.5.5.8'}  
        'Integer' = @{o=2;a='2.5.5.9'}  
        'Integer Enumeration' = @{o=10;a='2.5.5.9'}  
        'String(Octet)' = @{o=4;a='2.5.5.10'}  
        'String(UTC-Time)' = @{o=23;a='2.5.5.11'}  
        'String(Generalized-Time)'= @{o=24;a='2.5.5.11'}  
        'String(Unicode)' = @{o=64;a='2.5.5.12'}  
        'Object(Presentation-Address)'= @{o=127;a='2.5.5.13'}  
        'Object(DN-String)' = @{o=127;a='2.5.5.14'}  
        'String(NT-Sec-Desc)' = @{o=66;a='2.5.5.15'}  
        'LargeInteger' = @{o=65;a='2.5.5.16'}  
        'String(Sid)' = @{o=4;a='2.5.5.17'}  
    }
    
    # Wenn Attribut schon existiert Fehler generieren
    if ((Get-ADObject -SearchBase (Get-ADRootDSE).schemaNamingContext -Filter "ObjectClass -eq 'attributeSchema' -and name -eq '$Name'")){  
        Write-Error -Message "Ein Attribut mit diesem Namen existiert bereits!"  
        return
    }

    $schemaPath = (Get-ADRootDSE).schemaNamingContext
    $userSchema = get-adobject -SearchBase $schemapath -Filter "name -eq 'user'"  
    # Neue OID generieren
    $newoid = .$getnewoid
    # Wenn OID schon existiert neue erstellen
    while(Get-ADObject -SearchBase $schemaPath -Filter "ObjectClass -eq 'attributeSchema' -and attributeID -eq '$newoid'"){  
        $newoid = .$getnewoid
    }
    <# 
       	Attribute-Schema: https://technet.microsoft.com/en-us/library/cc961746.aspx
	    SearchFlags: http://www.frickelsoft.net/blog/?p=151
    #>
    $attributes = @{
        LDAPDisplayName = $Name
        attributeId = $newoid
        oMSyntax = $Datatype_map[$DataType].o
        attributeSyntax = $Datatype_map[$DataType].a
        isSingleValued = $IsSingleValued
        adminDescription = $Description
        searchflags = $searchflags
    }
    if ($rangeLower -ne $null){$attributes.rangeLower = $rangeLower}
    if ($rangeUpper -ne $null){$attributes.rangeUpper = $rangeUpper}
    if ($extendedCharsAllowed -ne $null){$attributes.extendedCharsAllowed = $extendedCharsAllowed}

    write-host "Adding attribute..." -F Green  
    New-ADObject -Name $Name -Type attributeSchema -Path $schemapath -OtherAttributes $attributes
    write-host "Adding attribute tu User-Schema..." -F Green  
    $userSchema | Set-ADObject -Add @{mayContain=$Name}

    # Force Update AD-Schema cache
    write-host "Updating Schema cache ..." -F Green  
    $root = [ADSI]"LDAP://$((Get-ADForest).SchemaMaster)/RootDSE"  
    $root.put("schemaUpdateNOW",1)  
    $root.SetInfo()
    write-host "Finished" -F Green  
}
Der Aufruf erfolgt dann bspw. wie folgt:
Add-ADSchemaUserAttribute -Name 'MeinNeuesAttribut' -DataType 'String(Unicode)'

Viel Spaß face-smile

Grüße @colinardo


back-to-top9. Updates

DatumÄnderung
19.04.2023 OID Möglichkeit aktualisiert
20.01.2019 Hinweis auf benötigte Gruppenmitgliedschaft zur Bearbeitung des Schemas unter Punkt 2 hinzugefügt
18.01.2017 Powershell-Funktion zur Automatisierung des Vorgangs unter Punkt 7. hinzugefügt

Content-ID: 227268

Url: https://administrator.de/contentid/227268

Ausgedruckt am: 22.11.2024 um 07:11 Uhr

Belloci
Belloci 31.01.2014 um 11:51:34 Uhr
Goto Top
Hallo Colinardo,

da mich u.a. gerade dieses Thema sehr interessiert, habe ich das einfach mal step by step nachgemacht um Andere und auch dich eventuell auf Fehler / Probleme hinzuweisen. "Leider" ist dem nichts hinzuzufügen außer ein herzliches Dankeschön!

Super Sache und Gruß
Belloci
colinardo
colinardo 18.01.2017 aktualisiert um 16:27:46 Uhr
Goto Top
Nur zur Info für alle die es interessiert: Dem Beitrag wurde noch eine Powershell-Funktion hinzugefügt die den Vorgang komplett automatisiert.

Grüße @colinardo
TOAOICE
TOAOICE 03.08.2020 um 13:02:51 Uhr
Goto Top
Hallo,
ich brauchte soeben dein Anleitung. Alles hat soweit auf anhieb geklappt. Danke dafür.
Mein Problem ist, dass ich das erzeugte Attribut über Powershell füllen möchte. Dabei laufe ich auf einen Fehler da er mir mitteilt dass er das eigene Attribut nicht als Parameter findet.
z.B. set-Aduser XY -meinattrib "hier soll was stehen"

wenn ich den Befehl lostretet kommt der Fehler.

Mache ich aber ein get-aduser | fl sehe ich das erzeugte attribut.

Was muss ich tun um hier weiterzukommen.

Danke
colinardo
colinardo 03.08.2020 aktualisiert um 13:17:37 Uhr
Goto Top
Servus @TOAOICE !
da er mir mitteilt dass er das eigene Attribut nicht als Parameter findet.
z.B. set-Aduser XY -meinattrib "hier soll was stehen"
Kann er so auch nicht, du kannst nicht einfach einen Parameter "erfinden" das CMDLet selbst hat ja nur fest definierte Parameter face-wink.

Für benutzerdefinierte Attribute machst du das stattdessen so
Set-Aduser XY -Replace @{"NamedesAttributes"="hier soll was stehen"}  
Es gibt hier im selben Kontext zusätzlich auch noch die Parameter -Add, -Remove und -Clear, zum einen für das Hinzufügen von Werten zu Multi-Valued Properties, zum Entfernen derselbigen und zu guter Letzt zum Löschen des Inhalts eines Attributes.

Siehe auch die detaillierten Beispiel in der Doku
https://docs.microsoft.com/en-us/powershell/module/addsadministration/se ...

Grüße Uwe
TOAOICE
TOAOICE 03.08.2020 um 13:44:00 Uhr
Goto Top
Servus Colinardo,

danke für die prompte Rückmeldung.
Hat funktioniert.

Gruß TOAOICE
PeterPanter
PeterPanter 24.03.2023 um 10:45:08 Uhr
Goto Top
Hallo Colinardo,

vielen Dank für die klasse Anleitung. Mussten unser AD um ein "gender"-Attribut erweitern und hat mit deiner Hilfe problemlos funktioniert. Zur Info: Auf dem Windows Server 2019 V1809 musste ich das Schema-Management mit

regsvr32 schmmgmt.dll

registrieren. (nicht schemamgmt.dll)

Viele Grüße / Peter
colinardo
colinardo 24.03.2023 aktualisiert um 10:55:55 Uhr
Goto Top
Zitat von @PeterPanter:
Zur Info: Auf dem Windows Server 2019 V1809 musste ich das Schema-Management mit

regsvr32 schmmgmt.dll

registrieren. (nicht schemamgmt.dll)

Servus Peter,
danke für deine Nachricht. Ohh ja, tatsächlich ein Tippfehler, habe ich oben korrigiert, herzlichen Dank!

Grüße Uwe