Windows PowerShellZeichenfolgentheorie

Don Jones

Inhalt

Ein praktisches Beispiel
Komplexe Entsprechungen
Die Welt der Zeichenfolgen

Wenn ich auf Konferenzen wie Tech•Ed oder TechMentor Vorträge halte, mache ich in der Regel Äußerungen allgemeiner Art, die Benutzern helfen, sich an die wichtigsten Punkte zu erinnern, z. B. in Bezug auf Windows PowerShell. Meine letzte Äußerung lautete: „Wenn Sie eine Zeichenfolge in Windows PowerShell analysieren, machen Sie etwas falsch.“

Sie beruht auf meiner Philosophie, dass Windows PowerShell™ eine objektorientierte Shell ist. Wenn Sie Dienstlisten in einer Textdatei sichern und diese dann analysieren, um festzustellen, welche Dienste gestartet werden, machen Sie sich zu viel Arbeit. Dieser Ansatz eignet sich für ein textorientiertes Betriebssystem, wie z. B. UNIX, aber in Windows PowerShell (sowie in Windows® selbst) können Sie Objekte viel effizienter verwenden.

Sogar Ihre eigenen Skripts sollten Objekte, nicht formatierten Text, generieren, damit die verschiedenen Shellbefehle zum Formatieren, Filtern, Exportieren usw. verwendet werden können, um die Ausgabe Ihrer Skripts zu ändern. (Im Artikel vom Juli 2008 zu Windows PowerShell erhalten Sie weitere Informationen zum Konzept benutzerdefinierter Objekte als Skriptausgabe.)

Bei einer TechMentor-Konferenz in Orlando, Florida, hat mich vor kurzem einer meiner Studenten daran erinnert, dass es bei nahezu allen Regeln, besonders allgemeinen Regeln, Ausnahmen gibt. „Was ist mit der Suche in einer IIS-Protokolldatei? Muss in diesem Fall denn kein Text analysiert werden?“

Nun ja, das stimmt. Glücklicherweise ist Windows PowerShell, so objektfreundlich es auch ist, nicht träge, was das Analysieren von Textzeichenfolgen angeht. Bei dieser Gelegenheit muss erwähnt werden, dass IIS-Protokolldateien, Firewallprotokolldateien und andere textorientierte Protokolle perfekte Beispiele darstellen.

Ein praktisches Beispiel

Ich musste einmal für ein Unternehmen einen Satz von Firewallprotokolldateien analysieren. Ein Mitarbeiter war beim Anzeigen einiger unangebrachter Websites erwischt worden, und als Teil der nachfolgenden Untersuchung benötigte die Personalabteilung eine umfassende Liste der von ihm besuchten Websites. Diese Informationen aus der Protokolldatei eines einzigen Tages herauszuziehen ist etwas zäh, und die Zuständigen im Personalbereich wollten sie für mehrere Wochen. Das war eine Aufgabe, die ich nicht gern manuell erledigen wollte.

Der DHCP-Server (Dynamic Host Configuration-Protokoll) des Unternehmens zeigte an, dass der Computer des Mitarbeiters über mehrere Monate die gleiche IP-Adresse (angenommen 192.168.17.54 für dieses Beispiel) verwendet hatte. Das ist natürlich nicht ungewöhnlich, da es sich um einen Desktopcomputer handelte, der selten ausgeschaltet wurde. Da das Firewallprotokoll einen Datensatz der Quell-IP-Adressen enthielt, wusste ich, dass Windows PowerShell behilflich sein könnte.

Das Geheimnis liegt im oft übersehenen Befehl „select-string“. Außerdem ist es nützlich, mit regulären Ausdrücken ausreichend vertraut zu sein (siehe Artikel zu Windows PowerShell in der Ausgabe vom November 2007).

