Die Grundlagen der PowerShell-Befehle ── Was man zuerst lernen sollte und wie man sicher damit arbeitet
· Go Komura · PowerShell, Windows, Kommandozeile, Automatisierung, Legacy-Bestände
1. Das Wichtigste zuerst
PowerShell ist eine Befehlsumgebung, die sich für die Prüfung von Windows-Einstellungen, das Organisieren von Dateien, die Untersuchung von Protokollen, die Verarbeitung von CSV-Dateien, die Steuerung von Diensten und die Automatisierung wiederkehrender Aufgaben einsetzen lässt.
Allerdings müssen Sie von Anfang an keine komplexen Skripte schreiben. Wenn Sie sich zunächst nur den folgenden Ablauf merken, sind Sie in der Praxis bereits recht gut gerüstet.
Suchen → Ansehen → Filtern → Sortieren → Ausgeben → bei Bedarf ändern
Die Grundlage von PowerShell ist nicht das „Auswendiglernen langer Befehle“. Wichtig sind die folgenden drei Dinge.
- Befehle mit
Get-CommandundGet-Helpnachschlagen können - Ergebnisse über die
|-Pipeline an den nächsten Befehl weiterreichen können - Vor dem Löschen, Stoppen oder Ändern die Auswirkungen mit
-WhatIfoder-Confirmprüfen
PowerShell lässt „Untersuchung“ und „Änderung“ auf demselben Bildschirm zu. Das ist praktisch, bedeutet aber auch, dass sich Löschungen und Stopps ebenso sofort ausführen lassen — die Gewohnheit, mit einer reinen Lesekontrolle zu beginnen, ist deshalb entscheidend.
Der in diesem Artikel vorkommende Code ist zusammen mit einer nach Kapiteln gegliederten Sammlung thematischer Skripte (so aufgebaut, dass Sie in einem temporären Ordner sicher einen Übungsarbeitsbereich anlegen und ausprobieren können) und Pester-Tests als vollständiges Beispielpaket auf GitHub veröffentlicht.
powershell-command-basics - komurasoft-blog-samples (GitHub)
So lesen Sie diesen Artikel
Dieser Artikel hat 26 Kapitel. Sie müssen ihn nicht von Anfang bis Ende durchlesen. Je nach Ziel verlieren Sie weniger leicht die Orientierung, wenn Sie mit den folgenden Kapiteln beginnen.
| Ziel | Zu lesende Kapitel |
|---|---|
| Sie fangen gerade erst mit PowerShell an | Kapitel 1–8 (Denkweise, Nachschlagen, Pipeline, Dateioperationen) und Kapitel 24 (Lernreihenfolge) |
| Sie wollen Protokolle oder Einstellungen untersuchen | Kapitel 9 (Text), Kapitel 12 (Prozesse/Dienste), Kapitel 13 (Ereignisprotokolle), Kapitel 21 (Untersuchungsbeispiel) |
| Sie wollen CSV- oder JSON-Daten verarbeiten | Kapitel 10, 11, 15 |
| Sie wollen Verarbeitungslogik in ein Skript packen | Kapitel 14, 16, 17, 18 |
| Sie wollen Löschen/Verschieben sicher ausführen | Kapitel 19, 22, 25 |
| Sie wollen nur Befehle nachschlagen | Kapitel 20 (Liste der Grundbefehle), Kapitel 23 (häufige Stolperfallen) |
Die Lernreihenfolge selbst ist in Kapitel 24 „Die Reihenfolge, in der man Befehle lernt“ zusammengefasst. Wenn Sie zum ersten Mal selbst Hand anlegen, halten Sie sich nur an Stufe 1 aus Kapitel 24 (Get-Command, Get-Help, Get-Member, Get-Location, Set-Location, Get-ChildItem, Get-Content, Select-String) und folgen Sie damit dem Haupttext. Sobald Sie diese acht kennen, können Sie den Rest bei Bedarf nachschlagen.
Abgrenzung zur „praktischen Befehlssammlung“
Es gibt noch einen weiteren PowerShell-Artikel. Da die beiden unterschiedliche Rollen haben, nutzen Sie sie wie folgt.
| Artikel | Inhalt | Wann lesen |
|---|---|---|
| Dieser Artikel (Grundlagen) | Das Bediensystem: wie man Befehle findet, das Konzept der Pipeline, die sichere Reihenfolge für Änderungsbefehle | Zuerst lesen |
| Praktische PowerShell-Befehlssammlung | Bausteine nach Zweck: Anzahl-/Summenauswertung (Measure-Object), Auswertung nach Kategorie (Group-Object), Differenzvergleich (Compare-Object), Protokollierung von Arbeitsschritten (Start-Transcript) usw. |
Wenn bei der eigentlichen Arbeit „das möchte ich tun“ auftaucht |
CSV, Prozesse, Dienste, Ereignisprotokolle sowie die Vorsichtsmaßnahmen bei Format-* tauchen in beiden Artikeln auf. Dieser Artikel behandelt „warum man es so schreibt“, die Befehlssammlung behandelt „welcher Baustein in welcher Situation zum Einsatz kommt“.
2. Der Unterschied zwischen PowerShell und der Eingabeaufforderung
PowerShell sieht der klassischen Eingabeaufforderung (cmd.exe) ähnlich, doch die zugrunde liegende Denkweise unterscheidet sich.
| Aspekt | Eingabeaufforderung | PowerShell |
|---|---|---|
| Hauptausgabe | Zeichenketten | Objekte |
| Befehlsnamen | dir, copy usw. |
Get-ChildItem, Copy-Item usw. |
| Ergebnisverarbeitung | Vor allem Zeichenkettenverarbeitung | Filtern und Sortieren über Eigenschaften |
| Automatisierung | Batchdateien | .ps1-Skripte |
| Stärken | Kompatibilität mit alten Kommandozeilen-Beständen | Windows-Verwaltung, CSV, JSON, APIs, Routineaufgaben |
Beim Abrufen einer Dateiliste betrachten Sie in cmd.exe die Ausgabe von dir meist als reine Zeichenkette. In PowerShell wird eine Datei dagegen als Objekt mit Eigenschaften wie Name, Length und LastWriteTime behandelt.
Get-ChildItem
Ist dieser Unterschied einmal klar, lässt sich ein Vorgang wie „nur die innerhalb der letzten 7 Tage aktualisierten Dateien anzeigen, sortiert nach dem neuesten Änderungsdatum“ ganz natürlich formulieren.
Get-ChildItem -File |
Where-Object { $_.LastWriteTime -gt (Get-Date).AddDays(-7) } |
Sort-Object LastWriteTime -Descending |
Select-Object Name, Length, LastWriteTime
3. Windows PowerShell 5.1 und PowerShell 7.x
Windows bringt sowohl das schon lange vorhandene Windows PowerShell 5.1 als auch die neuere Reihe PowerShell 7.x mit.
In der Praxis hilft folgende Betrachtung.
| Variante | Ausführbare Datei | Hauptsächlicher Einsatz |
|---|---|---|
| Windows PowerShell 5.1 | powershell.exe |
Alte Windows-spezifische Module, bestehende Skripte, Pflege interner Bestände |
| PowerShell 7.x | pwsh.exe |
Neue Skripte, plattformübergreifend, laufende Funktionsverbesserungen |
Wer neu einsteigt, kann sich problemlos an PowerShell 7.x orientieren. Allerdings sind alte interne Verwaltungsskripte und Windows-spezifische Module manchmal für Windows PowerShell 5.1 geschrieben.
Deshalb prüft man in der Praxis zuerst die Version.
$PSVersionTable
Für Skripte, die erst ab einer bestimmten Version laufen sollen, reduziert eine Bedingung am Anfang das Fehlerrisiko.
#Requires -Version 7.0
Mit welcher Version laufen die Beispiele dieses Artikels?
Die folgenden Beispiele sind, sofern nicht anders vermerkt, so geschrieben, dass sie unverändert sowohl unter Windows PowerShell 5.1 als auch unter PowerShell 7.x laufen. Bei denselben Befehlen unterscheidet sich jedoch in folgenden Punkten das Ergebnis — prüfen Sie das, bevor Sie sie übernehmen.
| Wo sich Unterschiede zeigen | Windows PowerShell 5.1 | PowerShell 7.x |
|---|---|---|
Standard-Anzeigespalten von Get-Process |
Handles, NPM(K), PM(K), WS(K), CPU(s), Id, SI, ProcessName |
NPM(K), PM(M), WS(M), CPU(s), Id, SI, ProcessName (Speicher in MB) |
Bedeutung von -Encoding UTF8 |
UTF-8 (mit BOM) | UTF-8 (ohne BOM). Soll ein BOM gesetzt werden, geben Sie utf8BOM an |
Wenn -Encoding weggelassen wird |
Unterschiedlich je Befehl (Out-File verwendet UTF-16LE, Set-Content ANSI, Export-Csv ASCII) |
Immer utf8NoBOM |
In den Beispielen dieses Artikels wird bei schreibenden Befehlen -Encoding UTF8 explizit angegeben, um eine ungewollte Zeichenkodierung zu vermeiden. Die Grundlagen zu BOM und Zeilenumbrüchen selbst werden im Artikel „Windows-Zeichenkodierung und Zeilenumbrüche - Grundlagen zu Mojibake und CRLF/LF“ behandelt.
4. Cmdlet-Namen folgen dem Muster Verb-Substantiv
PowerShells Standardbefehle haben grundsätzlich die Form Verb-Substantiv.
Get-Process
Get-Service
Get-ChildItem
Copy-Item
Remove-Item
Export-Csv
Wer sich dieses Muster einprägt, findet auch unbekannte Befehle leichter.
| Verb | Bedeutung | Beispiel |
|---|---|---|
Get |
Abrufen | Get-Process |
Set |
Festlegen | Set-Location |
New |
Erstellen | New-Item |
Copy |
Kopieren | Copy-Item |
Move |
Verschieben | Move-Item |
Remove |
Löschen | Remove-Item |
Start |
Starten | Start-Service |
Stop |
Stoppen | Stop-Process |
Import |
Einlesen | Import-Csv |
Export |
Ausgeben | Export-Csv |
Auch kurze Namen wie dir, ls, cat und cd funktionieren, die meisten davon sind jedoch Aliase.
Get-Command dir
Wenn Sie etwas als Skript behalten wollen, ist es sicherer, den vollständigen Namen statt eines Alias zu verwenden.
# lesbar, aber im Skript zu vermeiden
ls *.log
# Absicht ist eindeutig
Get-ChildItem -Filter *.log
5. Die drei Nachschlagebefehle, die man zuerst lernt
PowerShell hat sehr viele Befehle, deshalb ist es praxistauglicher, „wie man nachschlägt“ zu lernen als auswendig zu lernen.
1. Get-Command ── verfügbare Befehle finden
Get-Command ist der Befehl, um installierte Befehle, Funktionen, Aliase und Anwendungen zu finden.
# Befehle mit dem Substantiv Process finden
Get-Command -Noun Process
# Dienstbezogene Befehle finden
Get-Command *Service*
# CSV-bezogene Befehle finden
Get-Command *Csv*
Wenn Sie sich an einen Befehlsnamen nur ungefähr erinnern, verwenden Sie Platzhalter.
Get-Command *Item*
Get-Command *Content*
Get-Command *Json*
2. Get-Help ── die Verwendung ansehen
Get-Help ist der Befehl, um Beschreibung, Parameter und Beispiele eines Befehls anzusehen.
Get-Help Get-ChildItem
Get-Help Get-ChildItem -Examples
Get-Help Get-ChildItem -Full
Get-Help Get-ChildItem -Online
Am Anfang ist -Examples besonders praktisch.
Get-Help Where-Object -Examples
Ist die Hilfe veraltet oder unvollständig, aktualisieren Sie sie in einer PowerShell-Sitzung mit Administratorrechten.
Update-Help
Je nach Umgebung sind dafür eine Internetverbindung und entsprechende Rechte nötig. Auf Firmen-PCs kann dies an Proxys oder Verwaltungsrichtlinien scheitern.
3. Get-Member ── den Inhalt eines Objekts ansehen
Die Ausgabe von PowerShell ist meist keine „Zeichenkette“, sondern ein „Objekt“. Mit Get-Member lässt sich prüfen, welche Eigenschaften und Methoden dieses Objekt hat.
Get-Process | Get-Member
Get-Service | Get-Member
Get-ChildItem | Get-Member
Dienste haben zum Beispiel Eigenschaften wie Status und Name.
Get-Service | Select-Object Name, Status
Dateien haben Name, Length, LastWriteTime und weitere.
Get-ChildItem -File | Select-Object Name, Length, LastWriteTime
Wenn unklar ist, „wonach man filtern soll“, prüfen Sie zuerst mit
Get-Memberdie Eigenschaftsnamen.
6. Grundlagen der Pipeline
PowerShells | reicht das Ergebnis des linken Befehls an den rechten Befehl weiter.
Get-Process | Sort-Object CPU -Descending | Select-Object -First 10
Dieses Beispiel führt die folgende Verarbeitung von links nach rechts durch.
Prozessliste abrufen
→ nach CPU-Auslastung absteigend sortieren
→ nur die obersten 10 anzeigen
Wie wird die Ausgabe angezeigt?
Das Ergebnis von Get-Process wird standardmäßig als Tabelle mit den folgenden Spalten angezeigt. Die Werte unterscheiden sich je nach Umgebung, geprüft wird also die „Reihenfolge der Spalten“.
NPM(K) PM(M) WS(M) CPU(s) Id SI ProcessName
------ ----- ----- ------ -- -- -----------
| Spalte | Bedeutung |
|---|---|
NPM(K) |
Speicherverbrauch im nicht auslagerbaren Pool (KB) |
PM(M) |
Auslagerbarer Speicherverbrauch (MB) |
WS(M) |
Größe des Arbeitssatzes (kürzlich referenzierte Speicherseiten) (MB) |
CPU(s) |
Über alle Prozessoren verbrauchte Prozessorzeit (Sekunden) |
Id |
Prozess-ID |
SI |
Sitzungs-ID |
ProcessName |
Prozessname |
Das ist die Standardanzeige von PowerShell 7.x. Unter Windows PowerShell 5.1 steht vorn zusätzlich Handles (Anzahl offener Handles), und die Speicherspalten heißen PM(K)/WS(K) mit Werten in KB. Auch wenn sich die Spaltennamen unterscheiden, sind die Eigenschaftsnamen, die Sie bei Sort-Object oder Where-Object angeben (CPU, WorkingSet, Id, Name usw.), dieselben. Anzeigespaltenname und Eigenschaftsname sind zweierlei — greift eine Filterbedingung nicht, prüfen Sie mit Get-Process | Get-Member den tatsächlichen Eigenschaftsnamen.
Häufig genutzte Kombinationen sind diese.
| Befehl | Rolle | Beispiel |
|---|---|---|
Where-Object |
Nach Bedingung filtern | Nur gestoppte Dienste abrufen |
Sort-Object |
Sortieren | Nach neuestem Änderungsdatum sortieren |
Select-Object |
Spalten oder Anzahl auswählen | Nur Name und Größe anzeigen |
ForEach-Object |
Jedes Element verarbeiten | Pro Datei verarbeiten |
Export-Csv |
Als CSV ausgeben | Untersuchungsergebnis speichern |
Where-Object ── nach Bedingung filtern
# Nur gestoppte Dienste anzeigen
Get-Service | Where-Object { $_.Status -eq "Stopped" }
# Nur Dateien über 100MB anzeigen
Get-ChildItem -File |
Where-Object { $_.Length -gt 100MB }
# Nur Dateien anzeigen, deren Name backup enthält
Get-ChildItem -File |
Where-Object { $_.Name -like "*backup*" }
$_ steht für das aktuelle Objekt, das gerade durch die Pipeline fließt.
Where-Object { $_.Length -gt 100MB }
Das prüft: „Ist die Length der gerade betrachteten Datei größer als 100MB?“
Ab PowerShell 3.0 lässt sich auch eine vereinfachte Syntax verwenden.
Get-Service | Where-Object Status -EQ "Stopped"
Solange Sie noch Einsteiger sind, ist die Scriptblock-Syntax jedoch leichter nachzuvollziehen.
Get-Service | Where-Object { $_.Status -eq "Stopped" }
Sort-Object ── sortieren
# Nach Speicherverbrauch absteigend
Get-Process |
Sort-Object WorkingSet -Descending |
Select-Object -First 10 Name, Id, WorkingSet
# Nach neuestem Änderungsdatum
Get-ChildItem -File |
Sort-Object LastWriteTime -Descending |
Select-Object -First 20 Name, LastWriteTime
Select-Object ── nur die benötigten Spalten auswählen
Get-Process |
Select-Object Name, Id, CPU, WorkingSet
Auch zum Begrenzen der Anzahl wird es verwendet.
Get-Process | Select-Object -First 5
Get-Process | Select-Object -Last 5
Vor der Ausgabe in eine CSV lässt sich das Ergebnis mit Select-Object auf die benötigten Spalten reduzieren, was die Weiterverarbeitung erleichtert.
Get-Service |
Select-Object Name, DisplayName, Status, StartType |
Export-Csv .\services.csv -NoTypeInformation -Encoding UTF8
7. Format-Befehle zuletzt verwenden
PowerShell hat Befehle, um die Anzeige zu formatieren.
Format-Table
Format-List
Format-Wide
Diese sind für die „Bildschirmanzeige“ gedacht. Werden sie vor der CSV-Ausgabe oder vor der Weitergabe an die nachfolgende Verarbeitung eingesetzt, entstehen statt der ursprünglichen Eigenschaften Anzeigeobjekte.
# Vermeiden: Anzeigeinformationen mischen sich in die CSV
Get-Process |
Format-Table Name, CPU |
Export-Csv .\process.csv -NoTypeInformation
# Richtig: zuerst Eigenschaften auswählen, dann CSV ausgeben
Get-Process |
Select-Object Name, CPU |
Export-Csv .\process.csv -NoTypeInformation -Encoding UTF8
Wer sich merkt, dass
Format-*„nur ganz zum Schluss für die Bildschirmanzeige“ gedacht ist, vermeidet die meisten Zwischenfälle.
8. Grundlagen der Datei- und Ordneroperationen
Am häufigsten werden in PowerShell Datei- und Ordneroperationen genutzt.
| Was Sie tun möchten | Befehl |
|---|---|
| Aktuellen Ort ansehen | Get-Location |
| Ort wechseln | Set-Location |
| Auflistung ansehen | Get-ChildItem |
| Datei/Ordner erstellen | New-Item |
| Kopieren | Copy-Item |
| Verschieben | Move-Item |
| Umbenennen | Rename-Item |
| Löschen | Remove-Item |
| Existenz prüfen | Test-Path |
Den aktuellen Ort prüfen
Get-Location
Wechseln.
Set-Location C:\Work
Enthält der Pfad Leerzeichen, setzen Sie ihn in Anführungszeichen.
Set-Location "C:\Work Files\Reports"
Die Dateiliste ansehen
Get-ChildItem
Get-ChildItem -File
Get-ChildItem -Directory
Get-ChildItem -Recurse
Bei der Ausführung erscheint unter der Überschrift des Zielordners eine Tabelle mit den folgenden Spalten.
Directory: C:\Work
Mode LastWriteTime Length Name
---- ------------- ------ ----
Mode sind Zeichen für Attribute: d steht für Verzeichnis, a für das Archivattribut, r für schreibgeschützt, h für versteckt, s für System und l für Link. Bei Verzeichniszeilen bleibt Length (Größe) leer. LastWriteTime und Length, wie sie hier stehen, sind genau die Eigenschaftsnamen, die sich in Where-Object oder Sort-Object verwenden lassen.
Zum Filtern nach Erweiterung ist -Filter praktisch.
Get-ChildItem -Filter *.log
Um auch Unterordner zu durchsuchen, verwenden Sie -Recurse.
Get-ChildItem C:\Logs -Filter *.log -Recurse
An Orten mit einer großen Anzahl von Dateien sollten Sie nicht sofort -Recurse einsetzen, sondern den Zielordner zuerst eingrenzen.
Erstellen
# Ordner erstellen
New-Item -ItemType Directory -Path .\archive
# Leere Datei erstellen
New-Item -ItemType File -Path .\memo.txt
Wenn möglicherweise schon etwas existiert, prüfen Sie zuerst.
if (-not (Test-Path .\archive)) {
New-Item -ItemType Directory -Path .\archive
}
Kopieren
Copy-Item .\report.xlsx .\backup\report.xlsx
Um einen ganzen Ordner zu kopieren, verwenden Sie -Recurse.
Copy-Item .\data .\backup\data -Recurse
Ist ein Überschreiben möglich, prüfen Sie vorher die Auswirkungen.
Copy-Item .\data .\backup\data -Recurse -WhatIf
Verschieben
Move-Item .\old.log .\archive\old.log
Wenn Sie mehrere Dateien nach Bedingung verschieben, setzen Sie zuerst -WhatIf.
Get-ChildItem .\logs -Filter *.log |
Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-30) } |
Move-Item -Destination .\archive -WhatIf
Passt alles, entfernen Sie -WhatIf.
Get-ChildItem .\logs -Filter *.log |
Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-30) } |
Move-Item -Destination .\archive
Löschen
Löschen behandeln Sie besonders vorsichtig.
Remove-Item .\old.log -WhatIf
Führen Sie es erst aus, nachdem Sie bestätigt haben, dass das Ziel korrekt ist.
Remove-Item .\old.log
Die Kombination aus Platzhaltern und -Recurse ist mächtig. Führen Sie sie nicht sofort in einem Produktivordner aus, sondern prüfen Sie erst über eine Auflistung.
# Zuerst das Ziel prüfen
Get-ChildItem C:\Logs -Filter *.tmp -Recurse |
Select-Object FullName, Length, LastWriteTime
# Als Nächstes das geplante Löschen prüfen
Get-ChildItem C:\Logs -Filter *.tmp -Recurse |
Remove-Item -WhatIf
# Zuletzt ausführen
Get-ChildItem C:\Logs -Filter *.tmp -Recurse |
Remove-Item
9. Textdateien lesen, durchsuchen und schreiben
Bei der Protokolluntersuchung kommen Textdatei-Operationen ständig zum Einsatz.
Eine Datei lesen
Get-Content .\app.log
Um nur das Ende zu sehen, verwenden Sie -Tail.
Get-Content .\app.log -Tail 50
Um ein fortlaufend erweitertes Protokoll zu beobachten, verwenden Sie -Wait.
Get-Content .\app.log -Tail 20 -Wait
Zeichenketten suchen
Select-String -Path .\app.log -Pattern "ERROR"
Mehrere Dateien lassen sich gleichzeitig durchsuchen.
Select-String -Path .\logs\*.log -Pattern "ERROR", "WARN"
Aus den Suchergebnissen lassen sich Dateiname, Zeilennummer und Inhalt auch in eine CSV extrahieren.
Select-String -Path .\logs\*.log -Pattern "ERROR" |
Select-Object Path, LineNumber, Line |
Export-Csv .\error-lines.csv -NoTypeInformation -Encoding UTF8
In eine Datei schreiben
"hello" | Set-Content .\memo.txt -Encoding UTF8
"next line" | Add-Content .\memo.txt -Encoding UTF8
Zum Speichern von Befehlsergebnissen sind Export-Csv oder ConvertTo-Json gegenüber Out-File oft später leichter weiterzuverarbeiten.
Get-Process |
Select-Object Name, Id, CPU |
Export-Csv .\process.csv -NoTypeInformation -Encoding UTF8
10. Grundlagen im Umgang mit CSV
In der Geschäftsprozessautomatisierung kommt CSV sehr häufig vor. In PowerShell lässt sich eine CSV nicht als Zeichenketten, sondern als „Objekte mit Spalten“ behandeln.
Eine CSV einlesen
Angenommen, es gibt folgende users.csv.
Name,Department,Enabled
Suzuki,Sales,true
Tanaka,Accounting,false
Sato,Sales,true
Einlesen.
$users = Import-Csv .\users.csv
$users
Die Spaltennamen werden zu Eigenschaften.
$users | Select-Object Name, Department
Nach Bedingung filtern
$users |
Where-Object { $_.Department -eq "Sales" }
CSV-Werte kommen häufig als Zeichenketten herein, achten Sie deshalb bei true/false oder Zahlen darauf.
$users |
Where-Object { $_.Enabled -eq "true" }
In eine CSV ausgeben
$users |
Where-Object { $_.Department -eq "Sales" } |
Export-Csv .\sales-users.csv -NoTypeInformation -Encoding UTF8
Die eiserne Regel ist, Format-Table niemals vor Export-Csv zu setzen.
# Vermeiden
$users | Format-Table | Export-Csv .\out.csv -NoTypeInformation
# Richtig
$users | Select-Object Name, Department, Enabled | Export-Csv .\out.csv -NoTypeInformation -Encoding UTF8
11. Grundlagen im Umgang mit JSON
JSON kommt auch bei Konfigurationsdateien und Web-APIs häufig vor.
$data = Get-Content .\settings.json -Raw | ConvertFrom-Json
$data
Ein Objekt in JSON umwandeln.
[pscustomobject]@{
Name = "BatchJob"
Enabled = $true
Retry = 3
} | ConvertTo-Json
Bei tiefer Verschachtelung geben Sie -Depth an.
$config | ConvertTo-Json -Depth 10 | Set-Content .\settings.json -Encoding UTF8
12. Grundlagen zu Prozessen und Diensten
Prozesse ansehen
Get-Process
Die Prozesse mit dem größten Speicherverbrauch prüfen.
Get-Process |
Sort-Object WorkingSet -Descending |
Select-Object -First 10 Name, Id, WorkingSet
Nach Namen filtern.
Get-Process -Name notepad
Das Stoppen sollte vorsichtig erfolgen.
Stop-Process -Name notepad -WhatIf
Passt alles, ausführen.
Stop-Process -Name notepad
Dienste ansehen
Get-Service
Nur gestoppte Dienste ansehen.
Get-Service |
Where-Object { $_.Status -eq "Stopped" }
Nach Namen filtern.
Get-Service -Name "Spooler"
Auch beim Neustart prüfen Sie zuerst das Ziel.
Get-Service -Name "Spooler"
Restart-Service -Name "Spooler" -WhatIf
Diensteingriffe wirken sich leicht auf den Geschäftsbetrieb aus. Prüfen Sie in Produktivumgebungen deshalb zuerst das Vorgehen, das Wartungsfenster und das Wiederherstellungsverfahren.
13. Grundlagen der Ereignisprotokolle
Bei der Untersuchung von Windows sind Ereignisprotokolle unverzichtbar.
Aktuelle Fehler prüfen.
Get-WinEvent -LogName System -MaxEvents 100 |
Where-Object { $_.LevelDisplayName -eq "Error" } |
Select-Object TimeCreated, ProviderName, Id, Message
Wie wird die Ausgabe angezeigt?
Das Ergebnis von Get-WinEvent erhält standardmäßig eine Überschrift je Protokollanbieter (ProviderName), darunter folgt eine Tabelle mit diesen Spalten.
ProviderName: PowerShell
TimeCreated Id LevelDisplayName Message
----------- -- ---------------- -------
Wählen Sie wie im Beispiel oben mit Select-Object Spalten aus, entfällt diese Anbieter-Überschrift, und es entsteht eine Tabelle nur mit den gewählten Spalten. Message ist lang und wird auf dem Bildschirm abgeschnitten. Wollen Sie einen einzelnen Eintrag vollständig lesen, grenzen Sie zunächst auf einen Eintrag ein und zeigen Sie ihn dann mit Format-List an.
Get-WinEvent -LogName System -MaxEvents 1 | Format-List *
LevelDisplayName enthält Critical, Error, Warning, Information oder Verbose. Bei umfangreichen Protokollen ist es schneller, die Bedingung an -FilterHashtable zu übergeben, statt mit Where-Object zu filtern (Level = 3 steht für Warnung, Level = 4 für Information).
Die letzten 50 Einträge des Anwendungsprotokolls ansehen.
Get-WinEvent -LogName Application -MaxEvents 50 |
Select-Object TimeCreated, ProviderName, Id, LevelDisplayName, Message
Nach Zeitraum filtern.
$start = (Get-Date).AddHours(-24)
Get-WinEvent -FilterHashtable @{
LogName = "System"
StartTime = $start
} |
Select-Object TimeCreated, ProviderName, Id, LevelDisplayName, Message
Das Speichern der Untersuchungsergebnisse in einer CSV erleichtert später das Teilen.
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
14. Variablen, Arrays und Hashtabellen
Auch mit kurzen Befehlen allein lässt sich arbeiten, aber sobald es etwas länger wird, sind Variablen praktisch.
Variablen
$path = "C:\Logs"
Get-ChildItem $path
PowerShell-Variablen beginnen mit $.
$today = Get-Date
$limit = (Get-Date).AddDays(-30)
Arrays
$extensions = @("*.log", "*.txt", "*.csv")
foreach ($ext in $extensions) {
Get-ChildItem C:\Work -Filter $ext
}
Hashtabellen
Eine Hashtabelle ist eine Sammlung von Schlüssel-Wert-Paaren.
$params = @{
Path = "C:\Logs"
Filter = "*.log"
Recurse = $true
}
Get-ChildItem @params
Diese Schreibweise mit @params nennt man „Splatting“. Sie macht den Code besser lesbar, wenn die Zahl der Parameter zunimmt.
15. Ergebnisse mit PSCustomObject aufbereiten
Wenn Sie Untersuchungsergebnisse tabellarisch zusammenfassen möchten, ist [pscustomobject] praktisch.
[pscustomobject]@{
ComputerName = $env:COMPUTERNAME
UserName = $env:USERNAME
CheckedAt = Get-Date
}
Mehrere Ergebnisse lassen sich erzeugen und in eine CSV umwandeln.
Get-ChildItem C:\Logs -Filter *.log |
ForEach-Object {
[pscustomobject]@{
Name = $_.Name
FullName = $_.FullName
SizeMB = [math]::Round($_.Length / 1MB, 2)
LastWriteTime = $_.LastWriteTime
}
} |
Export-Csv .\log-files.csv -NoTypeInformation -Encoding UTF8
16. Grundlagen der Skriptdatei .ps1
Häufig genutzte Verarbeitung packen Sie in .ps1-Dateien.
Als Beispiel erstellen wir ein Skript, das alte Protokolle auflistet.
# Find-OldLogs.ps1
param(
[string]$Path = "C:\Logs",
[int]$Days = 30,
[string]$OutputPath = ".\old-logs.csv"
)
$limit = (Get-Date).AddDays(-$Days)
Get-ChildItem -Path $Path -Filter *.log -File -Recurse |
Where-Object { $_.LastWriteTime -lt $limit } |
Select-Object FullName, Length, LastWriteTime |
Export-Csv -Path $OutputPath -NoTypeInformation -Encoding UTF8
Write-Host "Exported: $OutputPath"
Ausführungsbeispiel.
.\Find-OldLogs.ps1 -Path C:\Logs -Days 60 -OutputPath .\old-logs.csv
Werden Argumente über param() entgegengenommen, lassen sich die Bedingungen später leicht ändern.
17. Grundlagen der Ausführungsrichtlinie
Beim Versuch, eine .ps1 auszuführen, kann folgender Fehler auftreten.
... kann nicht geladen werden, da die Ausführung von Skripts auf diesem System deaktiviert ist ...
Prüfen Sie in diesem Fall die aktuelle Ausführungsrichtlinie.
Get-ExecutionPolicy
Get-ExecutionPolicy -List
Wenn Sie auf einem persönlichen Entwicklungsrechner nur lokal erstellte Skripte ausführen möchten, wird häufig RemoteSigned im Gültigkeitsbereich des aktuellen Benutzers gesetzt.
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
Auf Firmen-PCs kann dies jedoch durch Gruppenrichtlinien gesteuert sein. Umgehen Sie das nicht eigenmächtig, sondern klären Sie es mit der Administration oder den betrieblichen Regeln ab.
Die Ausführungsrichtlinie ist eine Sicherheitsfunktion, die die Bedingungen steuert, unter denen PowerShell Skripte ausführt. Sie ist jedoch keine vollständige Sicherheitsgrenze. In Organisationen muss sie zusammen mit Signierung, AppLocker, Microsoft Defender, Rechteverwaltung und Protokollprüfung betrachtet werden.
18. Grundlagen der Fehlerbehandlung
PowerShell setzt die Verarbeitung mitunter auch dann fort, wenn ein Fehler auftritt.
Bei wichtigen Vorgängen verwenden Sie -ErrorAction Stop zusammen mit try/catch.
try {
Copy-Item .\source.txt .\backup\source.txt -ErrorAction Stop
Write-Host "Copy succeeded"
}
catch {
Write-Error "Copy failed: $($_.Exception.Message)"
}
Auch beim Verarbeiten mehrerer Dateien lässt sich ein Fehlschlag nachträglich nachvollziehen, wenn er protokolliert wird.
$results = foreach ($file in Get-ChildItem .\input -File) {
try {
Copy-Item $file.FullName .\backup -ErrorAction Stop
[pscustomobject]@{
FileName = $file.Name
Status = "OK"
Message = ""
}
}
catch {
[pscustomobject]@{
FileName = $file.Name
Status = "NG"
Message = $_.Exception.Message
}
}
}
$results | Export-Csv .\copy-result.csv -NoTypeInformation -Encoding UTF8
19. Die sichere Reihenfolge zum Ausführen von Änderungsbefehlen
In PowerShell ist das Vorgehen wichtig, um Änderungsbefehle — Löschen, Verschieben, Stoppen — sicher zu handhaben.
Die grundlegende Reihenfolge lautet:
1. Ziele mit Get-Befehlen ansehen
2. Mit Where-Object filtern
3. Mit Select-Object die Zielliste prüfen
4. Mit Export-Csv protokollieren
5. Mit -WhatIf die geplante Änderung prüfen
6. Real ausführen
Als Beispiel: .tmp-Dateien löschen, die älter als 30 Tage sind.
Schritt 1: Ziele ansehen
Get-ChildItem C:\Temp -Filter *.tmp -File -Recurse
Schritt 2: Nach Bedingung filtern
$limit = (Get-Date).AddDays(-30)
Get-ChildItem C:\Temp -Filter *.tmp -File -Recurse |
Where-Object { $_.LastWriteTime -lt $limit }
Schritt 3: Nur die benötigten Spalten anzeigen
$targets = Get-ChildItem C:\Temp -Filter *.tmp -File -Recurse |
Where-Object { $_.LastWriteTime -lt $limit }
$targets |
Select-Object FullName, Length, LastWriteTime
Schritt 4: Einen Nachweis sichern
$targets |
Select-Object FullName, Length, LastWriteTime |
Export-Csv .\delete-targets.csv -NoTypeInformation -Encoding UTF8
Schritt 5: Mit WhatIf prüfen
$targets | Remove-Item -WhatIf
Schritt 6: Ausführen
$targets | Remove-Item
Mit dieser Reihenfolge lassen sich Zwischenfälle der Art „wir wissen nicht, was wir gelöscht haben“ vermeiden.
20. Liste häufig genutzter Grundbefehle
Ort und Dateien
| Ziel | Befehlsbeispiel |
|---|---|
| Aktuellen Ordner anzeigen | Get-Location |
| Ordner wechseln | Set-Location C:\Work |
| Auflistung anzeigen | Get-ChildItem |
| Nur Dateien anzeigen | Get-ChildItem -File |
| Nur Ordner anzeigen | Get-ChildItem -Directory |
| Auch Unterordner durchsuchen | Get-ChildItem -Recurse |
| Existenz prüfen | Test-Path .\file.txt |
| Ordner erstellen | New-Item -ItemType Directory .\backup |
| Kopieren | Copy-Item .\a.txt .\backup\a.txt |
| Verschieben | Move-Item .\a.txt .\archive\a.txt |
| Geplante Löschung prüfen | Remove-Item .\a.txt -WhatIf |
Objektverarbeitung
| Ziel | Befehlsbeispiel |
|---|---|
| Nach Bedingung filtern | Where-Object { $_.Status -eq "Running" } |
| Sortieren | Sort-Object LastWriteTime -Descending |
| Spalten auswählen | Select-Object Name, LastWriteTime |
| Nur die obersten anzeigen | Select-Object -First 10 |
| Jedes Element verarbeiten | ForEach-Object { $_.Name } |
| Inhalt untersuchen | Get-Member |
Ein- und Ausgabe
| Ziel | Befehlsbeispiel |
|---|---|
| Text lesen | Get-Content .\app.log |
| Ende ansehen | Get-Content .\app.log -Tail 50 |
| Zeichenketten suchen | Select-String -Path .\app.log -Pattern "ERROR" |
| CSV einlesen | Import-Csv .\users.csv |
| CSV ausgeben | Export-Csv .\out.csv -NoTypeInformation -Encoding UTF8 |
| JSON einlesen | Get-Content .\a.json -Raw \| ConvertFrom-Json |
| JSON ausgeben | $obj \| ConvertTo-Json -Depth 10 |
Windows-Untersuchung
| Ziel | Befehlsbeispiel |
|---|---|
| Prozessliste | Get-Process |
| Dienstliste | Get-Service |
| Ereignisprotokoll | Get-WinEvent -LogName System -MaxEvents 100 |
| Umgebungsvariablen | Get-ChildItem Env: |
| PowerShell-Version | $PSVersionTable |
| Ausführungsrichtlinie | Get-ExecutionPolicy -List |
21. Praxisbeispiel: Protokolle untersuchen und einen Bericht erstellen
Betrachten wir folgende Anforderung.
Aus den .log-Dateien unter C:\App\Logs sollen Zeilen mit ERROR aus Dateien gefunden werden, die innerhalb der letzten 7 Tage aktualisiert wurden, und in einer CSV zusammengefasst werden.
Statt sofort die fertige Form zu schreiben, bauen wir sie schrittweise auf.
Schritt 1: Protokolldateien finden
Get-ChildItem C:\App\Logs -Filter *.log -File -Recurse
Schritt 2: Auf die letzten 7 Tage eingrenzen
$since = (Get-Date).AddDays(-7)
Get-ChildItem C:\App\Logs -Filter *.log -File -Recurse |
Where-Object { $_.LastWriteTime -ge $since }
Schritt 3: Nach ERROR suchen
$since = (Get-Date).AddDays(-7)
Get-ChildItem C:\App\Logs -Filter *.log -File -Recurse |
Where-Object { $_.LastWriteTime -ge $since } |
Select-String -Pattern "ERROR"
Schritt 4: In eine CSV ausgeben
$since = (Get-Date).AddDays(-7)
Get-ChildItem C:\App\Logs -Filter *.log -File -Recurse |
Where-Object { $_.LastWriteTime -ge $since } |
Select-String -Pattern "ERROR" |
Select-Object Path, LineNumber, Line |
Export-Csv .\error-report.csv -NoTypeInformation -Encoding UTF8
Schritt 5: In ein Skript umwandeln
# Export-ErrorReport.ps1
param(
[string]$LogPath = "C:\App\Logs",
[int]$Days = 7,
[string]$Pattern = "ERROR",
[string]$OutputPath = ".\error-report.csv"
)
$since = (Get-Date).AddDays(-$Days)
Get-ChildItem $LogPath -Filter *.log -File -Recurse |
Where-Object { $_.LastWriteTime -ge $since } |
Select-String -Pattern $Pattern |
Select-Object Path, LineNumber, Line |
Export-Csv $OutputPath -NoTypeInformation -Encoding UTF8
Write-Host "Exported: $OutputPath"
Ausführungsbeispiel.
.\Export-ErrorReport.ps1 -LogPath C:\App\Logs -Days 14 -Pattern "ERROR|FATAL" -OutputPath .\errors.csv
22. Praxisbeispiel: Alte Dateien archivieren
Als Nächstes ein Beispiel, das statt löscht verschiebt.
Von den Dateien in C:\Work\Reports sollen die seit mindestens 90 Tagen nicht mehr aktualisierten .xlsx-Dateien nach C:\Work\Archive verschoben werden.
Ziele prüfen
$source = "C:\Work\Reports"
$dest = "C:\Work\Archive"
$limit = (Get-Date).AddDays(-90)
$targets = Get-ChildItem $source -Filter *.xlsx -File |
Where-Object { $_.LastWriteTime -lt $limit }
$targets | Select-Object FullName, Length, LastWriteTime
Archivziel erstellen
if (-not (Test-Path $dest)) {
New-Item -ItemType Directory -Path $dest
}
Nachweis ausgeben
$targets |
Select-Object FullName, Length, LastWriteTime |
Export-Csv .\archive-targets.csv -NoTypeInformation -Encoding UTF8
Mit WhatIf prüfen
$targets | Move-Item -Destination $dest -WhatIf
Ausführen
$targets | Move-Item -Destination $dest
Sind Namenskollisionen möglich, schlägt dies so fehl. Legen Sie in der Praxis vorab Regeln fest: Jahr-Monat-Ordner trennen, dem Zielnamen einen Zeitstempel anhängen, oder bei bereits vorhandener Datei überspringen.
23. Häufige Stolperfallen
| Symptom | Ursache | Abhilfe |
|---|---|---|
| Befehle sind zu lang zum Merken | Versuch, sie auswendig zu lernen | Mit Get-Command, Get-Help -Examples nachschlagen |
$_ ist unverständlich |
Unzureichendes Verständnis des aktuellen Pipeline-Werts | In der Form Where-Object { $_.Name -like "*log*" } einprägen |
| Die CSV enthält seltsame Inhalte | Export-Csv wird nach Format-Table ausgeführt |
Export-Csv nach Select-Object ausführen |
| Pfade mit Leerzeichen schlagen fehl | Fehlende Anführungszeichen | Wie in "C:\Work Files\a.txt" einschließen |
| Skript lässt sich nicht ausführen | Ausführungsrichtlinie | Mit Get-ExecutionPolicy -List prüfen |
| Zu viele Löschziele | Bedingung zu weit gefasst | Zuerst mit Select-Object FullName und -WhatIf prüfen |
| Eigenschaftsname unklar | Objektstruktur nicht betrachtet | Get-Member verwenden |
| Zeichensalat | Kodierungsannahme stimmt nicht | -Encoding bei Ein-/Ausgabe und die verwendete Anwendung prüfen |
24. Die Reihenfolge, in der man Befehle lernt
Sie müssen nicht von Anfang an alle Befehle lernen.
Folgende Reihenfolge ist empfehlenswert.
Stufe 1: Ansehen und Finden
Get-Command
Get-Help
Get-Member
Get-Location
Set-Location
Get-ChildItem
Get-Content
Select-String
Stufe 2: Filtern und Aufbereiten
Where-Object
Sort-Object
Select-Object
ForEach-Object
Format-Table
Format-List
Stufe 3: Ein- und Ausgabe
Import-Csv
Export-Csv
ConvertFrom-Json
ConvertTo-Json
Set-Content
Add-Content
Out-File
Stufe 4: Ändern
New-Item
Copy-Item
Move-Item
Rename-Item
Remove-Item
Start-Service
Stop-Service
Restart-Service
Stop-Process
Änderungsbefehle lernen Sie stets zusammen mit den passenden Prüfbefehlen.
# Ansehen
Get-ChildItem .\logs -Filter *.tmp
# Geplante Löschung ansehen
Get-ChildItem .\logs -Filter *.tmp | Remove-Item -WhatIf
# Ausführen
Get-ChildItem .\logs -Filter *.tmp | Remove-Item
25. Betriebliche Checkliste für den Praxiseinsatz
Setzen Sie PowerShell im Geschäftsbetrieb ein, erhöht die Prüfung folgender Punkte die Sicherheit.
- Geprüft, ob die ausgeführte PowerShell
powershell.exeoderpwsh.exeist - Die Version mit
$PSVersionTablegeprüft - Vor Änderungen die Ziele mit
Get-*-Befehlen angezeigt - Die Bedingung von
Where-Objectauf dem Bildschirm geprüft - Vor Löschen, Verschieben oder Stoppen
-WhatIfverwendet - Die Zielliste vor der Ausführung in einer CSV gespeichert
- In Produktivumgebungen Backup oder Wiederherstellungsverfahren geprüft
- Die Ausführungsrichtlinie des Skripts und interne Regeln geprüft
- Protokollausgabe für den Fehlerfall vorbereitet
- In geteilten Skripten vollständige Befehlsnamen statt Aliase verwendet
26. Zusammenfassung
Die Grundlage von PowerShell besteht nicht darin, eine große Menge an Befehlen auswendig zu lernen. In der Praxis zahlt sich aus, sich folgendes Muster anzueignen.
Mit Get-Command suchen
Mit Get-Help die Verwendung ansehen
Mit Get-Member die Eigenschaften prüfen
Mit Get-* die Ziele ansehen
Mit Where-Object filtern
Mit Select-Object die Spalten aufbereiten
Mit Export-Csv einen Nachweis sichern
Mit -WhatIf die geplante Änderung prüfen
Zuletzt ausführen
PowerShell ist gerade deshalb eine mächtige Umgebung, weil es Dateien löschen, Dienste stoppen, Prozesse beenden und sogar die Registrierung bearbeiten kann. Genau deshalb sollten Sie zuerst nicht „die gefährlichen Befehle“ lernen, sondern „das Vorgehen, um Ziele sicher zu prüfen“.
Ansehen → Filtern → Protokollieren → Testen → Ausführen
Halten Sie diese Reihenfolge ein, wird PowerShell nicht nur ein schwarzer Bildschirm bleiben, sondern ein praktisches Werkzeug, um Windows-Arbeit zu organisieren, zu untersuchen und zu automatisieren.
Referenzlinks
- Das vollständige Beispielpaket zu diesem Artikel (thematische Skripte und Pester-Tests) - komurasoft-blog-samples (GitHub)
- PowerShell Documentation - Microsoft Learn
- PowerShell 7 unter Windows installieren - Microsoft Learn
- Unterschiede zwischen Windows PowerShell 5.1 und PowerShell 7.x - Microsoft Learn
- Get-Command - Microsoft Learn
- Get-Help - Microsoft Learn
- Get-Member - Microsoft Learn
- about_Pipelines - Microsoft Learn
- Where-Object - Microsoft Learn
- Select-Object - Microsoft Learn
- Get-Process - Microsoft Learn (mit Erläuterung der Standard-Anzeigespalten)
- Get-WinEvent - Microsoft Learn
- about_Character_Encoding (Windows PowerShell 5.1) - Microsoft Learn
- Import-Csv - Microsoft Learn
- Export-Csv - Microsoft Learn
- about_Execution_Policies - Microsoft Learn
Verwandte Artikel
- Praktische PowerShell-Befehlssammlung ── Kleine, oft genutzte Funktionen für den Alltag ausbauen
- Windows-Zeichenkodierung und Zeilenumbrüche - Grundlagen zu Mojibake und CRLF/LF
- Leitfaden zur VBScript-Abschaffung - VBA und interne Tools überprüfen
- Registrierungs- und Bitness-Fallen bei der COM/OCX/ActiveX-Entwicklung
Mit diesem Thema verbundene Leistungen
Windows-App-Entwicklung
Wir unterstützen die Entwicklung von Windows-Software wie Geschäftsanwendungen, Anlagenanbindung und Kommunikationstools.
Nutzung und Migration bestehender Assets
Wir unterstützen bei der Bestandsaufnahme, Überarbeitung und Migration bestehender Assets, darunter alte Batchdateien, VBScript, VBA, PowerShell sowie COM/ActiveX.
Verwandte Artikel
Aktuelle Artikel mit denselben Schlagwörtern führen zu verwandten Themen weiter.
Parameterdesign und Modularisierung für PowerShell-Skripte — Von der „funktionierenden“ zur „übergabefähigen“ Skript
Eine schrittweise Vorgehensweise, um ein PowerShell-Skript auf eine Qualität zu heben, die Sie an andere übergeben können. Behandelt den ...
Praktische PowerShell-Befehlssammlung — Kleine, oft genutzte Funktionen für den Alltag ausbauen
Eine praktische Übersicht über PowerShell-Befehle für den Arbeitsalltag: Wann Measure-Object, Group-Object, Select-String, Compare-Object...
PC-Kitting mit winget + PowerShell automatisieren — Aus dem Handbuch ein ausführbares Skript machen
Wie Sie die Einrichtung von PCs für neue Mitarbeitende reproduzierbar gestalten. Behandelt die Installation von Anwendungen mit winget so...
Mit REST-APIs aus PowerShell arbeiten — Invoke-RestMethod in der Praxis
Ein praktischer Leitfaden zum Aufruf interner und SaaS-REST-APIs aus PowerShell: das Übergeben von Authentifizierungsheadern, das Vermeid...
Wo Sie nachsehen sollten, wenn ein PowerShell-Skript langsam ist — Arrays, Pipelines und Abgleich
Die klassischen Ursachen langsamer PowerShell-Skripte im Überblick. Warum += bei einem Array O(n²) ist, der Unterschied zwischen Pipeline...
Verwandte Themen
Diese Seiten ordnen den Artikel in einen größeren Leistungs- und Entscheidungskontext ein.
Technische Windows-Themen
Portal zu Windows-Entwicklung, Fehleranalyse und der Nutzung bestehender Assets.
Leistungen zu diesem Thema
Dieser Artikel ist direkt mit den folgenden Leistungen verbunden.
Windows-App-Entwicklung
Geschäftsanwendungen, Geräteintegration und Kommunikationstools von den Anforderungen bis zur Umsetzung.
Häufige Fragen
Fragen, die in Beratungen zu diesem Artikelthema häufig gestellt werden.
- Womit sollte man beim Lernen von PowerShell zuerst anfangen?
- Nicht mit dem Auswendiglernen von Befehlen, sondern damit, wie man nachschlägt. Drei Dinge sind entscheidend: Befehle mit Get-Command und Get-Help finden können, Ergebnisse über die Pipeline (|) an den nächsten Befehl weiterreichen können, und vor dem Löschen, Stoppen oder Ändern die Auswirkungen mit -WhatIf oder -Confirm prüfen. Ist der Name einer Objekteigenschaft unklar, prüft man den Inhalt mit Get-Member. Der Grundablauf lautet: „Suchen → Ansehen → Filtern → Sortieren → Ausgeben → bei Bedarf ändern“.
- Was unterscheidet PowerShell von der Eingabeaufforderung?
- Der größte Unterschied ist, dass die Ausgabe der Eingabeaufforderung vor allem aus Zeichenketten besteht, während die Ausgabe von PowerShell aus Objekten besteht. Eine Datei wird beispielsweise als Objekt mit Eigenschaften wie Name, Length und LastWriteTime behandelt, wodurch sich Filtern mit Where-Object und Sortieren mit Sort-Object ganz natürlich schreiben lassen. Auch die Befehlsnamen folgen einheitlich der Form Verb-Substantiv, etwa Get-ChildItem oder Copy-Item, wodurch sich auch unbekannte Befehle leichter finden lassen.
- Sollte ich Windows PowerShell 5.1 oder PowerShell 7.x verwenden?
- Wer neu einsteigt, kann sich problemlos an PowerShell 7.x (pwsh.exe) orientieren. Allerdings sind alte interne Verwaltungsskripte und Windows-spezifische Module manchmal für Windows PowerShell 5.1 (powershell.exe) geschrieben. In der Praxis prüft man deshalb zuerst mit $PSVersionTable die Version, und für Skripte, die erst ab einer bestimmten Version laufen sollen, reduziert eine Bedingung wie #Requires -Version 7.0 am Anfang des Skripts das Fehlerrisiko.
- Wie führe ich Löschungen oder Änderungen in PowerShell sicher aus?
- Indem man die Reihenfolge „Ansehen → Filtern → Protokollieren → Testen → Ausführen“ einhält. Konkret: zuerst mit einem Get-Befehl die Ziele anzeigen, mit Where-Object filtern, mit Select-Object die Zielliste prüfen, mit Export-Csv einen Nachweis als CSV sichern, mit -WhatIf die geplante Änderung prüfen und erst dann den eigentlichen Befehl ausführen. Da sich in PowerShell Untersuchung und Änderung auf demselben Bildschirm ausführen lassen, ist die Gewohnheit, mit einer reinen Lesekontrolle zu beginnen, entscheidend.
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.