Praktische PowerShell-Befehlssammlung — Kleine, oft genutzte Funktionen für den Alltag ausbauen

· Aktualisiert am: · · PowerShell, Windows, Kommandozeile, Automatisierung, Betriebseffizienz, Weiternutzung von Altbeständen

1. Das Wichtigste zuerst

Wenn Sie die Grundlagen von PowerShell beherrschen, lohnt es sich als Nächstes, das eigene Repertoire an „kleinen, häufig genutzten Funktionen“ auszubauen — das macht PowerShell im Arbeitsalltag praktisch nutzbar.

Mit kleinen Funktionen sind hier nicht kurze Aliase gemeint. In diesem Artikel verwenden wir statt Abkürzungen wie ls oder cat die vollständigen Befehlsnamen wie Get-ChildItem, Get-Content und Select-String.

Auf dieser Grundlage machen wir folgende Arbeiten mit einer oder wenigen Zeilen möglich:

Anzahl zählen
Gesamtgröße ermitteln
Duplikate entfernen
Nach Kategorie auswerten
Nur die benötigten Werte extrahieren
Zwei Ergebnisse vergleichen
Vorherige und nachfolgende Zeilen eines Log-Treffers ansehen
An die Zwischenablage senden
Ergebnisse speichern und gleichzeitig auf dem Bildschirm anzeigen
Umgebungsvariablen und Netzwerk prüfen

PowerShell ist auch nützlich, ohne dass man lange Skripte schreibt. Bauen Sie zunächst Ihr Repertoire an „häufig genutzten Bausteinen“ aus, damit Sie sie im Arbeitsalltag nach und nach kombinieren können.

Wichtiger, als sich Befehle einzuprägen, ist es, sich erinnern zu können: „In so einer Situation lässt sich dieser Baustein einsetzen.“

Der in diesem Artikel vorkommende Code ist als lauffähiges Beispielpaket, nach der Kapitelgliederung thematisch geordnet (Rezeptskripte und Pester-Tests), auf GitHub veröffentlicht.

powershell-practical-command-recipes - komurasoft-blog-samples (GitHub)

Der Unterschied zum vorherigen Artikel

Dieser Artikel setzt „PowerShell-Befehlsgrundlagen — Die zuerst zu lernenden Operationen und ihre sichere Anwendung“ fort. Die Rollen sind wie folgt aufgeteilt.

  PowerShell-Befehlsgrundlagen Dieser Artikel
Ziel PowerShell bedienen können Die gewonnenen Ergebnisse zählen, zusammenfassen, vergleichen und festhalten können
Schwerpunkt Syntax, Pipeline, Befehle finden Bausteine für Auswertung, Vergleich, Extraktion, Ausgabe
CSV / JSON Grundlagen des Lesens und Schreibens Die Seite, die eingelesene Ergebnisse nach Bedingungen filtert und auswertet
Prozesse / Dienste / Ereignisprotokolle Grundlagen des Abrufens einer Liste Die Seite, die die abgerufene Liste nach Kategorie zählt und Unterschiede ermittelt
Verändernde Befehle Die sichere Ausführungsreihenfolge selbst Die Untersuchungs- und Nachweisbefehle, die in diese Reihenfolge eingebaut werden

Kurz gesagt: Der vorherige Artikel geht bis zu dem Punkt, an dem man Werte extrahieren kann; dieser Artikel behandelt, wie man die extrahierten Werte weiterverwendet.

Die Grundlagen von Abrufbefehlen wie Get-ChildItem, Get-Content, Import-Csv und Get-Service sowie die Ausführungsrichtlinie, das Schreiben von .ps1-Dateien und die Fehlerbehandlung finden Sie im vorherigen Artikel. Dieser Artikel setzt sie voraus und baut darauf auf. Manche Themen tauchen in beiden Artikeln auf, etwa dass Format-Befehle erst ganz am Ende verwendet werden oder Export-Csv -Encoding UTF8 — hier behandeln wir sie jedoch aus dem Blickwinkel, „wie geht man vor, wenn man Werte in eine Auswertung oder einen Vergleich einbringt“.

2. Der Ansatz in diesem Artikel

Die Prämissen sind die folgenden drei:

  1. Befehlsnamen werden vollständig ausgeschrieben
  2. Der Schwerpunkt liegt auf lesenden Befehlen
  3. Verändernde Befehle werden stets zusammen mit einer Zielprüfung oder -WhatIf betrachtet

Statt zum Beispiel gleich den Befehl zum Löschen von Dateien zu lernen, ist es sicherer, sich zuerst den folgenden Ablauf anzueignen.

Ziele betrachten
  → nach Bedingung eingrenzen
  → Anzahl zählen
  → bei Bedarf in CSV festhalten
  → geplante Änderung bestätigen
  → ausführen

Dieser Artikel behandelt eher Untersuchung, Auswertung, Vergleich und Ausgabe als starke Eingriffe wie Löschen oder Stoppen.

3. Eine Landkarte der häufig genutzten Befehle

Das sind die wichtigsten Befehle, die wir diesmal verwenden. Ganz rechts steht das Kapitel, in dem sie ausführlich behandelt werden.

Was Sie erreichen wollen Befehl Kapitel
Anzahl oder Summe ermitteln Measure-Object 4, 5
Nur die benötigten Werte extrahieren Select-Object -ExpandProperty 6
Duplikate bereinigen Sort-Object -Unique 7
Nach Kategorie auswerten Group-Object 8
Nur die benötigten Spalten ausgeben / berechnete Spalten erstellen Select-Object 9
Sortieren Sort-Object 10
Zeichenketten durchsuchen Select-String 12
Zwei Ergebnisse vergleichen Compare-Object 14
Hashwert berechnen Get-FileHash 15
Zwischenablage nutzen Set-Clipboard / Get-Clipboard 16
Sowohl auf dem Bildschirm als auch in einer Datei ausgeben Tee-Object 17
Arbeitsprotokoll führen Start-Transcript 18
Netzwerkerreichbarkeit prüfen Test-Connection / Test-NetConnection 26
Verarbeitungszeit messen Measure-Command 28
Fehlerdetails betrachten Get-Error 31
Jedes Element verarbeiten ForEach-Object je nach Kapitel

Sie müssen nicht alles auf einmal lernen. Es empfiehlt sich, die Befehle zusammen mit ihrem Zweck zu lernen: „Zum Zählen Measure-Object“, „zum Zusammenfassen Group-Object“, „zum Vergleichen Compare-Object“.

Kapitelübersicht nach Zweck

Kapitel 4 bis 36 gliedern sich in die folgenden Blöcke. Lesen Sie dort weiter, wo es Sie interessiert.

