PowerShell Trainer – Benannte Parameter und Parameter-Dekorator

In diesem Trainer übst du den Aufbau einer PowerShell-Funktion mit benannten Parametern, Parameter-Dekoratoren, Aliasen, Pflichtparametern, Switch-Parametern und ValidateSet.

Ziel ist eine Funktion namens:

check-userprofile

Diese Funktion soll für einen lokalen Benutzer das Home-Verzeichnis ermitteln und Dateien darin auswerten.

1. Grundlagen wiederholen

Wichtige Begriffe

Begriff Bedeutung
Parameter Eine Eingabe für ein Cmdlet, Skript oder eine Funktion.
Benannter Parameter Ein Parameter, der über seinen Namen angesprochen wird, z. B. -name.
Parameter-Dekorator Zusatzangabe wie [Parameter(Mandatory)], die das Verhalten eines Parameters festlegt.
Alias Alternativer Kurzname für einen Parameter, z. B. -n für -name.
Switch Schalterparameter ohne eigenen Wert, z. B. -size.
ValidateSet Beschränkt erlaubte Eingabewerte auf eine feste Auswahl.

2. Aufgabenstellung

Aufgabe:
Erstelle eine Funktion check-userprofile, die maximal drei benannte Parameter enthält. Die Funktion soll in ein Skript ausgelagert und per Dot-Sourcing eingebunden werden.
Parameter Eigenschaft Beschreibung
$name Pflichtparameter Lokaler Benutzername, Datentyp String, Aliasse user und n.
$size Switch Optionaler Schalter. Gibt zusätzlich die Gesamtgröße aller Dateien aus. Aliasse length und s.
$detail Optionaler String Nimmt nur All, BySize oder ByPercent entgegen und darf nicht NULL oder leer sein.

3. Aufgabe 1 – Funktionskopf ergänzen

Ergänze den Funktionskopf mit dem richtigen Namen.
function ____________ {
    param(

    )
}

Wie muss die Funktion heißen?

function check-userprofile {
    param(

    )
}

4. Aufgabe 2 – Pflichtparameter $name

Der Parameter $name soll zwingend angegeben werden. Außerdem soll er an erster Position nach dem Funktionsnamen eingegeben werden können. Der Datentyp ist String.
param(
    [Parameter(
        Mandatory = $true,
        Position = 0
    )]
    [string]$name
)

5. Aufgabe 3 – Aliasse für $name

Der Parameter $name soll die Aliasse user und n bekommen.
param(
    [Parameter(
        Mandatory = $true,
        Position = 0
    )]
    [Alias("user", "n")]
    [string]$name
)

6. Aufgabe 4 – Switch-Parameter $size

Der Parameter $size soll als Switch eingesetzt werden. Er ist optional und bekommt die Aliasse length und s.
param(
    [Parameter(Mandatory = $true, Position = 0)]
    [Alias("user", "n")]
    [string]$name,

    [Parameter()]
    [Alias("length", "s")]
    [switch]$size
)

7. Aufgabe 5 – Parameter $detail mit ValidateSet

Der Parameter $detail soll nur drei Werte erlauben: All, BySize und ByPercent. Außerdem darf er nicht NULL oder leer sein.
param(
    [Parameter(Mandatory = $true, Position = 0)]
    [Alias("user", "n")]
    [string]$name,

    [Parameter()]
    [Alias("length", "s")]
    [switch]$size,

    [Parameter()]
    [ValidateNotNullOrEmpty()]
    [ValidateSet("All", "BySize", "ByPercent")]
    [string]$detail
)

8. Aufgabe 6 – Home-Verzeichnis ermitteln

Das Home-Verzeichnis des lokalen Benutzerprofils soll über WMI ermittelt werden.

Welche Variable enthält laut Aufgabenhilfe das Home-Verzeichnis?

