Powershell und das AD: Mehr Flexibilität für „Einzeiler“

26. November 2014

Der Einsatz des Powershell-Cmdlets ForEach zusammen mit der Pipeline-Variablen „$_“ vereinfacht die Verwaltungsarbeiten im Umfeld des Active Dirtectory (AD). Dazu wurden im Beitrag „ForEach und die Pipeline-Variable richtig einsetzen“ bereits Beispiele gezeigt. In einem weiteren Beitrag zeigt der Autor, wie der Administrator noch mehr Flexibilität in seine Powershell-Befehle einbauen kann. Dazu wird ein Beispiel langsam verfeinert.

Bereits im Beitrag „ForEach und die Pipeline-Variable richtig einsetzen“ wurde gezeigt, wie sich mit Hilfe des Cmdlets ForEach und der Pipeline-Variablen $_ mächtige Powershell-Einzeiler erstellen lassen, die bei der Verwaltung im Umfeld des Active Directory (AD) nützlich sind. Wenn man diesen Ansatz weiter treiben möchte, könnte man bei den Benutzerkonten im AD die Attribute „givennamen“ (das ist im AD das Attribute für den Vornamen) und „sn“ („Surname“, also im AD das Attribut für den Nachnamen) heranziehen und daraus automatisch einen „Displayname“ erzeugen, der aus Vornamen und Nachnamen besteht. Damit hätte man für alle Anzeigennamen (Displaynames) im AD (oder den gewünschten Teilbereichen) eine sehr aussagekräftige Bezeichnung automatisch erstellt.

Wer sich an den verwendeten Bezeichnungen im AD stört („Givenname“ für den Vornamen und „sn“ – also „surname“ – für den Familiennamen), dem sei gesagt: Microsoft hat sich beim Anlegen des Schemas im AD an die Vorgaben gehalten, die im Rahmen des internationalen Standards X.500 definiert wurden. Dabei finden die Atribute „givenname“ und „sn“ Verwendung. Mit X.500 sollte eine Vorlage für sämtliche Kommunikationsdienste entstehen, bei denen Benutzernamen und Kennwörter benötigt werden. Die Arbeiten an X.500 begannen bereits in den 80er Jahren des letzten Jahrhunderts – soviel zum Thema „zeitgemäß“. Die AD-Entwickler bei Microsoft hatten sich allerdings erbarmt und ein synthetisches Zusatzattribut namens „Surname“ hinzugefügt, das allerdings nur im Rahmen der Powershell verwendet werden kann. Somit ist das Attribute „surname“ in der Tat nur ein Alias für das „sn“.

Will der Administrator nun einen Powershell-Einzeiler schreiben, empfiehlt sich die übliche Vorgehensweise: Zuerst wird der „Filter“ skizziert – also welche Konten geändert werden sollen. Danach ist die Aktion zu definieren – also der Teil des Befehls, der die eigentliche Aktion ausführt. In dem hier beschriebenen fall möchte man die Aktion auf alle AD-Benutzerkonten ausführen, daher ist das schnell erledigt:

get-aduser -filter * -properties *

Nun muss die Aktion definiert werden: Es sollen die DisplayName-Attribute all dieser Konten geändert werden. Das übliche Cmdlet für das Hantieren mit den Attributen eines AD-Benutzerobjekts ist bisher immer Set-ADUser. Wenn man Änderungen an den Werten machen will, ist das etwas komplexer als der Einsatz von Get-ADUser, daher soll mit einen recht einfachen Beispiel zu Set-ADUser begonnen werden:

Um an einen Benutzer mit dem „samaccountname“ „john“ einen „Displayname“ namens „John Smith“ zu vergeben, sieht die Syntax wie folgt aus:

set-aduser john -displayname "John Smith"

Bringt man nun den Powershell-Einzeiler aus dem Vorgängerbeitrag mit ins Spiel, ergibt sich das folgende Konzept für einen Befehl (Achtung: die Aktion ist noch nicht „ausprogrammiert“):

get-aduser -filter * -properties * | foreach {do something that uses $_}

Ausgehend von diesem Ansatz sind weitere Schritte erforderlich. Es muss das Beispiel zum Einsatz von Set-ADUser verwendet und mit der Pipeline-Variablen ($_) kombiniert werden. Danach gilt es noch, die Aktion in den geschweiften Klammern mit einer konkreten Aktion zu belegen. Dazu könnte man das Beispiel zu Set-ADUser nehmen und es zunächst in Worten (nicht in Powershell-Code) ausformulieren. Das sieht dann prinzipiell wie folgt aus:

set-aduser [Anmeldename des aktuellen Benutzers in der Pipeline]
-displayname (Vorname des Benutzers, daran ein Leerzeichen angehängt,
dann der Familienname des aktuellen Benutzers in der Pipeline angehängt)

Die runde Klammer in diesem „verbalen Befehl“ wird aus zwei Gründen verwendet: Zum einen ist es eine gute Vorgehensweise, um zu verdeutlichen, was man für die Syntax benötigt und zum anderen wird damit der „Einzeiler“ besser lesbar. Damit wird man auch nach einem halben Jahr noch verstehen, was man „damals“ mit diesem Code machen wollte.

Die Anhängen-Aktion in der Powershell wird mit Hilfe des Pluszeichens gemacht und für ein Leerzeichen muss man im Code dieses Leerzeichen in doppelte Hochkommata einbetten. Damit ergibt sich dann der folgende „Powershell-Teilbefehl“ für das zuvor geschilderte Vorgehen:

set-aduser [Anmeldename des aktuellen Benutzers in der Pipeline]
-displayname (givenname des Benutzers + " " +  sn des Benutzers)

Der abschließende Schritt, damit ein kompletter Powershell-Befehl erzeugt wird, ist das Konkretisieren des Anmeldenamens des Benutzers (logonname), sowie das Bestimmen seines „givenname“ und seines „sn“.  Das sind alles Attribute des jeweils aktuellen Objekts in der Pipeline (sprich der Variablen $_). Damit sieht der Powershell-Befehl zu Set-ADUser wie folgt aus:

set-aduser $_.samaccountname
-displayname ($_.givenname + " " + $_.sn)

Das lässt sich noch anders formulieren – dabei muss man nicht auf das Attribut samaccountname zugreifen, denn es genügt auch, wenn man das gesamte Objekt übergibt. Dazu muss man dann allerdings einen komletten Skriptblock (mit geschweiften Klammen) erstellen. Das sieht wie folgt aus:

get-aduser -filter * -properties * |
foreach { set-aduser $_
-displayname ($_.givenname + " " + $_.sn)}

Damit hat man eine sehr flexible Lösung – die allerdings ein wenig schwieriger zu lesen ist. Mit diesem Beispiel werden wir in einem späteren Beitrag weitermachen.

Mark Minasi/rhh

 

Lesen Sie auch