Kategorie Kapitel Inhalt
Auswertung / Aufbereitung 4–11 Anzahl, Summe, Maximum/Durchschnitt, Werte extrahieren, Duplikate entfernen, nach Kategorie auswerten, berechnete Spalten, Sortieren, Einordnung der Format-Befehle
Text- und Log-Untersuchung 12–14 Zeichenkettensuche mit Kontextzeilen, Ersetzen, Vergleich zweier Listen
Datei- und Dateninhalte 15, 19, 20 Hashwerte prüfen, CSV eingrenzen, JSON-Konfigurationswerte
Ausgabe / Nachweis 16–18 An die Zwischenablage senden, gleichzeitige Ausgabe auf Bildschirm und in Datei, Arbeitsprotokoll
Systemuntersuchung 21–25, 31 Umgebungsvariablen, Profil, Prozesse, Dienste, Ereignisprotokolle, Fehlerdetails
Netzwerk 26, 27 Erreichbarkeitsprüfung, Web-Antworten
Ausführungsweise 28–30 Messung der Ausführungszeit, Hintergrundausführung, Befehlsverlauf
Syntaxüberblick 32 Vergleichsoperatoren
Direkt einsetzbare Rezepte 33, 34 11 praktische Rezepte und Hinweise zur Kombination mit verändernden Befehlen
Schnellübersicht 35 Ein Spickzettel, um vom Zweck zum Befehl zu finden

Wenn Sie bereits wissen, was Sie herausfinden möchten, sich aber nicht an den passenden Befehl erinnern, ist der Einstieg über die Schnellübersicht in Kapitel 35 der schnellste Weg.

4. Anzahl zählen — Measure-Object

Eine sehr häufige Operation ist das Zählen von Elementen.

Zählen Sie die Anzahl der Dateien im aktuellen Ordner.

Get-ChildItem . -File | Measure-Object

So zählen Sie einschließlich der Unterordner.

Get-ChildItem . -File -Recurse | Measure-Object

Count im Ergebnis von Measure-Object ist die Anzahl.

Wenn Sie die Gesamtdateigröße sehen möchten, werten Sie Length aus.

Get-ChildItem . -File -Recurse |
  Measure-Object -Property Length -Sum

So bleibt der Wert allerdings in Byte, was für Menschen etwas schwer lesbar ist, also rechnen wir ihn in GB um.

$size = Get-ChildItem . -File -Recurse |
  Measure-Object -Property Length -Sum

[math]::Round($size.Sum / 1GB, 2)

Das ist praktisch, wenn Sie einen groben Überblick über die Gesamtgröße eines Ordners bekommen möchten.

5. Maximum und Durchschnitt ebenfalls ermitteln

Measure-Object kann nicht nur Summen, sondern auch Maximum und Durchschnitt liefern.

Get-ChildItem . -File |
  Measure-Object -Property Length -Sum -Average -Maximum -Minimum

Das lässt sich verwenden, um die Streuung der Dateigrößen zu sehen.

Sie können auch die kumulierte CPU-Zeit von Prozessen summieren. Das CPU-Feld von Get-Process ist keine Auslastung in Prozent, sondern die Anzahl der Sekunden CPU-Zeit, die seit dem Prozessstart verbraucht wurden.

Get-Process |
  Measure-Object -Property CPU -Sum

Beachten Sie jedoch, dass dieser Wert kein momentaner CPU-Auslastungswert, sondern ein kumulierter Wert ist, der sich je nach Ausführungszeitpunkt und Laufzeit der Prozesse ändert.

Für Untersuchungszwecke reicht das aus, aber wenn Sie eine strenge Überwachung wollen, brauchen Sie zusätzlich dedizierte Überwachungswerkzeuge und ein durchdachtes Log-Design.

6. Nur die Werte extrahieren — Select-Object -ExpandProperty

Select-Object wird oft verwendet, um Spalten auszuwählen.

Get-Process |
  Select-Object Name, Id, CPU

Das liefert „ein Objekt mit den Spalten Name, Id und CPU“.

Wenn Sie dagegen nur die Werte extrahieren möchten, verwenden Sie -ExpandProperty.

Get-Process -Name notepad -ErrorAction SilentlyContinue |
  Select-Object -ExpandProperty Id

Dasselbe gilt, wenn Sie nur Dateinamen extrahieren möchten.

Get-ChildItem . -File |
  Select-Object -ExpandProperty Name

Wenn Sie das Ergebnis eines Befehls an einen anderen Befehl oder in eine Textdatei weitergeben möchten, ist -ExpandProperty praktisch.

Speichern Sie beispielsweise nur die Liste der Dateinamen.

Get-ChildItem . -File |
  Select-Object -ExpandProperty Name |
  Set-Content .\file-names.txt -Encoding UTF8

Select-Object Name und Select-Object -ExpandProperty Name sehen ähnlich aus, aber die Form des Ergebnisses ist unterschiedlich.

Select-Object Name
  → eine Tabelle mit einer Spalte Name

Select-Object -ExpandProperty Name
  → der Wert von Name selbst

Für CSV-Ausgabe ist es besser, die Spalte zu behalten; wenn Sie in eine andere Textverarbeitung weitergeben möchten, sind die reinen Werte einfacher zu handhaben.

7. Duplikate entfernen — Sort-Object -Unique

Angenommen, Sie möchten nur eine Liste der Dateiendungen.

Get-ChildItem . -File |
  Select-Object -ExpandProperty Extension |
  Sort-Object -Unique

Bei der Ausführung werden nur die deduplizierten Endungen wie .txt, .log und .csv angezeigt.

Sie können auch nur die verschiedenen Prozessnamen sehen.

Get-Process |
  Select-Object -ExpandProperty ProcessName |
  Sort-Object -Unique

Ein Beispiel, um aus einer Benutzerliste als CSV nur die Liste der Abteilungsnamen zu extrahieren.

Import-Csv .\users.csv |
  Select-Object -ExpandProperty Department |
  Sort-Object -Unique

Wenn „die Liste unübersichtlich viele gleiche Werte enthält“, ist es praktisch, sich zuerst an Sort-Object -Unique zu erinnern.

8. Nach Kategorie auswerten — Group-Object

Wenn Sie nicht nur Duplikate entfernen, sondern sehen möchten, „was wie oft vorkommt“, verwenden Sie Group-Object.

Zählen Sie die Anzahl der Dateien pro Endung.

Get-ChildItem . -File |
  Group-Object -Property Extension -NoElement |
  Sort-Object -Property Count -Descending

Die Ausgabe hat diese Form. Anzahl und Endungen hängen vom Ordnerinhalt ab, aber die Spaltenreihenfolge bleibt gleich.

Count Name
----- ----
   42 .log
   18 .csv
    7 .txt
    3

Zeilen mit leerem Name sind Dateien ohne Endung.

Wenn Sie -NoElement weglassen, kommt eine Spalte Group hinzu, in der die zur Gruppe gehörenden Elemente selbst angezeigt werden.

Count Name  Group
----- ----  -----
   42 .log  {app-20260601.log, app-20260602.log, app-20260603.log...}
   18 .csv  {export-01.csv, export-02.csv, export-03.csv...}

Wenn Sie nur die Anzahl sehen möchten, füllt die Group-Spalte den Bildschirm unnötig, daher fügen Sie -NoElement hinzu. Möchten Sie umgekehrt prüfen, was in der jeweiligen Gruppe enthalten ist, lassen Sie es weg.

Zählen Sie nach Dienststatus.

Get-Service |
  Group-Object -Property Status -NoElement

Zählen Sie nach Ereignisprotokollstufe.

Get-WinEvent -LogName System -MaxEvents 500 |
  Group-Object -Property LevelDisplayName -NoElement

Group-Object eignet sich gut dafür, sich zu Beginn einer Untersuchung einen Gesamtüberblick zu verschaffen.

