PS/ÜBUNGSZETTEL ~/05-pipeline.ps1 0 / 9 gelöst
PS C:\pollhammer> .\uebungszettel\05-pipeline.ps1

05 / Pipeline & Report-Skript

Hier fügst du alles zusammen: Mit der Pipeline, Measure-Object und Group-Object analysierst du einen Ordner und baust daraus Schritt für Schritt ein echtes Report-Skript mit sauber formatierter Ausgabe.

9 Aufgaben Measure-Object, Group-Object & FolderReport.ps1 Fortschritt wird gespeichert
man 05-pipeline — das Wichtigste in Kürze
  • Die Pipeline | reicht die Ausgabe-OBJEKTE eines Befehls als Eingabe an den nächsten weiter — kein Text, echte .NET-Objekte.
  • Measure-Object rechnet über eine Eigenschaft: ($files | Measure-Object -Property Length -Sum).Sum — genauso gibt es -Average, -Minimum, -Maximum.
  • Group-Object Extension liefert Gruppen mit .Name (der Wert), .Count (Anzahl) und .Group (die Objekte); mit Sort-Object Count -Descending kommt die größte Gruppe zuerst.
  • 1KB, 1MB, 1GB sind eingebaute Konstanten (1KB = 1024); [math]::Round($bytes / 1MB, 2) rundet auf 2 Nachkommastellen.
  • Einen Report baust du zeilenweise auf: $reportLines = @() und dann $reportLines += "..."; Trennlinien erzeugt die String-Wiederholung "=" * 50.
  • Join-Path setzt Pfade korrekt zusammen, PadRight/PadLeft bauen Spalten, und exit 1 bricht ein Skript mit Fehlercode ab (0 = Erfolg).
~/uebungen/05-pipeline.ps1 : aufgabe_01✓ gelöst1 aus N
01Was macht die Pipeline?
Was passiert bei Get-ChildItem -File | Measure-Object -Property Length -Sum?

Die Pipeline | reicht die Objekte des linken Befehls einzeln an den rechten weiter. Weil PowerShell dabei echte .NET-Objekte transportiert (keinen Text), kann Measure-Object direkt auf die Eigenschaft Length jedes Datei-Objekts zugreifen und die Summe bilden.

~/uebungen/05-pipeline.ps1 : aufgabe_02✓ gelöstoutput vorhersagen
02Summe mit Measure-Object
$sizes = @(120, 480, 600)
$total = ($sizes | Measure-Object -Sum).Sum
Write-Host "Summe: $total Bytes"
Was gibt die letzte Zeile aus?

Measure-Object -Sum gibt ein Ergebnis-Objekt zurück, keine nackte Zahl — deshalb holst du die Summe erst mit .Sum heraus: 120 + 480 + 600 = 1200. Nach demselben Muster funktionieren -Average (→ .Average), -Minimum und -Maximum.

~/uebungen/05-pipeline.ps1 : aufgabe_03✓ gelöstcode vervollständigen
03Dateien nach Endung gruppieren
Welches Cmdlet fasst Objekte mit gleichem Extension-Wert zu Gruppen zusammen?
$allFiles = Get-ChildItem -File -Recurse
$byExt = $allFiles |  Extension
Write-Host "Verschiedene Endungen: $($byExt.Count)"

Group-Object Extension legt für jeden vorkommenden Extension-Wert eine Gruppe an. Jede Gruppe hat .Name (die Endung), .Count (Anzahl der Dateien) und .Group (die Datei-Objekte selbst). $byExt.Count zählt hier also, wie viele verschiedene Endungen es gibt. Kurz-Alias: group.

~/uebungen/05-pipeline.ps1 : aufgabe_04✓ gelöstcode vervollständigen
04Größte Gruppe zuerst
Welcher Parameter dreht die Sortierung um, sodass die häufigste Endung an Position [0] steht?
$groups = $allFiles | Group-Object Extension
$sorted = $groups | Sort-Object Count 
Write-Host "Haeufigste Endung: $($sorted[0].Name)"

Sort-Object sortiert standardmäßig aufsteigend (kleinster Wert zuerst). -Descending dreht die Reihenfolge um, sodass die Gruppe mit dem größten Count vorne landet. .Name liefert dann die Endung dieser häufigsten Gruppe.

~/uebungen/05-pipeline.ps1 : aufgabe_05✓ gelöstzuordnung
05Bausteine des Report-Skripts
Ordne jedem Code-Baustein seine Wirkung im FolderReport.ps1 zu.
`"=" * 50`
`$ext.PadRight(15)`
`$count.ToString().PadLeft(4)`
`exit 1`

"=" * 50 wiederholt den String 50-mal — perfekt für Trennlinien. PadRight hängt Leerzeichen rechts an (Text linksbündig), PadLeft links (Zahlen rechtsbündig) — zusammen ergibt das saubere Spalten. exit 1 beendet das Skript mit Fehlercode: 0 bedeutet Erfolg, alles andere Fehler.

~/uebungen/05-pipeline.ps1 : aufgabe_06✓ gelöstoutput vorhersagen
06Bytes in KB umrechnen
$bytes = 2560
$kb = [math]::Round($bytes / 1KB, 1)
Write-Host "$kb KB"
Was gibt die letzte Zeile aus?

1KB ist die eingebaute Konstante 1024, also rechnet PowerShell 2560 / 1024 = 2.5. [math]::Round(..., 1) rundet auf eine Nachkommastelle (hier ändert sich nichts). In Strings gibt PowerShell Zahlen immer mit Punkt als Dezimaltrennzeichen aus, daher 2.5 KB.

