- 1 Section
- 10 Lessons
- unbegrenzt
- PowerShell – Grundlagen bis Automation10
- 1.1Was ist PowerShell? Versionen und ISE vs. VS Code
- 1.2Cmdlets: Verben, Substantive, Get-Help
- 1.3Variablen, Datentypen und Pipeline
- 1.4Kontrollstrukturen: if, switch, for, foreach, while
- 1.5Funktionen und Module
- 1.6Dateisystem und Prozesse verwalten
- 1.7Active Directory mit PowerShell verwalten
- 1.8Netzwerkbefehle: Test-NetConnection, Resolve-DnsName
- 1.9Skripte planen: Task Scheduler
- 1.10Praxisprojekt: AD-Onboarding-Skript
Skripte planen: Task Scheduler
Du hast jetzt mächtige Skripte – aber sie laufen nur wenn du sie manuell startest. In der Praxis willst du Skripte zeitgesteuert ausführen: jeden Abend ein Backup, jede Stunde ein Healthcheck, jeden Montag ein Report. Das macht der Task Scheduler – Windows' Pendant zum cron-Daemon aus K43.
Du kannst Tasks per grafischer Konsole („Aufgabenplanung") anlegen oder – viel besser für Reproducibility – per PowerShell. Die ScheduledTasks-Cmdlets sind seit PowerShell 3.0 dabei und ersetzen das alte schtasks.exe. Diese Lektion zeigt dir wie du Tasks erstellst, verwaltest und überwachst.
1) Was ist der Task Scheduler?
Der Windows Task Scheduler ist ein System-Dienst, der im Hintergrund läuft und wartet bis ein Auslöser („Trigger") feuert. Dann führt er eine vorher festgelegte „Action" aus – meistens ein Programm oder Skript. Stell ihn dir wie einen Roboter-Sekretär vor: er beobachtet die Uhr, das System, Events – und drückt zur richtigen Zeit den richtigen Knopf.
Im Vergleich zu cron auf Linux ist der Task Scheduler deutlich umfangreicher. Cron kennt nur Zeit-Trigger; Task Scheduler kann viel mehr:
- Zeit-basiert (Minute/Std/Tag)
- Boot (@reboot)
- Beliebige Shell-Befehle
- Klassische Crontab-Datei
- Schlank und schnell
- Zeit-basiert
- Login eines Users
- System-Start
- Idle-State
- Event Log entries
- USB-Geräte angeschlossen
- Programme starten
- Mails versenden (Legacy)
- Nachrichten anzeigen (Legacy)
- Nur bei Netzstrom
- Nur bei Idle
- Nur mit Netzwerk
2) Anatomie eines Tasks
Ein Task Scheduler-Task hat drei Hauptbestandteile. Klick die Teile:
3) Trigger: die Auslöser
Die wichtigsten Trigger-Arten:
4) Einen Task per PowerShell anlegen
Das Kern-Pattern: einzelne Teile (Trigger, Action, Principal, Settings) erstellen und dann als Task registrieren. Hier der vollständige Code für „täglich 3 Uhr Backup-Skript starten":
Wichtige Detail-Erklärungen:
- -NoProfile: lädt nicht das Benutzer-Profil – schneller und unabhängig von User-Konfig
- -ExecutionPolicy Bypass: umgeht die Execution Policy aus L1 für diesen Lauf – damit dein Skript auch in restriktiven Umgebungen läuft
- -File: gibt das Skript an, mit vollem absoluten Pfad
- SYSTEM-Account: das mächtigste Konto auf einem Windows-System. Hat alle Rechte, läuft auch ohne eingeloggten User. Aber: kein Zugriff auf User-Profile, keine Netzwerk-Shares (außer per UNC mit Credentials)
- RunLevel Highest: läuft mit höchster Berechtigung (Admin)
- StartWhenAvailable: wenn der geplante Zeitpunkt verpasst wurde (z.B. Server war aus), läuft der Task sobald möglich nach. Wie cron mit Persistent=true bei systemd-Timer.
5) Bestehende Tasks verwalten
Tasks anzeigen, ändern, manuell auslösen, löschen – alles per PowerShell:
6) Häufige Stolperfallen
Die typischen Probleme die Task-Scheduler-Jobs zum Scheitern bringen:
- Skript läuft manuell, aber nicht aus Task Scheduler: meist Berechtigungs- oder Pfad-Problem. Im Skript IMMER absolute Pfade, NIE auf
~oder relative Pfade verlassen. Der Working-Directory ist standardmäßigC:\Windows\System32! - Execution Policy verhindert Start: in Action-Argument
-ExecutionPolicy Bypassmitgeben (siehe L1). - Kein Output sichtbar: Task Scheduler-Jobs haben kein Konsolen-Fenster.
Write-Hostverschwindet ins Nichts. Lösung: in Skript Logging einbauen mitSet-ContentoderOut-Filein eine Logdatei (siehe L6). - SYSTEM-Account hat keinen Zugriff auf Netzwerk-Shares: bei UNC-Pfaden entweder Service-Account verwenden oder Credentials im Skript laden.
- Profil-Variablen fehlen:
$env:PSModulePath, persönliche Aliase aus dem PowerShell-Profil sind nicht da. Wenn dein Skript Module braucht: explizit mitImport-Moduleladen. - UI-Interaktion in Skript:
Read-Hostoder Pop-ups in einem Task-Skript = Skript hängt. Im SYSTEM-Kontext gibt es keine GUI.
7) Logging einbauen
Pflichtprogramm für jeden produktiven Task: ein robustes Logging. Hier ein Pattern das in deinen Skripten oben rein sollte:
Mit täglicher Logdatei behält der Log Übersicht. Optionale Erweiterung: alte Logdateien (älter als 30 Tage) automatisch löschen – mit den File-Cmdlets aus L6: Get-ChildItem $logDir | Where-Object LastWriteTime -lt (Get-Date).AddDays(-30) | Remove-Item.
8) Monitoring: lief der Task erfolgreich?
Ein geplanter Task ist nur wertvoll wenn du auch weißt OB er gelaufen ist und ERFOLGREICH war. Das einfachste Monitoring: Get-ScheduledTaskInfo:
LastTaskResult: 0 heißt Erfolg. 267009 (0x41301) heißt „Task läuft gerade". Andere Werte sind Fehler-Codes. Im Skript kannst du mit exit 1 selbst einen Fehler signalisieren – der Task Scheduler übernimmt den Code als LastTaskResult.
Solch ein Monitor-Skript kann selbst per Task Scheduler stündlich laufen – wenn Tasks fehlschlagen, Mail an Admin. Ein klassisches Setup für Server-Farmen.
9) Tasks zwischen Servern übertragen
Du hast einen Task perfekt eingerichtet und willst ihn auf 20 weiteren Servern haben. Lösung: Task als XML exportieren, dann auf den anderen Servern importieren:
Damit ist Task-Verteilung skalierbar. Pro-Setup: die XML-Datei in einem zentralen Share oder Git-Repo halten – dann hast du Versionierung deiner geplanten Tasks. Das ist auch Teil von Infrastructure-as-Code.
10) Best-Practices
Die Punkte die Task-Scheduler-Skripte robust machen:
- Absolute Pfade überall. Niemals auf relativen Pfaden bauen.
- -NoProfile -ExecutionPolicy Bypass in der Action-Argument-Zeile.
- Logging implementieren, mindestens INFO am Start und Ende, ERROR im catch.
- Versuche und Fehler mit try/catch (siehe L4). Bei Fehler
exit 1oderthrow, damit Task-Scheduler den Fehler sieht. - ExecutionTimeLimit setzen damit hängende Skripte nicht ewig laufen.
- Sinnvolle Task-Namen mit Präfix:
FIRMA-Backup-Dailystatt nurBackup. Macht das Filtern leichter. - Description ausfüllen: was macht der Task, von wem ist er, Stand wann.
- Test mit Start-ScheduledTask: zum manuellen Auslösen, ohne auf den Trigger zu warten.
- Erst mit -WhatIf bei Tasks die löschen oder ändern (siehe L2 Common Parameters).
- Versionsverwaltung: Skripte und XML-Exports in einem Git-Repo (siehe K54 CI/CD).
Zusammenfassung
Der Task Scheduler ist Windows' Pendant zu cron – aber deutlich mächtiger. Tasks bestehen aus 4 Teilen: Trigger (Wann?), Action (Was?), Principal (Wer?), Settings (Wie?). PowerShell-Cmdlets dazu: New-ScheduledTaskAction, New-ScheduledTaskTrigger, New-ScheduledTaskPrincipal, New-ScheduledTaskSettingsSet, dann Register-ScheduledTask zum Anlegen. Verwalten mit Get-/Start-/Stop-/Enable-/Disable-/Unregister-ScheduledTask. Trigger-Varianten: Daily, Weekly, Once, AtStartup, AtLogon, Event-basiert. Wichtig in der Action: powershell.exe -NoProfile -ExecutionPolicy Bypass -File C:\absoluter\Pfad\skript.ps1. Stolperfallen: absolute Pfade nötig, kein UI, SYSTEM-Account hat keinen Netzwerk-Share-Zugriff, Profil-Variablen fehlen, Output ins Nichts (Logging einbauen!). Monitoring mit Get-ScheduledTaskInfo – LastTaskResult 0 = OK. Tasks übertragen via XML-Export/-Import, auch in Massen mit Invoke-Command (siehe L8).
