Windows PowerShell
Coole Pipelinetricks, Redux
Don Jones
Im letzten Monat habe ich Ihnen einige interessante Pipelinetricks gezeigt, die sich die Pipelineparameterbindung zunutze machen, um eine in gewisser Weise komplexe Aufgabe in einen einfachen Windows PowerShell-Einzeiler umzuwandeln.
Hier ist eine kurze Wiederholung: Ich habe eine durch Kommas getrennte Datei (CSV) mit Informationen über neue Benutzer erstellt, die ich der Active Directory-Domäne hinzufügen musste. Ich habe dabei sichergestellt, dass die Spaltenüberschriften in der CSV-Datei mit den Parameternamen des New-ADUser-Cmdlets übereinstimmten (dieses Cmdlet kommt mit Windows Server 2008 R2 und kann ebenfalls mit Windows Server 2003-Domänen verwendet werden). Die Spaltenüberschriften lauteten ähnlich wie „Department“, „City“, „Name“, „GivenName“, „Surname“ und so weiter. Da New-ADUser Pipelineeingaben nach Eigenschaftenname bindet, konnte ich die Benutzer bei Auswahl dieser Spaltenüberschriften mit nur zwei Cmdlets erstellen:
Import-CSV c:\new-users.csv | New-ADUser
Das Import-CSV-Cmdlet gibt für jede Zeile in der CSV-Datei ein Objekt aus, wobei diese Objekte über Eigenschaften verfügen, die den CSV-Spaltenüberschriften entsprechen. Da meine CSV-Datei alle erforderlichen Parameter für New-ADUser enthielt, musste ich keine weiteren Parameter manuell angeben. Ich hätte jedoch zusätzliche Parameter angeben können, die nicht in der Datei vorhanden, aber dennoch für jeden neuen Benutzer gültig sind, wie z. B. eine Organisation:
Import-CSV c:\new-users.csv | New-ADUser –organization "OurCompany"
Ich denke, dass dieses Beispiel die Leistungsfähigkeit von Windows PowerShell unter Beweis stellt: In den Tagen von VBScript hätte diese Aufgabe ein Skript mit mehreren Zeilen erfordert (und sie könnten dies in Windows PowerShell auf die gleiche Art und Weise tun). Wenn Sie sich jedoch die Zeit nehmen, um die Funktionsweise der Pipeline richtig zu verstehen, können Sie dieses „Skript“ mithilfe einer Reihe von sorgfältig geschriebenen Cmdlets in zwei einfache Befehle umwandeln.
Wo liegt also das Problem?
Einige scharfsinnige Leser wiesen auf meiner Website www.ConcentratedTech.com darauf hin, dass mein cooler Trick nur dann funktionierte, wenn die Spaltenüberschriften in der CSV-Datei genau mit den Parameternamen in New-ADUser übereinstimmten. Erstellt ein Admin die CSV-Datei, können wir wahrscheinlich davon ausgehen, dass die Überschriften übereinstimmen. Kommt die Datei jedoch von einem Mitarbeiter aus der Personalabteilung, lauten die Spaltenüberschriften wohl eher „First Name“, „Last Name“ usw. und stimmen somit nicht genau mit New-ADUser überein. Dies führt dazu, dass diese Eigenschaften nicht automatisch an die Parameter gebunden werden können.
Wir könnten natürlich einfach die Datei oder Datenbank, die uns aus der Personalabteilung rübergeschickt wird, editieren. Aber wurden Computer nicht gerade deshalb erfunden, um uns diese Art von sinnloser Sisyphusarbeit zu ersparen? Windows PowerShell bietet natürlich eine schnelle und einfache Lösung zur „Umbenennung“ von Eigenschaften: Das Select-Object-Cmdlet.
Select-Object ist eines dieser Cmdlets, die aufgrund ihrer Vielzahl von Funktionen nicht unbedingt einfach zu verstehen sind. Beispielsweise gehört die Vereinfachung von Objekten durch die Eliminierung von Eigenschaften, die Sie zu dem Zeitpunkt nicht benötigen, zu einer der Hauptaufgaben dieses Cmdlets. Geben Sie einfach die Eigenschaften an, die Sie wirklich benötigen, und das Cmdlet gibt ein abgespecktes Objekt aus. Dies führt zur übersichtlichen Gestaltung der Ausgabe und von Textdateien. Ein Beispiel:
Get-WmiObject Win32_OperatingSystem | Select-Object BuildNumber,ServicePackMajorVersion
Das Select-Object-Cmdlet kann ebenfalls dazu verwendet werden, eine Teilmenge der Objekte in der Pipeline auszuwählen, indem die Parameter –first oder –last verwendet werden:
Get-Process | Sort VM –desc | Select –first 10
Sie haben wahrscheinlich bemerkt, dass ich den Alias Select anstelle des vollen Cmdlet-Namens verwende.
Hier ist also die Lösung:
Eine weitere oft übersehene Funktion von Select-Object liegt in seiner Fähigkeit, nicht nur die gewünschten Parameter auszuwählen, sondern diese auch umzubenennen. Sollten Sie jemals die vollständige Hilfe zum Cmdlet (Help Select –full - manchmal empfehle ich, dies bei jedem Cmdlet zu tun) gelesen haben, ist Ihnen diese Funktionalität bekannt und Sie haben Anwendungsbeispiele gesehen. Hier ist ein Beispiel:
Import-CSV c:\new-users.csv | Select @{Name="Surname";Expression={$_."Last Name"}}
Hat die Eingabe-CSV-Datei eine Spalte mit der Bezeichnung „Last Name“, wird diese in „Surname“ umbenannt, was zur Folge hat, dass die Ausgabeeigenschaft dem Parameternamen von New-ADUser entspricht. Ich habe einfach eine Hashtable erstellt, die auch als Dictionary oder assoziierendes Array bekannt ist. Das @-Zeichen ist ein Array-Operator in Windows PowerShell, und die Hashtable ist ein Array, das aus Schlüssel-Wert-Paaren besteht. In diesem Fall ist der Schlüssel der Name der von mir zu erstellenden Eigenschaft und der Wert ist der Inhalt, den ich der Eigenschaft zuweisen möchte. Innerhalb des Ausdrucksteil der Hashtable kann ich die Variable $_ verwenden, um mich auf das gegenwärtige Pipelineobjekt zu beziehen. In diesem Beispiel habe ich dessen Eigenschaft „Last Name“ erhalten. (Ich musste Anführungsstriche setzen, da der Name der Eigenschaft ein Leerzeichen enthält.)
Sie können beliebig viele Parameter an das Select-Object übergeben:
Import-CSV c:\new-users.csv | Select @{Name="Surname";Expression={$_."Last Name"}}, @{Name="GivenName";Expression={$_."First Name"}}
Problematisch könnte sein, dass Select-Object nur das ausgibt, was Sie von ihm verlangen. Sollten Sie also nur die zwei umzubenennenden Spalten angeben, enthält die Ausgabe auch nur diese beiden Spalten. Alle weiteren Spalten, die nicht umbenannt werden mussten, werden bei der Ausgabe ignoriert. Generell gesehen müssen Sie jede Eigenschaft, die zum nächsten Cmdlet ausgegeben werden soll, angeben. Natürlich müssen Sie nicht jede Spalte in Ihrer CSV-Datei umbenennen. Sie können sie einfach wie folgt aufführen:
Import-CSV c:\new-users.csv | Select @{Name="Surname";Expression={$_."Last Name"}}, @{Name="GivenName";Expression={$_."First Name"}},Department,Organization,Name
In diesem Fall würden „Department“, „Organization“ und „Name“ ohne Umbenennung übernommen, was natürlich Sinn macht, da sie den zugehörigen Parametern von New-ADUser genau entsprechen.
Da dies bei einer Vielzahl von anzugebenden Spalten mühselig sein kann, gibt es die folgende Kurzform:
Import-CSV c:\new-users.csv | Select @{Name="Surname";Expression={$_."Last Name"}}, @{Name="GivenName";Expression={$_."First Name"}},*
Das „*“ gibt zusätzlich zu den von mir erstellten Eigenschaften „Surname“ und „GivenName“ alle weiteren Eigenschaften aus dem Eingabeobjekt aus. Nehmen wir einmal an, dass unsere CSV-Datei folgendermaßen aussieht:
First Name,Last Name,Department,Name
Don,Jones,IT,DonJ
Greg,Shields,Hausmeister,GregS
Jeff,Hicks,IT,JeffH
Ich kann nun die beiden folgenden Cmdlets verwenden:
Import-CSV c:\new-users.csv | Select @{Name="Surname";Expression={$_."Last Name"}}, @{Name="GivenName";Expression={$_."First Name"}},*
Und meine Ausgabeobjekte weisen jeweils sechs Eigenschaften auf: „First Name“, „Last Name“, „Department“, „Name“, „Surname“ und „GivenName“. Mit anderen Worten sind alle ursprünglichen Eigenschaften plus meine zwei Zusätze enthalten. Ich füge anschließend einfach das New-ADUser-Cmdlet an:
Import-CSV c:\new-users.csv | Select @{Name="Surname";Expression={$_."Last Name"}}, @{Name="GivenName";Expression={$_."First Name"}},* | New-ADUser
Das New-ADUser-Cmdlet kann nichts mit den Eigenschaften „First Name“ und „Last Name“ machen, da diese keinem seiner Parameter entsprechen. Das ist aber in Ordnung, da das Cmdlet die nicht zu bindenden Eigenschaften einfach ignoriert. Es wird jedoch die verbleibenden vier Eigenschaften, „Surname“, „GivenName“, „Department“ und „Name“ binden und die neuen Benutzerkonten für mich erstellen.
Ändern Sie Ihre Denkweise
Sie sollten niemals aufgeben, auch wenn das eine der größten Herausforderungen bei der Verwendung von Windows PowerShell ist. Mit anderen Worten sollten sie niemals davon ausgehen, dass Sie eine vorliegende CSV-Datei ändern müssen, weil die Spaltenüberschriften nicht mit dem, was Sie benötigen, übereinstimmen! Windows PowerShell kann fast jedes Problem lösen – Sie müssen lediglich ein wenig Zeit in die Lösung investieren.
Welchen Herausforderungen mussten Sie sich bei der Verwendung von Windows PowerShell stellen? Das würde mich wirklich sehr interessieren – und vielleicht kann ich Ihr Kopfzerbrechen in einem zukünftigen Artikel einbringen. Stellen Sie Ihre Fragen auf www.ConcentratedTech.com, wo ich mich direkt online mit Ihnen in Verbindung setzen kann, um zusätzliche Einzelheiten in Erfahrung zu bringen, und möglicherweise den Grundstein für einen zukünftigen Artikel für Microsoft TechNet Magazine legen kann.
Don Jones gehört zu den erfahrensten Programmierern und Schulungsleitern für Windows PowerShell. Er stellt wöchentlich Tipps zu Windows PowerShell in seinem Blog unter ConcentratedTech.com bereit. Sie können dort mit ihm in Kontakt treten oder ihm Fragen stellen.