KI-Übungen
Die Beispielskripte findest du im Lab unter C:\Kurs\KI\. Sie stehen auch hier auf der Seite.
Öffne C:\Kurs\KI\altes-skript.ps1 (siehe unten, Passwort ist erfunden).
$s = gwmi win32_service | ? {$_.StartMode -eq "Auto" -and $_.State -ne "Running"}foreach($x in $s){ write-host $x.Name $x.State }$pw = "Sommer2024!"$c = New-Object System.Management.Automation.PSCredential("PSLAB\svc-backup",(ConvertTo-SecureString $pw -AsPlainText -Force))Invoke-Expression ("net use Z: \\dc01\Kursdaten /user:PSLAB\svc-backup " + $pw)gci C:\Kurs\Daten\Logs | ? {$_.LastWriteTime -lt (get-date).AddDays(-30)} | del- Lass dir das Skript von der KI zeilenweise erklären.
- Prüfe die Erklärung: Führe die erste Zeile ohne die letzte aus (nicht das ganze Skript!). Stimmt die Beschreibung der KI mit dem überein, was du siehst?
- Notiere zwei Dinge, die die KI richtig erklärt hat, und eines, das du selbst nachschlagen musstest.
Lösung anzeigen
Zeile 1 ist ein Dienst-Report (Starttyp „Auto”, Status nicht „Running”). Zeile 2 gibt die Ergebnisse aus. Zeilen 3 bis 5 enthalten ein Klartextpasswort und bauen daraus Zugangsdaten und einen Netzwerkzugriff. Die letzte Zeile löscht Logdateien, die älter als 30 Tage sind, ohne Rückfrage.
Wichtige Prüfpunkte: gwmi ist Get-WmiObject und existiert in PowerShell 7 nicht. ? ist Where-Object, gci ist Get-ChildItem, del ist Remove-Item.
Bitte die KI, das Skript aus K.1 zu reviewen und in eine moderne, sichere Fassung zu bringen.
- Welche Probleme findet die KI? Welche findest du, die sie nicht nennt?
- Lass sie eine verbesserte Fassung schreiben, mit
Get-CimInstance, vollen Cmdlet-Namen, Parametern und-WhatIffür das Löschen. Das Passwort darf nicht im Code stehen. - Vergleiche vorher und nachher: Liefert der Dienst-Report dasselbe Ergebnis?
Lösung anzeigen
Typische Befunde: Aliase, Get-WmiObject, Klartextpasswort, Invoke-Expression mit Passwort in der Kommandozeile (taucht in Prozesslisten und Logs auf), Löschen ohne -WhatIf, feste Pfade, keine Fehlerbehandlung. Ein Prüfstein für die verbesserte Fassung: Der Dienst-Report muss für Get-CimInstance Win32_Service -Filter "StartMode = 'Auto' AND State <> 'Running'" dieselben Dienste liefern wie vorher.
Eine KI hat folgende „Lösung” für „Zeige alle AD-Benutzer, die sich 90 Tage nicht angemeldet haben, und löschen alle Dateien älter als 30 Tage auf PSLAB-02” geliefert:
Get-ADUser -Filter * | Get-ADUserLastLogon -Days 90 -Format TableGet-ChildItem C:\Kurs\Daten -Recurse -OlderThan 30d | Remove-Item -ForceGet-Service -Name Spooler -ComputerName PSLAB-02Invoke-Parallel -ComputerName PSLAB-02 -ScriptBlock { Get-Process }Set-ExecutionPolicy -Scope Everything -ExecutionPolicy Unrestricted- Prüfe jede Zeile mit
Get-CommandundGet-Help. Welche Cmdlets, Parameter oder Werte existieren nicht oder nicht in PowerShell 7? - Welche Zeile ist außerdem gefährlich, auch wenn sie syntaktisch stimmen würde?
- Frage die KI, ob ihre Antwort Fehler enthält. Findet sie sie? Was ändert sich, wenn du ihr die Fehlermeldungen zeigst?
Lösung anzeigen
| Zeile | Befund |
|---|---|
Get-ADUserLastLogon |
Cmdlet existiert nicht (Get-Command meldet einen Fehler) |
-OlderThan 30d |
Parameter existiert nicht. Richtig: Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-30) } |
Get-Service -ComputerName |
In PowerShell 7 nicht vorhanden. Richtig: Invoke-Command -ComputerName … { Get-Service … } |
Invoke-Parallel |
Kein Bestandteil von PowerShell. Richtig: ForEach-Object -Parallel oder Invoke-Command mit mehreren Computernamen |
-Scope Everything |
Ungültiger Wert (gültig: Process, CurrentUser, LocalMachine, …). Die Absicht, Unrestricted zu setzen, ist zudem unnötig riskant |
Remove-Item -Force auf ganze Verzeichnisbäume |
Gefährlich: löscht ohne Rückfrage. Immer zuerst mit -WhatIf |
Lass die KI das Skript aus K.1 auf Sicherheitsprobleme prüfen und nach Schweregrad ordnen. Beurteile selbst:
- Welche Befunde sind wirklich kritisch, welche sind Stilfragen?
- Wie würdest du das Passwort stattdessen bereitstellen? (Siehe Kapitel „Anmeldeinformationen und Geheimnisse”.)
Lösung anzeigen
Kritisch: Klartextpasswort im Skript, Passwort in der Befehlszeile von net use (sichtbar in Prozess- und Ereignisprotokollen), Invoke-Expression mit zusammengesetzter Eingabe, ungeprüftes Löschen. Stilfragen: Aliase, Groß-/Kleinschreibung. Das Passwort gehört in einen Tresor (Get-Secret) oder wird per Get-Credential abgefragt, und die Netzlaufwerk-Verbindung läuft über New-PSDrive -Credential oder New-SmbMapping.
Beschreibe der KI mit den Prompt-Bausteinen folgende Aufgabe und erzeuge einen ersten Entwurf:
„Erstelle einen Bericht über alle Benutzer der Abteilung IT: Name, Anmeldename, Konto aktiv/deaktiviert, Datum der letzten Anmeldung. Ausgabe als CSV.”
- Vergleiche einen schlechten Prompt („Schreib ein Skript für AD-Benutzer”) mit deinem guten Prompt. Was unterscheidet die Ergebnisse?
- Prüfe den Entwurf mit
Get-CommandundGet-Help, dann im Lab. Funktioniert er? - Verbessere ihn im Dialog (zum Beispiel: Parameter für die Abteilung, Fehlerbehandlung, deutsche Kommentare).
Lösung anzeigen
Ein Entwurf, der sich bewährt hat:
param([string]$Abteilung = 'IT', [string]$Pfad = 'C:\Kurs\Ausgabe\ad-bericht.csv')
Get-ADUser -Filter "Department -eq '$Abteilung'" -Properties Department, LastLogonDate | Select-Object Name, SamAccountName, Enabled, LastLogonDate | Export-Csv -Path $PfadPrüfpunkte: -Properties ist nötig, weil LastLogonDate nicht zu den Standardeigenschaften gehört. LastLogonDate wird nur mit niedriger Genauigkeit repliziert und kann bis zu 14 Tage nachhinken.
- Lass die KI für deine Funktion
Get-FreierSpeicher(Tag 3, Block 1) Comment-Based Help schreiben und prüfe die Beispiele. - Lass sie drei Pester-Tests vorschlagen. Verstehst du jeden Test? Führe sie mit
Invoke-Pesteraus. - Welcher Test ist überflüssig oder falsch? Warum?
Lösung anzeigen
Gute Kandidaten für einen überflüssigen Test: ein Test, der nur prüft, dass „etwas” zurückkommt (Should -Not -BeNullOrEmpty) und damit praktisch immer besteht, oder ein Test, der den Wert einer externen Abhängigkeit (aktueller freier Speicher) mit einer festen Zahl vergleicht.
Formuliere in fünf Sätzen deine Regeln, wie du KI in deinem Arbeitsalltag mit PowerShell einsetzt: Wofür ja, wofür nein, was prüfst du immer, was gibst du nie ein. Tausche dich mit den anderen Teilnehmern aus.
Beispielregeln
- Ich lasse mir Code erklären, bevor ich ihn ausführe.
- Ich prüfe jedes Cmdlet mit
Get-CommandundGet-Help. - Ich teste Änderungen zuerst mit
-WhatIfund in einer Testumgebung. - Ich gebe keine Passwörter, Token, Kundendaten oder vertraulichen Skripte in externe Dienste ein.
- Ich verstehe jede Zeile, die ich ausführe. Was ich nicht verstehe, führe ich nicht in Produktion aus.