$homeverzeichnis = (
    Get-WmiObject Win32_UserProfile |
    Where-Object { $_.LocalPath -like "*\$name" }
).LocalPath

9. Aufgabe 7 – Dateien rekursiv ermitteln

Alle Dateien im Home-Verzeichnis sollen rekursiv und inklusive versteckter Dateien ermittelt werden. Fehler sollen unterdrückt werden.
$files = Get-ChildItem -Path $homeverzeichnis -Recurse -Force -File -ErrorAction SilentlyContinue
Wichtig: -File braucht einen Bindestrich. Ohne Bindestrich wäre File kein Parameter.

10. Aufgabe 8 – Anzahl und Gesamtgröße berechnen

Aus der Dateiliste sollen die Gesamtanzahl und die Gesamtgröße berechnet werden.
$gesamtAnzahl = $files.Count
$gesamtGroesse = ($files | Measure-Object -Property Length -Sum).Sum

if (-not $gesamtGroesse) {
    $gesamtGroesse = 0
}

11. Aufgabe 9 – Dateien nach Größe gruppieren

Die Dateien sollen in vier Größenklassen eingeteilt werden: bis 1 KiB, 1 KiB bis 1 MiB, 1 MiB bis 1 GiB und größer als 1 GiB.
$bis1KiB = $files | Where-Object { $_.Length -le 1KB }
$bis1MiB = $files | Where-Object { $_.Length -gt 1KB -and $_.Length -le 1MB }
$bis1GiB = $files | Where-Object { $_.Length -gt 1MB -and $_.Length -le 1GB }
$groesser = $files | Where-Object { $_.Length -gt 1GB }

12. Aufgabe 10 – Detailparameter verstehen

Ordne die Werte des Parameters -detail der richtigen Ausgabe zu.
Detailwert Bedeutung
All Gesamtzahl aller Dateien
BySize Anzahl der Dateien gruppiert nach Größe
ByPercent Prozentualer Anteil der Dateien nach Größenklassen

Welcher Wert zeigt die prozentuale Verteilung?

13. Komplettlösung

Diese Komplettlösung erfüllt die Aufgabenstellung mit maximal drei benannten Parametern: $name, $size und $detail.

