PowerShell-Ausführungsrichtlinie per GPO: Warum „Skriptausführung aktivieren“ nicht greift
Die Gruppenrichtlinie Skriptausführung aktivieren (englisch Turn on Script Execution) ist der zentrale Hebel, um die PowerShell-Ausführungsrichtlinie im Active Directory durchzusetzen. Trotzdem läuft auf dem Server ein Skript weiter, das laut Richtlinie blockiert sein sollte – oder umgekehrt wird ein sauberes Wartungsskript abgewiesen. Meist steckt kein GPO-Defekt dahinter, sondern eine von vier typischen Ursachen.
Fehlerbild
Ein Anwender oder ein geplanter Task erhält beim Start eines .ps1-Skripts:
File C:\Scripts\report.ps1 cannot be loaded because running scripts
is disabled on this system.
+ CategoryInfo : SecurityError: (:) [], PSSecurityException
+ FullyQualifiedErrorId : UnauthorizedAccess
Ein Admin setzt daraufhin Set-ExecutionPolicy -ExecutionPolicy RemoteSigned. Der Befehl läuft fehlerfrei durch, die Wirkung bleibt aber aus. Genau dieses Muster ist der Hinweis auf eine vorgelagerte Gruppenrichtlinie.
Ursache 1: Die GPO überstimmt alle lokalen Scopes
Eine per Gruppenrichtlinie gesetzte Richtlinie erscheint als Scope MachinePolicy oder UserPolicy und überstimmt alles andere – auch Process und das per Cmdlet gesetzte LocalMachine. Der Rechner gewinnt dabei gegen den Benutzer: Computer Configuration schlägt User Configuration.
Der häufigere Fall ist der Spiegelfehler: Die Richtlinie liegt nur in der Benutzerkonfiguration. Ein Dienstkonto oder ein Task unter einem anderen Konto bekommt sie nie ab. Gehört die Einstellung deshalb grundsätzlich in die Computerkonfiguration.
Ursache 2: „Nicht konfiguriert“ statt aktiv
Nur aktiviert mit der Auswahl „Lokale Skripts und fernsignierte Skripts zulassen“ entspricht RemoteSigned. Wer die Einstellung auf „Nicht konfiguriert“ belässt, ändert nichts – es gilt weiter der Wert, den jemand einst lokal per Set-ExecutionPolicy hinterlassen hat.
Wird die Richtlinie deaktiviert, entspricht das Restricted: gar keine Skripte mehr, auch keine signierten. Das ist kein „entfernt“, sondern ein hartes Blockieren.
Diagnose
Schritt 1 liefert sofort die Antwort, welcher Scope gewinnt:
Get-ExecutionPolicy -List
Steht bei MachinePolicy ein Wert, kommt die Richtlinie vom Domänencontroller. Lokale Änderungen sind dann wirkungslos – auch wenn der Befehl ohne Fehlermeldung durchläuft.
Schritt 2 prüft die Registry direkt. Die Richtlinie schreibt zwei Werte unter den Policy-Key:
Get-ItemProperty -Path 'HKLM:\Software\Policies\Microsoft\Windows\PowerShell'
Erwartetes Ergebnis bei „Lokale Skripts und fernsignierte Skripts zulassen“: EnableScripts = 1 und ExecutionPolicy = RemoteSigned. Fehlt der Schlüssel komplett, ist die GPO nicht angekommen.
Schritt 3 klärt, ob die GPO überhaupt verknüpft und nicht gefiltert wurde:
gpresult /r /scope computer
gpresult /h C:\Temp\gpreport.html
Im HTML-Bericht steht zu jeder Richtlinie, ob sie angewendet oder verworfen wurde – mitsamt Grund wie Sicherheitsfilter, WMI-Filter oder „Deaktiviert“.
Lösung: Richtlinie korrekt setzen
- Computer Configuration → Administrative Templates → Windows Components → Windows PowerShell öffnen.
- Skriptausführung aktivieren auf Aktiviert stellen und Lokale Skripts und fernsignierte Skripts zulassen wählen.
- Die GPO mit der OU der Server-Computerobjekte verknüpfen, nicht mit einer Benutzer-OU.
- Sicherheitsfilter auf Domain Computers belassen und die eigenen Rechte auf „Anwenden“ prüfen.
- Auf dem Client anwenden und nachprüfen:
gpupdate /force
Get-ExecutionPolicy -List
Eine neue Konsole ist danach Pflicht. Der Scope Process lebt in der offenen Sitzung weiter und hält den alten Wert, bis das Fenster geschlossen wird.
Ursache 3: ADMX fehlt im zentralen Speicher
Ist die Einstellung im Editor gar nicht erst auffindbar, fehlen die Vorlagendateien. Der zentrale Speicher liegt hier:
\\contoso.com\SYSVOL\contoso.com\Policies\PolicyDefinitions
Der zentrale Speicher liegt auf dem Domänencontroller unter SYSVOL im Pfad \\Policies\PolicyDefinitions und wird über SYSVOL repliziert und hat Vorrang vor lokal mitgebrachten Templates. Für PowerShell 7 stellt Microsoft zusätzlich PowerShellCoreExecutionPolicy.admx samt ADML-Datei bereit. Auch sie gehören in den zentralen Speicher, sonst erscheint die Richtlinie für die Kern-Shell im Editor nicht.
Ursache 4: PowerShell 7 wird separat bewertet
Windows PowerShell 5.1 und PowerShell 7 legen ihre Werte an unterschiedlichen Orten ab. 5.1 nutzt die Registry, PowerShell 7 JSON-Dateien: powershell.config.json in der Benutzervariante und im Installationsverzeichnis der Shell.
Deshalb in beiden Shells getrennt prüfen:
powershell.exe -NoProfile -Command "Get-ExecutionPolicy -List"
pwsh.exe -NoProfile -Command "Get-ExecutionPolicy -List"
Wer nur die 5.1-Konsole kontrolliert, sieht einen korrekten Wert – und wundert sich über das Skript, das aus pwsh gestartet wird.
Einordnung: keine Sicherheitsgrenze
Microsoft beschreibt die Ausführungsrichtlinie ausdrücklich als Defense in Depth, nicht als Sicherheitsgrenze. Jeder Nutzer mit Konsolenzugriff kann sie umgehen, indem er den Skriptinhalt direkt in die Befehlszeile kopiert.
Für belastbare Kontrolle kommen die PowerShell-Skriptblockprotokollierung und eine Signaturpflicht über eine interne Zertifizierungsstelle dazu. Die Richtlinie verhindert Bedienfehler – keine gezielten Angriffe.
Fazit
In der Reihenfolge Get-ExecutionPolicy -List, Policy-Registry, gpresult ist der Fall meist in zwei Minuten gelöst. Der häufigste Fehler bleibt die Benutzerkonfiguration statt der Computerkonfiguration, direkt gefolgt von der schlicht vergessenen Aktivierung.
Dauerhaft sauber gepflegt wird das in einer eigenen GPO für Shell-Richtlinien – zusammen mit der Skriptblockprotokollierung und, für gemischte Umgebungen, den PowerShell-7-Vorlagen im zentralen Speicher.
FAQ
Warum ignoriert PowerShell mein Set-ExecutionPolicy?
Weil eine Gruppenrichtlinie die Scopes MachinePolicy oder UserPolicy setzt. Diese lassen sich per Cmdlet nicht ändern; Get-ExecutionPolicy -List macht die Rangfolge sichtbar.
Welche Rangfolge gilt zwischen den Scopes?
Zuerst die Gruppenrichtlinie (MachinePolicy vor UserPolicy), danach Process, dann CurrentUser, zuletzt LocalMachine.
Unterschied zwischen RemoteSigned und AllSigned?RemoteSigned erlaubt alle lokal erstellten Skripte und verlangt für aus dem Internet übernommene eine Signatur. AllSigned verlangt für jedes Skript die Signatur eines vertrauenswürdigen Herausgebers – auch für selbst geschriebene Dateien.
Warum läuft ein RemoteSigned-Skript vom UNC-Pfad nicht?
Systeme, die UNC-Pfade nicht von Internetpfaden unterscheiden, stufen solche Skripte unter RemoteSigned mitunter als extern ein und blockieren sie. Abhilfe schafft eine Signatur – oder Unblock-File, wenn die Markierung „aus dem Internet“ versehentlich gesetzt wurde.
Wie löse ich die Richtlinie testweise, ohne sie zu löschen?
Nicht lokal überschreiben, das wirkt ohnehin nicht. Stattdessen den Sicherheitsfilter der GPO vorübergehend auf ein Test-Computerkonto einengen und die Änderung danach zurücknehmen.
No responses yet