Welche Endung am häufigsten vorkommt
Welcher Dienststatus am häufigsten vorkommt
Welche Fehlerstufe am häufigsten vorkommt
Welche Abteilung die meisten Daten hat

Verwenden Sie es, wenn Sie zuerst die Verteilung sehen möchten, bevor Sie sich die Details ansehen.

9. Die benötigten Spalten erzeugen — berechnete Spalten hinzufügen

Die Dateigröße erhalten Sie über Length, allerdings in Byte. Jedes Mal Byte-Werte anzusehen ist mühsam, daher ist es praktisch, eine in MB oder KB umgerechnete Spalte zu erzeugen.

Get-ChildItem . -File |
  Select-Object Name, @{Name="SizeKB"; Expression={ [math]::Round($_.Length / 1KB, 1) }}, LastWriteTime

Ein Beispiel, das auch Unterordner einbezieht und nach der größten Datei zuerst sortiert.

Get-ChildItem . -File -Recurse |
  Sort-Object -Property Length -Descending |
  Select-Object -First 20 FullName, @{Name="SizeMB"; Expression={ [math]::Round($_.Length / 1MB, 2) }}, LastWriteTime

@{Name="..."; Expression={ ... }} ist die Schreibweise, um eine berechnete Spalte zu erstellen. Sie wirkt anfangs etwas lang, wird in der Praxis aber häufig verwendet.

Sie können zum Beispiel den Speicherverbrauch von Prozessen in MB anzeigen.

Get-Process |
  Sort-Object -Property WorkingSet -Descending |
  Select-Object -First 10 Name, Id, @{Name="MemoryMB"; Expression={ [math]::Round($_.WorkingSet / 1MB, 1) }}

Für einen Bericht ist eine Spalte wie SizeMB deutlich lesbarer als das rohe Length.

10. Nach neuestem, ältestem und größtem sortieren

In PowerShell übernimmt Sort-Object das Sortieren.

Betrachten Sie zuletzt aktualisierte Dateien.

Get-ChildItem . -File |
  Sort-Object -Property LastWriteTime -Descending |
  Select-Object -First 10 Name, LastWriteTime

Betrachten Sie alte Dateien.

Get-ChildItem . -File |
  Sort-Object -Property LastWriteTime |
  Select-Object -First 10 Name, LastWriteTime

Betrachten Sie große Dateien.

Get-ChildItem . -File -Recurse |
  Sort-Object -Property Length -Descending |
  Select-Object -First 10 FullName, Length

Diese drei kommen ständig zum Einsatz.

Neuestes zuerst → LastWriteTime -Descending
Ältestes zuerst → LastWriteTime
Größtes zuerst  → Length -Descending

Diese Kombinationen kommen häufig bei Log-Untersuchungen, dem Aufräumen unnötiger Dateien und der Untersuchung des Speicherplatzes zum Einsatz.

11. Die Format-Befehle nur ganz am Ende für die Bildschirmanzeige verwenden

Wenn Sie die Anzeige auf dem Bildschirm übersichtlicher gestalten möchten, verwenden Sie Format-Table oder Format-List.

Get-Process |
  Sort-Object -Property WorkingSet -Descending |
  Select-Object -First 10 Name, Id, WorkingSet |
  Format-Table -AutoSize

Für die Detailansicht eines einzelnen Elements ist Format-List praktisch.

Get-Process -Id $PID |
  Format-List *

Format-Table und Format-List sind jedoch „für die Anzeige“ gedacht.

Vor der CSV-Ausgabe oder vor der Weiterverarbeitung mit dem nächsten Befehl sollten Sie sie besser nicht verwenden.

# Vermeiden
Get-Process |
  Format-Table Name, Id |
  Export-Csv .\process.csv -NoTypeInformation

Für die CSV-Ausgabe wählen Sie die Spalten mit Select-Object aus.

# Richtig
Get-Process |
  Select-Object Name, Id |
  Export-Csv .\process.csv -NoTypeInformation -Encoding UTF8

Im Zweifel denken Sie so:

Nur zum Anschauen auf dem Bildschirm → Format-Table / Format-List
Zur Weiterverwendung              → Select-Object

12. Log-Suche etwas komfortabler machen — Select-String

Für die Zeichenkettensuche verwenden Sie Select-String.

Select-String -Path .\logs\*.log -Pattern "ERROR"

Sie können auch mehrere Muster angeben.

Select-String -Path .\logs\*.log -Pattern "ERROR", "WARN", "FATAL"

Wenn Sie auch die umgebenden Zeilen sehen möchten, verwenden Sie -Context.

Select-String -Path .\logs\*.log -Pattern "ERROR" -Context 2

Das zeigt zusätzlich die zwei Zeilen vor und nach der Treffer-Zeile an, was praktisch ist, wenn Sie den Zusammenhang rund um einen Fehler prüfen möchten.

Wenn Sie als einfache Zeichenkette suchen möchten, verwenden Sie -SimpleMatch.

Select-String -Path .\logs\*.log -Pattern "[ERROR]" -SimpleMatch