function check-userprofile {
    param(
        [Parameter(
            Mandatory = $true,
            Position = 0
        )]
        [Alias("user", "n")]
        [string]$name,

        [Parameter()]
        [Alias("length", "s")]
        [switch]$size,

        [Parameter()]
        [ValidateNotNullOrEmpty()]
        [ValidateSet("All", "BySize", "ByPercent")]
        [string]$detail
    )

    $homeverzeichnis = (
        Get-WmiObject Win32_UserProfile |
        Where-Object { $_.LocalPath -like "*\$name" }
    ).LocalPath

    if (-not $homeverzeichnis) {
        Write-Error "Kein lokales Benutzerprofil für '$name' gefunden."
        return
    }

    $files = Get-ChildItem -Path $homeverzeichnis -Recurse -Force -File -ErrorAction SilentlyContinue

    $gesamtAnzahl = $files.Count
    $gesamtGroesse = ($files | Measure-Object -Property Length -Sum).Sum

    if (-not $gesamtGroesse) {
        $gesamtGroesse = 0
    }

    $bis1KiB = $files | Where-Object { $_.Length -le 1KB }
    $bis1MiB = $files | Where-Object { $_.Length -gt 1KB -and $_.Length -le 1MB }
    $bis1GiB = $files | Where-Object { $_.Length -gt 1MB -and $_.Length -le 1GB }
    $groesser = $files | Where-Object { $_.Length -gt 1GB }

    if (-not $detail) {
        if ($size) {
            [PSCustomObject]@{
                Benutzer        = $name
                HomeVerzeichnis = $homeverzeichnis
                Dateien         = $gesamtAnzahl
                Gesamtgroesse   = $gesamtGroesse
            }
        }
        else {
            [PSCustomObject]@{
                Benutzer        = $name
                HomeVerzeichnis = $homeverzeichnis
                Dateien         = $gesamtAnzahl
            }
        }

        return
    }

    if ($detail -eq "All") {
        if ($size) {
            [PSCustomObject]@{
                Benutzer        = $name
                HomeVerzeichnis = $homeverzeichnis
                Dateien         = $gesamtAnzahl
                Gesamtgroesse   = $gesamtGroesse
            }
        }
        else {
            [PSCustomObject]@{
                Benutzer        = $name
                HomeVerzeichnis = $homeverzeichnis
                Dateien         = $gesamtAnzahl
            }
        }

        return
    }

    if ($detail -eq "BySize") {
        [PSCustomObject]@{
            Benutzer           = $name
            Bis_1KiB           = $bis1KiB.Count
            Von_1KiB_bis_1MiB  = $bis1MiB.Count
            Von_1MiB_bis_1GiB  = $bis1GiB.Count
            Groesser_1GiB      = $groesser.Count
            Gesamt             = $gesamtAnzahl
        }

        return
    }

    if ($detail -eq "ByPercent") {
        if ($gesamtAnzahl -eq 0) {
            [PSCustomObject]@{
                Benutzer           = $name
                Bis_1KiB           = "0 %"
                Von_1KiB_bis_1MiB  = "0 %"
                Von_1MiB_bis_1GiB  = "0 %"
                Groesser_1GiB      = "0 %"
                Gesamt             = 0
            }

            return
        }

        [PSCustomObject]@{
            Benutzer           = $name
            Bis_1KiB           = "{0:N2} %" -f (($bis1KiB.Count / $gesamtAnzahl) * 100)
            Von_1KiB_bis_1MiB  = "{0:N2} %" -f (($bis1MiB.Count / $gesamtAnzahl) * 100)
            Von_1MiB_bis_1GiB  = "{0:N2} %" -f (($bis1GiB.Count / $gesamtAnzahl) * 100)
            Groesser_1GiB      = "{0:N2} %" -f (($groesser.Count / $gesamtAnzahl) * 100)
            Gesamt             = $gesamtAnzahl
        }

        return
    }
}

14. Dot-Sourcing und Testaufrufe

Skript einbinden

. .\check-userprofile.ps1
Vor dem Pfad steht ein Punkt, dann ein Leerzeichen, dann der Dateiname. Dadurch wird die Funktion in die aktuelle PowerShell-Sitzung geladen.

Testaufrufe

check-userprofile -name "Benutzername"

check-userprofile "Benutzername"

check-userprofile -user "Benutzername"

check-userprofile -n "Benutzername"

check-userprofile -name "Benutzername" -size

check-userprofile -name "Benutzername" -s

check-userprofile -name "Benutzername" -detail All

check-userprofile -name "Benutzername" -detail BySize

check-userprofile -name "Benutzername" -detail ByPercent

15. Prüfungsfragen

Beantworte die Fragen zur Wiederholung.

Frage 1

Welcher Parameter-Dekorator macht einen Parameter verpflichtend?

Frage 2

Welcher Datentyp wird für einen Schalterparameter verwendet?

Frage 3

Welche Validierung beschränkt erlaubte Eingabewerte auf eine feste Auswahl?

Frage 4

Welcher Parameter erlaubt den Aufruf check-userprofile Felix ohne -name?

16. Merksätze

Merksatz 1:
Mit param() definiert man Eingabeparameter für Skripte oder Funktionen.
Merksatz 2:
[Parameter(Mandatory = $true)] macht einen Parameter verpflichtend.
Merksatz 3:
[Alias("user", "n")] gibt einem Parameter alternative Namen.
Merksatz 4:
[switch] erstellt einen Schalterparameter ohne eigenen Wert.
Merksatz 5:
[ValidateSet()] begrenzt die erlaubten Werte eines Parameters.