~/uebungen/05-pipeline.ps1 : aufgabe_07✓ gelöstcode vervollständigen
07Report-Datei im Zielordner speichern
Welches Cmdlet setzt die beiden Pfadteile korrekt zu einem vollständigen Pfad zusammen?
$reportPath =  $FolderPath "FolderReport.txt"
Set-Content -Path $reportPath -Value $reportLines -Encoding UTF8

Join-Path fügt Pfadteile zusammen und kümmert sich selbst um den \ dazwischen — egal ob $FolderPath mit oder ohne Backslash endet. Das ist robuster als String-Verkettung wie "$FolderPath\FolderReport.txt".

~/uebungen/05-pipeline.ps1 : aufgabe_08✓ gelöstmehrfachauswahl
08Wahr oder falsch?
Welche Aussagen stimmen? Kreuze zwei an.

1KB = 1024 und 1MB = 1024 * 1024 = 1048576 Bytes (nicht 1 Million!). += hängt ein Element an — PowerShell baut dabei intern ein neues, größeres Array. Measure-Object liefert immer ein Ergebnis-Objekt, deshalb brauchst du .Sum. Und [math]::Round(3.14159, 2) ergibt 3.14, denn die 2 steht für zwei Nachkommastellen.

~/uebungen/05-pipeline.ps1 : aufgabe_09✓ gelösthands-on
09Final Challenge: FolderReport.ps1
Öffne eine echte PowerShell und arbeite die Schritte durch:
  1. Lege eine Datei FolderReport.ps1 an. Ganz oben: param([string]$FolderPath = "."). Prüfe mit Test-Path, ob der Ordner existiert — wenn nicht: rote Fehlermeldung (Write-Host ... -ForegroundColor Red) und Abbruch mit exit 1.
  2. Sammle alle Dateien mit Get-ChildItem -Path $FolderPath -File -Recurse und berechne mit Measure-Object: Anzahl, Gesamtgröße in MB und Durchschnittsgröße in KB (jeweils gerundet mit [math]::Round und den Konstanten 1MB/1KB).
  3. Gruppiere mit Group-Object Extension, sortiere mit Sort-Object Count -Descending und baue den Report zeilenweise auf: $reportLines = @() plus +=, Trennlinien aus "=" * 50, pro Endung eine Spalten-Zeile mit PadRight(15) und PadLeft(4).
  4. Gib alle Zeilen mit Write-Host aus und speichere den Report mit Join-Path und Set-Content -Encoding UTF8 als FolderReport.txt im untersuchten Ordner. Teste: .\FolderReport.ps1 -FolderPath C:\TestFolder (ein Ordner mit ein paar Dateien).
param([string]$FolderPath = ".")

# 1) Validierung: Ordner muss existieren
if (-not (Test-Path $FolderPath)) {
    Write-Host "Ordner nicht gefunden: $FolderPath" -ForegroundColor Red
    exit 1
}

# 2) Alle Dateien einsammeln (rekursiv, nur Dateien)
$allFiles = @(Get-ChildItem -Path $FolderPath -File -Recurse)

if ($allFiles.Count -eq 0) {
    Write-Host "Keine Dateien gefunden in: $FolderPath" -ForegroundColor Red
    exit 1
}

# 3) Statistik mit Measure-Object
$fileCount  = ($allFiles | Measure-Object).Count
$totalBytes = ($allFiles | Measure-Object -Property Length -Sum).Sum
$avgBytes   = ($allFiles | Measure-Object -Property Length -Average).Average

$totalMB = [math]::Round($totalBytes / 1MB, 2)
$avgKB   = [math]::Round($avgBytes / 1KB, 1)

# 4) Nach Endung gruppieren, haeufigste zuerst
$groups = $allFiles | Group-Object Extension | Sort-Object Count -Descending

# 5) Report zeilenweise aufbauen
$reportLines = @()
$reportLines += "=" * 50
$reportLines += "FOLDER REPORT: $FolderPath"
$reportLines += "=" * 50
$reportLines += "Dateien gesamt : $fileCount"
$reportLines += "Groesse gesamt : $totalMB MB"
$reportLines += "Durchschnitt   : $avgKB KB"
$reportLines += "-" * 50
$reportLines += "Dateitypen:"

foreach ($group in $groups) {
    $ext = $group.Name
    if ($ext -eq "") { $ext = "(ohne Endung)" }
    $reportLines += ($ext.PadRight(15) + $group.Count.ToString().PadLeft(4))
}

$reportLines += "=" * 50

# 6) Ausgeben
foreach ($line in $reportLines) {
    Write-Host $line
}

# 7) Speichern
$reportPath = Join-Path $FolderPath "FolderReport.txt"
Set-Content -Path $reportPath -Value $reportLines -Encoding UTF8
Write-Host "Report gespeichert: $reportPath" -ForegroundColor Green

Das Skript folgt dem klassischen Report-Muster: validieren (Test-Path + exit 1), Daten sammeln (Get-ChildItem -File -Recurse), rechnen (Measure-Object -Sum/-Average), gruppieren (Group-Object + Sort-Object Count -Descending), formatieren (+=, "=" * 50, PadRight/PadLeft) und speichern (Join-Path + Set-Content -Encoding UTF8). Genau nach diesem Ablauf sind auch echte Admin-Skripte aufgebaut.