Das -Pattern von Select-String wird normalerweise als regulärer Ausdruck behandelt. Wenn Sie Symbole wie [ oder . wörtlich suchen möchten, wird es mit -SimpleMatch eindeutig.

So gehen Sie vor, wenn Groß-/Kleinschreibung beachtet werden soll.

Select-String -Path .\logs\*.log -Pattern "Error" -CaseSensitive

Sie können Suchergebnisse auch in einer CSV festhalten.

Select-String -Path .\logs\*.log -Pattern "ERROR" |
  Select-Object Path, LineNumber, Line |
  Export-Csv .\error-lines.csv -NoTypeInformation -Encoding UTF8

13. Zeichenketten ersetzen

Um einen Teil eines Textes zu ersetzen, verwenden Sie -replace.

"server01.example.com" -replace "\.example\.com$", ""

Wenn Sie den Inhalt einer Datei ersetzen, ist es sicherer, nicht sofort die Originaldatei zu überschreiben. Geben Sie zunächst in eine andere Datei aus.

(Get-Content .\appsettings.json -Raw) -replace "localhost", "db01" |
  Set-Content .\appsettings.preview.json -Encoding UTF8

Prüfen Sie das Ergebnis und übertragen Sie es bei Bedarf erst dann in die Originaldatei.

Bei Konfigurationsdateien und Massenersetzungen führen zu viele Treffer zu Zwischenfällen. Prüfen Sie die Ziele vorher mit Select-String, bevor Sie ersetzen, um sicher zu sein.

Select-String -Path .\appsettings.json -Pattern "localhost" -SimpleMatch

14. Zwei Ergebnisse vergleichen — Compare-Object

Compare-Object ist der Befehl, um die Unterschiede zwischen zwei Listen zu sehen.

Wann Sie das brauchen: um zu prüfen, ob sich die Konfiguration vor und nach einer Arbeit verändert hat, um Einstellungen oder installierte Software zwischen zwei PCs abzugleichen, oder um die Dienstkonfiguration zwischen Produktion und Test zu vergleichen. Es wirkt für den Zweck, „sollte unverändert sein“ zu bestätigen.

Vergleichen Sie zum Beispiel die Dateinamenlisten vor und nach einer Änderung.

Compare-Object `
  -ReferenceObject (Get-Content .\before.txt) `
  -DifferenceObject (Get-Content .\after.txt)

Enthält before.txt a.log, b.log, c.log und after.txt b.log, c.log, d.log, sieht die Ausgabe so aus.

InputObject SideIndicator
----------- -------------
d.log       =>
a.log       <=

b.log und c.log, die in beiden vorkommen, werden standardmäßig nicht angezeigt. Angezeigt werden nur die Unterschiede.

Die Bedeutung von SideIndicator ist wie folgt.

Anzeige Bedeutung
<= Nur auf der linken Seite, also nur in ReferenceObject vorhanden
=> Nur auf der rechten Seite, also nur in DifferenceObject vorhanden
== In beiden vorhanden. Wird angezeigt, wenn -IncludeEqual gesetzt ist

Die Pfeilrichtung lässt sich leichter merken, wenn Sie sie als „auf welcher Seite liegt es näher — bei ReferenceObject (links) oder DifferenceObject (rechts)“ lesen. Im obigen Beispiel existiert a.log nur links (vor der Änderung), ist also eine entfernte Datei, während d.log nur rechts (nach der Änderung) existiert, also eine hinzugekommene Datei ist.

Ein Beispiel, bei dem die Dateinamenliste eines Ordners gespeichert und verglichen wird.

Get-ChildItem .\before -File |
  Select-Object -ExpandProperty Name |
  Set-Content .\before-list.txt -Encoding UTF8

Get-ChildItem .\after -File |
  Select-Object -ExpandProperty Name |
  Set-Content .\after-list.txt -Encoding UTF8

Compare-Object `
  -ReferenceObject (Get-Content .\before-list.txt) `
  -DifferenceObject (Get-Content .\after-list.txt)

Sie können auch Änderungen an der Dienstliste betrachten.

Get-Service |
  Select-Object Name, Status |
  Export-Csv .\services-before.csv -NoTypeInformation -Encoding UTF8

Geben Sie nach der Änderung erneut aus.

Get-Service |
  Select-Object Name, Status |
  Export-Csv .\services-after.csv -NoTypeInformation -Encoding UTF8

Vergleichen Sie.

Compare-Object `
  -ReferenceObject (Import-Csv .\services-before.csv) `
  -DifferenceObject (Import-Csv .\services-after.csv) `
  -Property Name, Status

Wenn Sie die Unterschiede vor und nach einer Arbeit festhalten, wird die Untersuchung und Berichterstattung einfacher.

15. Dateihashwerte prüfen — Get-FileHash

Wenn Sie prüfen möchten, ob eine heruntergeladene oder verteilte Datei identisch ist, verwenden Sie Hashwerte.

Get-FileHash .\installer.exe -Algorithm SHA256

So prüfen Sie die Dateien in einem Ordner gesammelt.

Get-ChildItem .\downloads -File |
  ForEach-Object { Get-FileHash -LiteralPath $_.FullName -Algorithm SHA256 }

Sie können sie auch in einer CSV festhalten.

Get-ChildItem .\downloads -File |
  ForEach-Object { Get-FileHash -LiteralPath $_.FullName -Algorithm SHA256 } |
  Select-Object Path, Hash |
  Export-Csv .\hashes.csv -NoTypeInformation -Encoding UTF8

Allein am Dateinamen sehen Dateien manchmal gleich aus, obwohl sich der Inhalt unterscheidet. Bei verteilten Dateien, Backups und Migrationsarbeiten macht das Festhalten von Hashwerten die Prüfung viel einfacher.

16. In die Zwischenablage senden — Set-Clipboard

Wann Sie das brauchen: um ein Untersuchungsergebnis direkt in die Antwort auf eine Anfrage oder in einen Störungsbericht einzufügen, oder um es in Excel als Tabelle einzufügen. Der Umweg über das Erstellen, Öffnen, Markieren und Kopieren einer Datei entfällt vollständig.

Wenn Sie ein Befehlsergebnis in eine E-Mail oder einen Chat einfügen möchten, ist das Senden an die Zwischenablage praktisch.

Get-Service |
  Select-Object Name, Status |
  ConvertTo-Csv -NoTypeInformation |
  Set-Clipboard

So sehen Sie den Inhalt der Zwischenablage.

Get-Clipboard

Wenn Sie es tabulatorgetrennt haben möchten, um es in Excel einzufügen, stellen Sie das Trennzeichen von ConvertTo-Csv auf einen Tabulator um.

Get-Process |
  Select-Object Name, Id, CPU |
  ConvertTo-Csv -NoTypeInformation -Delimiter "`t" |
  Set-Clipboard

Wenn Sie ein Ergebnis nur vorübergehend teilen möchten, ist das bequemer, als jedes Mal eine Datei zu erstellen. Möchten Sie es jedoch als Nachweis festhalten, speichern Sie es mit Export-Csv in eine Datei.

17. Gleichzeitig auf dem Bildschirm anzeigen und in einer Datei speichern — Tee-Object

Wenn Sie ein Ergebnis auf dem Bildschirm sehen und gleichzeitig in einer Datei festhalten möchten, verwenden Sie Tee-Object.

Get-Process |
  Sort-Object -Property WorkingSet -Descending |
  Select-Object -First 10 Name, Id, WorkingSet |
  Tee-Object -FilePath .\top-process.txt

Tee-Object leitet das Pipeline-Ergebnis in zwei Richtungen.

Auf dem Bildschirm anzeigen
Zusätzlich in einer Datei speichern

Das eignet sich für den Zweck, „während der Untersuchung mitverfolgen und gleichzeitig protokollieren“. Möchten Sie die Daten später in Excel öffnen, ist Export-Csv jedoch einfacher zu handhaben.

Get-Process |
  Sort-Object -Property WorkingSet -Descending |
  Select-Object -First 10 Name, Id, WorkingSet |
  Export-Csv .\top-process.csv -NoTypeInformation -Encoding UTF8

Für die Bildschirmanzeige Tee-Object, zum Aufbewahren als Tabellendaten Export-Csv — mit dieser Faustregel ist es leicht verständlich.

18. Ein Arbeitsprotokoll führen — Start-Transcript

Wann Sie das brauchen: bei Arbeiten in einer Produktionsumgebung, wenn Sie später berichten müssen, „was in welcher Reihenfolge ausgeführt wurde“. Als Nachweis bei Störungsbehebung oder Wartungsarbeiten setzen Sie es einmal vor Beginn ab.

Wenn Sie eine Abfolge von Vorgängen protokollieren möchten, verwenden Sie Start-Transcript.

Start-Transcript -Path .\work-log.txt

Die danach ausgeführten Befehle und die Bildschirmausgabe werden protokolliert.

Beenden Sie es.

Stop-Transcript

Bei Untersuchungsarbeiten möchten Sie später oft Folgendes nachvollziehen:

Welche Befehle ausgeführt wurden
In welchem Ordner gearbeitet wurde
Welche Ergebnisse aufgetreten sind
Ob Fehler aufgetreten sind

Start-Transcript dient als Absicherung für den Fall, dass Sie vergessen haben, sich Notizen zur Arbeit zu machen. Achten Sie jedoch bei Arbeiten, bei denen Informationen wie Passwörter oder Token auf dem Bildschirm erscheinen, darauf, wie Sie es einsetzen — solche Informationen dürfen nicht protokolliert werden.

19. CSV einlesen und nach Bedingungen betrachten

In Geschäftsdaten kommt CSV häufig vor.

Nehmen wir an, es gibt die folgende users.csv.

Name,Department,Enabled
Suzuki,Sales,true
Tanaka,Accounting,false
Sato,Sales,true

Lesen Sie sie ein.

Import-Csv .\users.csv

Betrachten Sie nur Personen mit der Abteilung Sales.

Import-Csv .\users.csv |
  Where-Object { $_.Department -eq "Sales" }

Geben Sie nur die aktivierten Benutzer in eine separate CSV aus.

Import-Csv .\users.csv |
  Where-Object { $_.Enabled -eq "true" } |
  Export-Csv .\enabled-users.csv -NoTypeInformation -Encoding UTF8

CSV-Werte werden meist als Zeichenketten behandelt. Wenn Sie true / false oder Zahlen vergleichen, denken Sie bei Bedarf an eine Typumwandlung.

Betrachten Sie zum Beispiel nur die Zeilen mit einer Punktzahl von 80 oder mehr.

Import-Csv .\scores.csv |
  Where-Object { [int]$_.Score -ge 80 }

20. JSON-Konfigurationswerte betrachten

JSON wird häufig in Konfigurationsdateien und Web-APIs verwendet.

$config = Get-Content .\settings.json -Raw | ConvertFrom-Json
$config

Sie können auch nur einen bestimmten Wert betrachten.

$config.Database.Host

Ein Beispiel, bei dem ein Wert geändert und in eine separate Datei gespeichert wird.

$config.Database.Host = "db01"
$config |
  ConvertTo-Json -Depth 10 |
  Set-Content .\settings.updated.json -Encoding UTF8

Beim Umgang mit JSON wird häufig Get-Content -Raw verwendet. Mit -Raw wird die gesamte Datei als eine einzige Zeichenkette eingelesen, was bei mehrzeiligem JSON übersichtlicher ist.

21. Umgebungsvariablen betrachten

Umgebungsvariablen kommen häufig bei Anwendungseinstellungen und Pfadprüfungen zum Einsatz.

Betrachten Sie die Liste.

Get-ChildItem Env:

Betrachten Sie den aktuellen Benutzernamen.

$env:USERNAME

Betrachten Sie den temporären Ordner.

$env:TEMP

Teilen Sie PATH übersichtlich auf.

$env:PATH -split ";"

Setzen Sie eine Umgebungsvariable nur für die aktuelle PowerShell-Sitzung.

$env:APP_MODE = "Development"

Diese Einstellung gilt nur innerhalb der aktuell geöffneten PowerShell-Sitzung.

So gehen Sie vor, um sie als Benutzerumgebungsvariable dauerhaft zu speichern.

[Environment]::SetEnvironmentVariable("APP_MODE", "Development", "User")

Das ist ein Vorgang, der die Umgebung verändert. Prüfen Sie deshalb auf Firmen-PCs oder Produktionsservern zunächst den Wirkungsbereich, bevor Sie ihn durchführen.

22. Das Profil prüfen

PowerShell verfügt über ein Profil, das beim Start geladen wird.

Prüfen Sie den Speicherort.

$PROFILE

Prüfen Sie, ob es existiert.

Test-Path $PROFILE

So erstellen Sie es.

New-Item -ItemType File -Path $PROFILE -Force

Öffnen Sie es im Editor.

notepad $PROFILE

Es ist praktisch, häufig genutzte Einstellungen und Funktionen in das Profil zu schreiben. Wenn Sie jedoch zu komplexe Verarbeitung hineinschreiben, verlangsamt das den Start von PowerShell und macht es schwerer, dasselbe Verhalten in einer anderen Umgebung zu reproduzieren. Es empfiehlt sich daher, sich zunächst auf häufig genutzte Pfade und Anzeigeeinstellungen zu beschränken.

23. Prozesse betrachten

Bei der Prozessuntersuchung schaut man meist zuerst nach dem größten Speicherverbrauch.

Get-Process |
  Sort-Object -Property WorkingSet -Descending |
  Select-Object -First 10 Name, Id, @{Name="MemoryMB"; Expression={ [math]::Round($_.WorkingSet / 1MB, 1) }}

Grenzen Sie auf einen bestimmten Namen ein.

Get-Process -Name notepad -ErrorAction SilentlyContinue

Wenn Sie einen Prozess stoppen möchten, führen Sie das nicht sofort aus, sondern prüfen Sie erst mit -WhatIf.

Stop-Process -Name notepad -WhatIf

Wenn alles in Ordnung ist, führen Sie es aus.

Stop-Process -Name notepad

In einer Produktionsumgebung kann das Stoppen eines Prozesses den Geschäftsbetrieb beeinträchtigen. Prüfen Sie vor dem Stoppen Ziel, Nutzer und Wiederherstellungsmethode.

24. Dienste betrachten

Betrachten Sie die Dienstliste.

Get-Service

So sehen Sie nur gestoppte Dienste.

Get-Service |
  Where-Object { $_.Status -eq "Stopped" }

Suchen Sie Dienste, die auf automatischen Start eingestellt, aber gestoppt sind.

Get-Service |
  Where-Object { $_.StartType -eq "Automatic" -and $_.Status -ne "Running" } |
  Select-Object Name, DisplayName, Status, StartType

Auch beim Neustart eines Dienstes prüfen Sie zunächst das Ziel.

Get-Service -Name "Spooler"

Führen Sie eine Probeausführung durch.

Restart-Service -Name "Spooler" -WhatIf

Diensteingriffe haben eine große Auswirkung, prüfen Sie deshalb Wartungsfenster und Wiederherstellungsverfahren, bevor Sie sie ausführen.

25. Ereignisprotokolle betrachten

Bei der Windows-Untersuchung kommt es häufig vor, dass Sie Ereignisprotokolle betrachten.

Betrachten Sie die letzten 100 Einträge des Systemprotokolls.

Get-WinEvent -LogName System -MaxEvents 100 |
  Select-Object TimeCreated, ProviderName, Id, LevelDisplayName, Message

Grenzen Sie auf Fehler und Warnungen ein.

Get-WinEvent -LogName System -MaxEvents 500 |
  Where-Object { $_.LevelDisplayName -in @("Error", "Warning") } |
  Select-Object TimeCreated, ProviderName, Id, LevelDisplayName, Message

Betrachten Sie nur die Fehler der letzten 24 Stunden.

$start = (Get-Date).AddHours(-24)

Get-WinEvent -FilterHashtable @{ LogName = "System"; StartTime = $start } |
  Where-Object { $_.LevelDisplayName -eq "Error" } |
  Select-Object TimeCreated, ProviderName, Id, Message

So halten Sie das Untersuchungsergebnis in einer CSV fest.

Get-WinEvent -LogName System -MaxEvents 500 |
  Where-Object { $_.LevelDisplayName -in @("Error", "Warning") } |
  Select-Object TimeCreated, ProviderName, Id, LevelDisplayName, Message |
  Export-Csv .\system-events.csv -NoTypeInformation -Encoding UTF8

Ereignisprotokolle werden leicht sehr umfangreich, deshalb ist es wichtig, den Bereich mit -MaxEvents oder einer Zeitraumangabe einzugrenzen.

26. Das Netzwerk prüfen

Für die Erreichbarkeitsprüfung verwenden Sie Test-Connection.

Test-Connection example.com -Count 4

Um unter Windows die Erreichbarkeit eines TCP-Ports zu prüfen, ist Test-NetConnection praktisch.

Test-NetConnection example.com -Port 443

So prüfen Sie die DNS-Auflösung.

Resolve-DnsName example.com

Bei der Netzwerkuntersuchung grenzen Sie wie folgt ein:

Lässt sich der Name auflösen
Erreicht man die IP-Adresse
Ist der gewünschte Port offen
Gibt es Einfluss von Proxy oder Firewall

Nutzen Sie PowerShell nicht, um alles allein zu beurteilen, sondern als Einstiegspunkt für die Eingrenzung — das ist praktisch.

27. Web-Ergebnisse betrachten

Für den Abruf von Webseiten verwenden Sie Invoke-WebRequest.

Invoke-WebRequest https://example.com |
  Select-Object StatusCode, StatusDescription

Für die Verarbeitung von JSON-API-Ergebnissen ist Invoke-RestMethod praktisch.

Invoke-RestMethod https://api.github.com/repos/PowerShell/PowerShell |
  Select-Object full_name, stargazers_count, forks_count

API-Ergebnisse lassen sich häufig von Anfang an als PowerShell-Objekte behandeln und kombinieren sich gut mit Select-Object und Where-Object.

Auch bei der Untersuchung interner APIs beginnen Sie am besten mit lesenden GET-Aufrufen.

Beim Umgang mit Anmeldeinformationen oder Token achten Sie auf die Bildschirmanzeige und die Aufzeichnung im Transcript.

28. Ausführungszeit messen — Measure-Command

Wann Sie das brauchen: um zu entscheiden, ob „dieser Vorgang gefahrlos in einen nächtlichen Batch aufgenommen werden kann“, oder um zu vergleichen, ob eine geänderte Schreibweise schneller geworden ist. Sie können sich dann auf Zahlen statt auf ein Gefühl verlassen.

Wenn Sie wissen möchten, wie lange ein Vorgang dauert, verwenden Sie Measure-Command.

Measure-Command {
  Get-ChildItem C:\Windows -File -Recurse -ErrorAction SilentlyContinue |
    Measure-Object
}

Das Ergebnis enthält TotalSeconds und TotalMilliseconds.

$result = Measure-Command {
  Get-ChildItem . -File -Recurse | Measure-Object
}

$result.TotalSeconds

Wenn Sie ein Skript beschleunigen möchten, ist es wichtig, die Zeit zu messen statt sich auf ein Gefühl zu verlassen. Da das Ergebnis jedoch von Dateianzahl, Datenträgerzustand und Netzwerkzustand abhängt, sollten Sie nicht nach einem einzelnen Ergebnis entscheiden, sondern mehrmals prüfen.

29. Zeitaufwendige Vorgänge im Hintergrund ausführen — Start-Job

Wann Sie das brauchen: wenn Sie einen mehrere Minuten dauernden Vorgang wie das vollständige Durchsuchen eines großen Ordners oder die Berechnung von Hashwerten laufen lassen und währenddessen eine andere Untersuchung fortsetzen möchten. Umgekehrt lohnt sich der Aufwand des Job-Starts nicht, wenn ein Vorgang nur wenige Sekunden dauert.

Wenn Sie eine zeitaufwendige Untersuchung als separaten Job ausführen möchten, verwenden Sie Start-Job.

$job = Start-Job -ScriptBlock {
  Get-ChildItem C:\Windows -File -Recurse -ErrorAction SilentlyContinue |
    Measure-Object
}

Betrachten Sie den Status des Jobs.

Get-Job

Rufen Sie das Ergebnis ab.

Receive-Job $job

Entfernen Sie nicht mehr benötigte Jobs.

Remove-Job $job

Start-Job ist praktisch, muss aber nicht von Anfang an übermäßig eingesetzt werden. Führen Sie Vorgänge zunächst normal aus und wandeln Sie nur die langsamen in Jobs um — das bleibt übersichtlich.

30. Den Befehlsverlauf nutzen

Wann Sie das brauchen: um einen durch Ausprobieren zusammengestellten Befehl, sobald er funktioniert, in eine Anleitung oder ein Skript zu übertragen.

Um bereits ausgeführte Befehle zu sehen, verwenden Sie Get-History.

Get-History

Machen Sie nur die Befehlszeilen übersichtlich.

Get-History |
  Select-Object Id, CommandLine

Führen Sie einen bestimmten Verlaufseintrag erneut aus.

Invoke-History 12

Der Verlauf ist praktisch, kann aber auch gefährliche Befehle erneut ausführen. Wenn Sie verändernde Befehle wie Remove-Item oder Stop-Process aus dem Verlauf erneut ausführen, prüfen Sie den Inhalt, bevor Sie ihn ausführen.

31. Fehlerdetails betrachten — Get-Error

In PowerShell 7 steht Get-Error zur Verfügung, um den letzten Fehler im Detail zu betrachten.

Get-Error

So sehen Sie nur die letzte Fehlermeldung.

$Error[0].Exception.Message

Wenn ein Fehler auftritt, schauen Sie nicht nur auf den roten Text auf dem Bildschirm, sondern prüfen Sie Folgendes:

Bei welchem Befehl der Fehler aufgetreten ist
Bei welchem Pfad oder Ziel er aufgetreten ist
Ob es sich um ein Berechtigungsproblem handelt
Ob die Datei nicht existiert
Ob es sich um ein Netzwerk- oder Sperrproblem handelt

Wenn Sie das Untersuchungsergebnis festhalten möchten, kombinieren Sie es mit Start-Transcript und Export-Csv.

32. Häufig genutzte Vergleichsoperatoren

Bei Where-Object werden Vergleichsoperatoren häufig verwendet.

Operator Bedeutung Beispiel
-eq gleich $_.Status -eq "Running"
-ne ungleich $_.Status -ne "Running"
-gt größer als $_.Length -gt 10MB
-ge größer oder gleich $_.Length -ge 10MB
-lt kleiner als $_.Length -lt 10MB
-le kleiner oder gleich $_.Length -le 10MB
-like Wildcard-Übereinstimmung $_.Name -like "*.log"
-match Übereinstimmung mit regulärem Ausdruck $_.Name -match "^app"
-in Wert ist in der Liste enthalten $_.Status -in @("Running", "Paused")
-contains Liste enthält den Wert @("a", "b") -contains "a"

Beispiele.

Get-ChildItem . -File |
  Where-Object { $_.Length -gt 10MB }
Get-Service |
  Where-Object { $_.Status -in @("Running", "Paused") }
Get-ChildItem . -File |
  Where-Object { $_.Name -match "\.log$" }

Anfangs reichen -eq, -ne, -gt, -lt und -like völlig aus. Wenn Sie sich sicherer fühlen, lassen sich mit -match und -in Bedingungen leichter formulieren.

33. Ein paar praktische Rezepte

Ab hier folgen Beispiele in einer Form, die Sie direkt in der Praxis einsetzen können.

Dateianzahl pro Endung sehen

Get-ChildItem C:\Work -File -Recurse |
  Group-Object -Property Extension -NoElement |
  Sort-Object -Property Count -Descending

Verwenden Sie das, wenn Sie sich einen groben Überblick über den Ordnerinhalt verschaffen möchten.

Die 20 größten Dateien sehen

Get-ChildItem C:\Work -File -Recurse |
  Sort-Object -Property Length -Descending |
  Select-Object -First 20 FullName, @{Name="SizeMB"; Expression={ [math]::Round($_.Length / 1MB, 2) }}

Häufig genutzt bei der Untersuchung des Speicherplatzes.

In den letzten 24 Stunden aktualisierte Dateien sehen

$since = (Get-Date).AddHours(-24)

Get-ChildItem C:\Work -File -Recurse |
  Where-Object { $_.LastWriteTime -ge $since } |
  Select-Object FullName, Length, LastWriteTime

Nützlich, um nach einer Störung zu sehen, welche Dateien aktualisiert wurden.

ERROR-haltige Log-Zeilen in eine CSV umwandeln

Select-String -Path C:\App\Logs\*.log -Pattern "ERROR" |
  Select-Object Path, LineNumber, Line |
  Export-Csv .\error-lines.csv -NoTypeInformation -Encoding UTF8

Macht Untersuchungsergebnisse leichter teilbar.

Zwei Zeilen vor und nach ERROR sehen

Select-String -Path C:\App\Logs\*.log -Pattern "ERROR" -Context 2

Verwenden Sie das, wenn Sie den Zusammenhang rund um die Ursache sehen möchten.

Prozesse mit hohem Speicherverbrauch sehen

Get-Process |
  Sort-Object -Property WorkingSet -Descending |
  Select-Object -First 10 Name, Id, @{Name="MemoryMB"; Expression={ [math]::Round($_.WorkingSet / 1MB, 1) }}

Auf automatischen Start eingestellte, aber gestoppte Dienste sehen

Get-Service |
  Where-Object { $_.StartType -eq "Automatic" -and $_.Status -ne "Running" } |
  Select-Object Name, DisplayName, Status, StartType

Fehler des Systemprotokolls in eine CSV umwandeln

Get-WinEvent -LogName System -MaxEvents 500 |
  Where-Object { $_.LevelDisplayName -eq "Error" } |
  Select-Object TimeCreated, ProviderName, Id, Message |
  Export-Csv .\system-errors.csv -NoTypeInformation -Encoding UTF8

Befehlsergebnisse an die Zwischenablage senden

Get-Service |
  Select-Object Name, DisplayName, Status |
  ConvertTo-Csv -NoTypeInformation |
  Set-Clipboard

Praktisch zum Einfügen in E-Mail oder Chat.

Dateilisten vor und nach einer Arbeit vergleichen

Get-ChildItem C:\Work -File |
  Select-Object -ExpandProperty Name |
  Set-Content .\before.txt -Encoding UTF8

Erfassen Sie sie nach der Arbeit erneut.

Get-ChildItem C:\Work -File |
  Select-Object -ExpandProperty Name |
  Set-Content .\after.txt -Encoding UTF8

Vergleichen Sie.

Compare-Object (Get-Content .\before.txt) (Get-Content .\after.txt)

Gesamtgröße eines Ordners in GB sehen

$size = Get-ChildItem C:\Work -File -Recurse |
  Measure-Object -Property Length -Sum

[math]::Round($size.Sum / 1GB, 2)

34. Vorsicht bei der Kombination mit verändernden Befehlen

Das meiste bisher Behandelte war lesend, und allein damit lässt sich schon relativ unbeschwert experimentieren. Hier dagegen handelt es sich um verändernde Befehle.

Vorgang Befehl
Kopieren Copy-Item
Verschieben Move-Item
Löschen Remove-Item
Umbenennen Rename-Item
Prozess stoppen Stop-Process
Dienst neu starten Restart-Service
Umgebungsvariable dauerhaft setzen [Environment]::SetEnvironmentVariable()

Verändernde Befehle setzen Sie in dieser Reihenfolge ein.

1. Ziele mit einem Get-Befehl betrachten
2. Mit Where-Object eingrenzen
3. Zielliste mit Select-Object betrachten
4. Anzahl mit Measure-Object zählen
5. Bei Bedarf mit Export-Csv festhalten
6. Wenn -WhatIf verfügbar ist, eine Probeausführung durchführen
7. Ausführen

Zum Beispiel beim Löschen alter .tmp-Dateien.

Betrachten Sie zunächst die Ziele.

$limit = (Get-Date).AddDays(-30)

$targets = Get-ChildItem C:\Temp -Filter *.tmp -File -Recurse |
  Where-Object { $_.LastWriteTime -lt $limit }

$targets |
  Select-Object FullName, Length, LastWriteTime

Zählen Sie die Anzahl.

$targets | Measure-Object

Halten Sie sie in einer CSV fest.

$targets |
  Select-Object FullName, Length, LastWriteTime |
  Export-Csv .\delete-targets.csv -NoTypeInformation -Encoding UTF8

Bestätigen Sie das geplante Löschen.

$targets | Remove-Item -WhatIf

Wenn alles in Ordnung ist, führen Sie es aus.

$targets | Remove-Item

Allein das Einhalten dieses Ablaufs verringert Zwischenfälle deutlich.

35. Merkhilfen

Da es aufwendig ist, Befehle einzeln auswendig zu lernen, ist es einfacher, sie nach Zweck zu merken.

Zweck Zu erinnernder Befehl
Zählen Measure-Object
Summieren Measure-Object -Sum
Nach Kategorie betrachten Group-Object
Duplikate entfernen Sort-Object -Unique
Nur die benötigten Werte Select-Object -ExpandProperty
Spalten aufbereiten Select-Object
Größtes zuerst betrachten Sort-Object -Descending
Zeichenkette suchen Select-String
Umgebung betrachten Select-String -Context
Zwei Dinge vergleichen Compare-Object
Nachweis festhalten Export-Csv / Start-Transcript
Auf Bildschirm und in Datei ausgeben Tee-Object
An die Zwischenablage senden Set-Clipboard
Zeit messen Measure-Command
Fehler im Detail sehen Get-Error

Spickzettel für eine Seite

Als Nachschlagewerk zum Ausdrucken und griffbereit Halten fügen wir eine Schnellübersicht mit der genauen Schreibweise hinzu. Allein damit lässt sich der Großteil der alltäglichen Arbeit zusammenstellen.

Zweck Direkt einsetzbare Form
Dateianzahl zählen Get-ChildItem . -File \| Measure-Object
Gesamtgröße in GB sehen [math]::Round((Get-ChildItem . -File -Recurse \| Measure-Object -Property Length -Sum).Sum / 1GB, 2)
Anzahl pro Endung Get-ChildItem . -File \| Group-Object -Property Extension -NoElement \| Sort-Object -Property Count -Descending
Die 20 größten Dateien Get-ChildItem . -File -Recurse \| Sort-Object Length -Descending \| Select-Object -First 20 FullName, Length
In den letzten 24 Stunden Aktualisiertes Get-ChildItem . -File -Recurse \| Where-Object { $_.LastWriteTime -gt (Get-Date).AddDays(-1) }
Nur Werte extrahieren Get-Service \| Select-Object -ExpandProperty Name
Duplikate entfernen Get-Content .\list.txt \| Sort-Object -Unique
ERROR im Log suchen Select-String -Path .\logs\*.log -Pattern "ERROR"
Zwei Zeilen vor/nach ERROR sehen Select-String -Path .\logs\*.log -Pattern "ERROR" -Context 2
Zwei Listen vergleichen Compare-Object -ReferenceObject (Get-Content .\before.txt) -DifferenceObject (Get-Content .\after.txt)
Hashwert prüfen Get-FileHash .\installer.exe -Algorithm SHA256
Ergebnis an die Zwischenablage Get-Service \| Select-Object Name, Status \| ConvertTo-Csv -NoTypeInformation \| Set-Clipboard
Auf Bildschirm und in Datei ausgeben Get-Process \| Tee-Object -FilePath .\out.txt
Arbeitsprotokoll starten Start-Transcript -Path .\work.log
CSV nach Bedingung eingrenzen Import-Csv .\data.csv \| Where-Object { $_.Status -eq "NG" }
In CSV festhalten ... \| Export-Csv .\out.csv -NoTypeInformation -Encoding UTF8
Prozesse mit hohem Speicherverbrauch Get-Process \| Sort-Object WorkingSet -Descending \| Select-Object -First 10 Name, Id, WorkingSet
Gestoppte, automatisch startende Dienste Get-Service \| Where-Object { $_.StartType -eq "Automatic" -and $_.Status -ne "Running" }
Fehler im Ereignisprotokoll Get-WinEvent -LogName System -MaxEvents 200 \| Where-Object { $_.LevelDisplayName -eq "Error" }
Erreichbarkeit prüfen Test-NetConnection -ComputerName example.local -Port 443
Ausführungszeit messen Measure-Command { ... }
Letzten Fehler im Detail sehen Get-Error

Die nicht zu vergessende Reihenfolge

Betrachten → Zählen → Aufbereiten → Festhalten → Probeausführung → Ausführen

Format-Table und Format-List werden ganz am Ende dieses Ablaufs verwendet, nur für die Bildschirmanzeige. Fügen Sie sie vor Export-Csv oder der Weitergabe an den nächsten Befehl ein, geht ab dieser Stelle alles kaputt.

36. Zusammenfassung

PowerShell ist stark, sobald man Skripte schreiben kann. In der Praxis wird jedoch, vielleicht überraschend, am häufigsten die Kombination kleiner Befehle genutzt.

Zählen
Sortieren
Zusammenfassen
Vergleichen
Suchen
Extrahieren
Speichern
An die Zwischenablage senden
Arbeitsprotokoll führen

Allein diese Fähigkeiten machen den Arbeitsalltag deutlich leichter. Sie müssen nicht von Anfang an eine anspruchsvolle Automatisierung anstreben. Werden Sie zunächst mit lesenden Befehlen in der Lage, die Lage genau zu betrachten, und setzen Sie erst danach bei Bedarf verändernde Befehle wie Copy-Item, Move-Item, Remove-Item und Restart-Service ein.

Der Trick, PowerShell sicher zu nutzen, liegt in dieser Reihenfolge:

Betrachten → Zählen → Aufbereiten → Festhalten → Probeausführung → Ausführen

Verinnerlichen Sie dieses Muster, und PowerShell wird nicht mehr „ein schwarzer Bildschirm, in den man Befehle eintippt“, sondern ein praktisches Werkzeug, das Ihre tägliche Untersuchung, Organisation und Berichterstattung unterstützt.

Aktuelle Artikel mit denselben Schlagwörtern führen zu verwandten Themen weiter.

Diese Seiten ordnen den Artikel in einen größeren Leistungs- und Entscheidungskontext ein.

Dieser Artikel ist direkt mit den folgenden Leistungen verbunden.

Häufige Fragen

Fragen, die in Beratungen zu diesem Artikelthema häufig gestellt werden.

Wie ermittle ich mit PowerShell die Anzahl der Dateien und die Gesamtgröße eines Ordners?
Leiten Sie das Ergebnis von Get-ChildItem per Pipe an Measure-Object weiter. Die Anzahl lässt sich an der Count-Eigenschaft des Ergebnisses ablesen; sollen auch Unterordner einbezogen werden, fügen Sie -Recurse hinzu. Die Gesamtgröße ermitteln Sie mit Measure-Object -Property Length -Sum. Da das Ergebnis in Byte kaum lesbar ist, rechnen Sie es mit [math]::Round($size.Sum / 1GB, 2) in Gigabyte um. Mit -Average und -Maximum lassen sich Durchschnitt und Maximum gleich mit ausgeben.
Worin unterscheidet sich -ExpandProperty von Select-Object von der normalen Angabe?
Select-Object Name liefert „ein Objekt mit einer Spalte namens Name“, während Select-Object -ExpandProperty Name „den reinen Wert von Name“ liefert. Wenn Sie nach CSV exportieren möchten, eignet sich die normale Angabe, bei der die Spalte erhalten bleibt; wenn Sie die reinen Werte an einen anderen Befehl, eine Textverarbeitung oder eine Textdatei weitergeben möchten, ist -ExpandProperty einfacher zu handhaben. Die Wahl richtet sich nach dem Zweck.
Warum sollte Format-Table nicht vor Export-Csv verwendet werden?
Format-Table und Format-List sind für die Bildschirmanzeige gedacht: Sie wandeln die Ausgabe in Anzeigeobjekte um, sodass eine nachfolgende CSV-Ausgabe oder Weiterverarbeitung nicht mehr korrekt funktioniert. Wenn Sie nach CSV exportieren oder mit dem nächsten Befehl weiterverarbeiten möchten, wählen Sie die Spalten zuerst mit Select-Object aus und übergeben das Ergebnis dann an Export-Csv. Merkregel: „Nur zum Anschauen auf dem Bildschirm → Format-Reihe, zur Weiterverwendung → Select-Object.“
Gibt es ein Vorgehen, um verändernde Befehle wie Remove-Item sicher einzusetzen?
Führen Sie sie nicht sofort aus. Betrachten Sie die Ziele zunächst mit einem Get-Befehl, grenzen Sie sie mit Where-Object ein, prüfen Sie die Zielliste mit Select-Object, zählen Sie die Anzahl mit Measure-Object und sichern Sie bei Bedarf mit Export-Csv einen Nachweis. Bei Befehlen, die -WhatIf unterstützen, führen Sie anschließend eine Probeausführung durch, um die geplanten Lösch- oder Verschiebevorgänge zu prüfen, und führen den Befehl erst dann tatsächlich aus, wenn alles stimmt. Allein das Einhalten dieser Reihenfolge verringert Zwischenfälle deutlich.

Autorenprofil

Profilseite des Artikelautors.

Go Komura

Geschäftsführer von KomuraSoft LLC

Spezialisiert auf Windows-Softwareentwicklung, technische Beratung und Fehleranalyse, insbesondere bei bestehenden Systemen und schwer reproduzierbaren Störungen.

Zurück zum Blog