Der Befehl „select-string“ akzeptiert einen Dateipfad voller Textdateien, einen regulären Ausdruck oder eine einfache gesuchte Zeichenfolge. Dann gibt er jede Zeile aus jeder Protokolldatei zurück, die dem regulären Ausdruck oder der einfachen Zeichenfolge entspricht. Um mit der Aufgabe zu beginnen, wollte ich einfach jede Zeile abrufen, die die IP-Adresse des Desktopcomputers des Mitarbeiters enthielt. Jede Protokolldateizeile enthielt ein Datum und einen Zeitstempel, und das war alles, was von der Personalabteilung benötigt wurde.

Hier ist der Befehl dazu:

select-string -path c:\logs\*.txt -pattern "192.168.17.54" 
-allmatches –simplematch

Der Parameter „–simplematch“ gibt an, dass das oben genannte Muster nur eine einfache Zeichenfolge und kein regulärer Ausdruck ist. In Abbildung 1 sehen Sie einen Teil der Ausgabe, die auch in eine Datei geleitet werden könnte. Beachten Sie, dass die Ausgabe sowohl den Namen der Datei als auch die Zeilennummer enthält, in denen die Entsprechung gefunden wurde, was sehr nützlich sein kann, wenn Sie zu einem späteren Zeitpunkt weitere Informationen ermitteln möchten.

Cmdlet des Monats: Start-Sleep

Hier ist ein Cmdlet, das Ihnen genau das geben kann, was Sie bei einem langen Arbeitstag benötigen – ein kurzes Mittagsschläfchen. Start-Sleep sorgt für eine kurze Pause, und zwar für Ihre Windows PowerShell-Skripts.

Es ist nicht ungewöhnlich, dass in einem Skript eine kurze Pause erforderlich ist. Angenommen, Sie müssen einen Dienst starten, einige Sekunden warten, bis er betriebsbereit ist und ausgeführt werden kann, und dann einige andere Aufgaben ausführen, die von diesem Dienst abhängen. Start-Sleep ist genau das, was Sie für dieses Verhalten benötigen. Wenn Sie z. B. „Start-Sleep 10“ ausführen, wird die Shell 10 Sekunden lang angehalten. Wenn Sie eine präzisere Steuerung benötigen, können Sie z. B. „Start-Sleep -milli 100“ ausführen, um eine Pause von 100 Millisekunden zu erzielen. Start-Sleep hält die Shell, einschließlich der Skripts, Pipelines und allem anderen, für die angegebene Zeitdauer vollständig an. Wenn nur jemand dieses Start-Mittagsschlaf-Cmdlet schreiben würde, das ich herbeisehne.

fig01.gif

Abbildung 1 Ausgabe eines select-string-Befehls (zum Vergrößern auf das Bild klicken)

Komplexe Entsprechungen

Nachdem die Mitarbeiter der Personalabteilung genau die gewünschten Informationen in den Händen hielten, erkannten sie, dass es eigentlich nicht das war, was sie wollten. Der Bericht enthielt die Besuche bei zahlreichen IP-Adressen, wie z. B. 207.68.172.246 (der MSN®-Website). Die nächste Anforderung des Ermittlers bestand darin, den Bericht auf die Besuche einer speziellen IP-Adresse zu reduzieren, die als eine der in Frage kommenden Websites identifiziert worden war. In diesem Artikel wird die tatsächliche IP-Adresse, die bei der Untersuchung ermittelt wurde, nicht enthüllt. Stattdessen soll für dieses Beispiel 207.68.172.246 verwendet werden (auch wenn die MSN-Website normalerweise nicht als unangebracht angesehen wird).

Diese Anfrage könnte etwas schwieriger sein. In der Protokolldatei, mit der ich es zu tun hatte, befanden sich die Quell- und die Ziel-IP-Adresse direkt nebeneinander und waren durch ein Komma getrennt. So konnte die Suchzeichenfolge einfach in „192.168.17.54,207.68.172.246“ geändert und die Suche wiederholt werden.

In einer komplexeren Protokolldatei ist es jedoch möglich, dass zwischen den beiden IP-Adressen veränderliche Daten gespeichert sind, sodass eine Entsprechung anhand einer einfachen Zeichenfolge nicht funktioniert. In diesem Szenario müsste ein regulärer Ausdruck eingesetzt werden, der auch bei einfacheren Protokollformaten gut funktioniert. Dies wird im Folgenden veranschaulicht.

