Vier neue Wochen nach Rahmenplan, im bestehenden Format: - Woche 5 Ausbildung, Betrieb und Zusammenarbeit (C1, C2, C5) - Woche 6 IT-Sicherheit und Datenschutz (A6, LF4) - Woche 7 Skripting mit PowerShell (A10, A4) - Woche 8 Datensicherung und Speicher (A9) 12 Handouts, 38 Merkkarten, 4 Praxisaufgaben, 2 Checklisten, 2 Lernzielkontrollen, 22 Glossareintraege, zwei neue Themenbloecke. Jede Berufsbildposition ist jetzt von mindestens einem Inhalt beruehrt. Die Praxisaufgaben bauen aufeinander auf: Die Abteilungsuebersicht aus 5.1 ist Grundlage der Schutzbedarfsfeststellung in 6.1, und deren Ergebnis ist Massstab fuer die Sicherungspruefung in 8.1. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
87 lines
4.4 KiB
Markdown
87 lines
4.4 KiB
Markdown
---
|
||
id: P3
|
||
titel: Ein Skript schreiben, das man in einem Jahr noch versteht
|
||
block: programmierung
|
||
woche: 7
|
||
worum: Ein Skript, das nur sein Verfasser bedienen kann, ist eine Abhängigkeit. Ein gutes Skript erklärt sich, prüft seine Eingaben und meldet Fehler, statt sie zu verschweigen.
|
||
rahmenplan: [A10, A4, A5]
|
||
lernfeld: LF5
|
||
merksatz: Sagen, was es tut. Prüfen, was hineinkommt. Melden, was schiefgeht. Erst mit -WhatIf laufen lassen.
|
||
karten:
|
||
- frage: Wozu dient ein param-Block am Anfang eines Skripts?
|
||
antwort: Er legt fest, welche Eingaben das Skript erwartet, mit Typ und ob sie Pflicht sind. Werte stehen dann nicht fest im Code, und PowerShell fragt fehlende Pflichtangaben selbst ab.
|
||
- frage: Warum fängt ein try-catch-Block manche Fehler nicht ab, und wie behebt man das?
|
||
antwort: Viele Cmdlets melden Fehler nur und laufen weiter (nicht abbrechende Fehler). Mit -ErrorAction Stop am Befehl wird daraus ein abbrechender Fehler, den catch auffängt.
|
||
- frage: Was bewirkt die Ausführungsrichtlinie RemoteSigned?
|
||
antwort: Selbst geschriebene, lokale Skripte laufen; aus dem Internet heruntergeladene Skripte nur, wenn sie signiert sind. Sie schützt vor versehentlichem Ausführen, ist aber keine Sicherheitsgrenze.
|
||
---
|
||
|
||
## Das Wesentliche
|
||
|
||
- **Ein Kopf mit Hilfe:** Ein Block `<# .SYNOPSIS … .EXAMPLE … #>` ganz oben macht das
|
||
Skript für `Get-Help .\skript.ps1` lesbar. Darin steht, was es tut, was es braucht und ein
|
||
Beispielaufruf.
|
||
- **Eingaben als Parameter**, nicht fest im Code: Pfade, Rechnernamen und Grenzwerte gehören
|
||
in den `param()`-Block. `[Parameter(Mandatory)]` macht eine Angabe zur Pflicht.
|
||
- **Namen, die etwas sagen:** `$freierPlatzProzent` statt `$x`. Kommentare erklären das
|
||
**Warum**, nicht das Was – das Was steht im Code.
|
||
- **Fehler nicht verschlucken.** `try { … -ErrorAction Stop } catch { … }` fängt Fehler auf
|
||
und meldet sie verständlich. Ein leerer `catch`-Block ist schlimmer als gar keiner.
|
||
- **Erst trocken, dann echt.** Mit `[CmdletBinding(SupportsShouldProcess)]` bekommt das eigene
|
||
Skript `-WhatIf`. Ein Skript, das löscht, ändert oder verschiebt, läuft zuerst so.
|
||
- **Klein anfangen und testen.** Erst an einem Testrechner, dann an einem echten, dann an
|
||
allen. Jede Stufe mit Blick auf die Ausgabe.
|
||
- **Versionieren.** Skripte gehören in ein Git-Repository der IT, nicht auf den Desktop. So
|
||
sieht man, wer wann was geändert hat, und kommt zur letzten funktionierenden Fassung zurück.
|
||
- **Ausführungsrichtlinie:** Auf Clients ist meist `RemoteSigned` eingestellt. Sie verhindert
|
||
versehentliches Ausführen fremder Skripte, ist aber keine Sicherheitsgrenze.
|
||
|
||
## Übersicht
|
||
|
||
```powershell
|
||
<#
|
||
.SYNOPSIS
|
||
Löscht Protokolldateien, die älter als eine bestimmte Anzahl Tage sind.
|
||
.EXAMPLE
|
||
.\Protokolle-Aufraeumen.ps1 -Pfad D:\Logs -Tage 30 -WhatIf
|
||
#>
|
||
[CmdletBinding(SupportsShouldProcess)]
|
||
param(
|
||
[Parameter(Mandatory)][string]$Pfad,
|
||
[int]$Tage = 30
|
||
)
|
||
|
||
if (-not (Test-Path $Pfad)) {
|
||
throw "Den Pfad $Pfad gibt es nicht."
|
||
}
|
||
|
||
$stichtag = (Get-Date).AddDays(-$Tage)
|
||
$alt = Get-ChildItem $Pfad -Filter *.log -File | Where-Object LastWriteTime -lt $stichtag
|
||
|
||
foreach ($datei in $alt) {
|
||
if ($PSCmdlet.ShouldProcess($datei.FullName, 'Löschen')) {
|
||
try {
|
||
Remove-Item $datei.FullName -ErrorAction Stop
|
||
}
|
||
catch {
|
||
Write-Warning "Konnte $($datei.Name) nicht löschen: $($_.Exception.Message)"
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
## Prüfungsfrage
|
||
|
||
**Frage:** Ein Kollege hat ein Skript geschrieben, das auf allen Rechnern temporäre Dateien
|
||
löscht. Pfad und Rechnerliste stehen fest im Code, Fehler werden nicht behandelt. Nennen Sie
|
||
vier Verbesserungen und begründen Sie sie.
|
||
|
||
**Antwort:** (1) Pfad und Rechnerliste als Parameter übergeben – das Skript lässt sich dann
|
||
für andere Fälle nutzen, ohne den Code zu ändern. (2) `-WhatIf` unterstützen und das Skript
|
||
zuerst trocken laufen lassen – bei einem löschenden Skript lässt sich so vorab prüfen, was
|
||
betroffen wäre. (3) Fehlerbehandlung mit `try`/`catch` und `-ErrorAction Stop` – damit nicht
|
||
erreichbare Rechner oder gesperrte Dateien gemeldet und nicht stillschweigend übergangen
|
||
werden. (4) Einen Hilfeblock mit Beschreibung und Beispiel ergänzen und das Skript im
|
||
Repository der IT versionieren – so kann es auch jemand anderes betreuen. Ebenfalls richtig:
|
||
Eingaben prüfen, z. B. mit `Test-Path`, und ein Protokoll der gelöschten Dateien schreiben.
|