Innerhalb eines regulären Ausdrucks ist der Punkt ein Platzhalter für ein beliebiges einzelnes Zeichen. Dabei kann der Unterausdruck (.)* für die Suche beliebig vieler Zeichen zwischen den beiden IP-Adressen verwendet werden. Es ist jedoch notwendig, dass ein umgekehrter Schrägstrich verwendet wird, um die tatsächlichen Punkte zu berücksichtigen, die in den IP-Adressen selbst vorkommen.

Daraus ergibt sich der folgende Befehl:

select-string -path c:\logs\*.txt -pattern 
"192\.168\.17\.54(.)*207\.68\.172\.246" –allmatches

Ich habe den Parameter „–simplematch“ entfernt, da ich dieses Mal einen regulären Ausdruck verwende. Die resultierende Ausgabe zeigte nur die Besuche vom Computer des entsprechenden Mitarbeiters bei einer bestimmten, als unangebracht gekennzeichneten Website an. Die Ausgabe enthielt außerdem die Datums- und Zeitstempelangaben, die der Ermittler angefordert hatte. In Abbildung 2 sehen Sie einen Teil der Ausgabe, die Sie beim Ausführen eines solchen Befehls möglicherweise erhalten.

fig02.gif

Abbildung 2 Eingeschränkte Suchergebnisse, die nur die Besuche bei einer bestimmten Website anzeigen (zum Vergrößern auf das Bild klicken)

Dies kann noch verbessert werden, indem die Ausgabe zu „Format-Table“ geleitet und die Fähigkeit des Befehls zur Anzeige berechneter Spalten genutzt wird. Sie können dafür sorgen, dass die Tabelle den Namen der Protokolldatei und die Zeilennummer enthält, wo die Entsprechung gefunden wurde, und dass sie sogar die entsprechende Zeile anzeigt. Die Shell kann jedoch so eingestellt werden, dass sie die Entsprechung mit dem regulären Ausdruck durch eine Zeichenfolge ersetzt, sodass nur die restliche Zeile angezeigt wird, in diesem Beispiel das Datum und den Zeitstempel. Dies ist ein Trick für Fortgeschrittene, aber dadurch wird veranschaulicht, wie Windows PowerShell Zeichenfolgedaten ändern und stark angepasste Ausgaben generieren kann, und das alles in einer einzigen Befehlszeile:

select-string -path c:\logs\*.txt -pattern 
"192\.168\.17\.54(.)*207\.68\.172\.246" -allmatches | 
ft  filename,linenumber,@{"Label"="Time";
"Expression"={$_.line.replace
($_.matches[0],"")}} –auto

In Abbildung 3 sehen Sie, wie die Endergebnisse aussehen könnten.

fig03.gif

Abbildung 3 Formatierte Ausgabe eines select-string-Befehls (zum Vergrößern auf das Bild klicken)

Die Welt der Zeichenfolgen

Ich warte nicht lang mit der Äußerung, dass die objektorientierte Natur von Windows PowerShell eine seiner größten Stärken ist. Aber es gibt nichtsdestotrotz Situationen, in denen Objekte keine Lösung darstellen.

Windows PowerShell existiert in einer objektorientierten Welt. Glücklicherweise hat das Windows PowerShell-Team erkannt, dass Ihre Welt oft externe Daten in formatierten Zeichenfolgen enthält, und deshalb wurde der Befehl „select-string“ hinzugefügt. Mit select-string und der Kenntnis von regulären Ausdrücken können Sie Windows PowerShell dazu verwenden, Einzeiler zu schreiben, die die kompliziertesten Zeichenfolgen analysieren können.

Don Jones ist Mitautor von Windows PowerShell: TFM sowie Autor Dutzender anderer IT-Bücher. Sie erreichen ihn über seinen Blog unter www.concentratedtech.com.