GPOs analysieren mit PowerShell: Nicht verlinkte und leere Objekte, WMI-Filter

    GruppenrichtlinienEine Reihe von Cmdlets, die im Modul GroupPolicy zusammengefasst sind, helfen dabei, den Überblick über vorhandene GPOs zu behalten und sie zu administrieren. Mit ihrer Hilfe kann man etwa jene anzeigen lassen, die mit keiner Domäne oder OU verlinkt sind, die keine Einstellungen enthalten oder die deaktiviert wurden.

    Wenn man die Liste aller GPOs in einer Domäne abrufen möchte, dann dient das Cmdlet Get-GPO diesem Zweck. Ruft man es mit dem Schalter -All auf, dann erhält man sämtliche Gruppenricht­linienobjekte jener Domäne, in welcher der betreffende User angemeldet ist. Alternativ kann man über den Parameter -Domain eine bestimmte Domäne festlegen. Darüber hinaus lassen sich mit Hilfe von -Name und -GIUD einzelne GPOs ausgeben.

    Gruppenrichtlinienobjekte auslesen mit Get-GPO

    Die in der Ergebnisliste enthaltenen Objekte lassen sich wie gewohnt anhand ihrer Eigenschaften analysieren und filtern. So könnte man mit dem Aufruf

    Get-GPO -All | Where WmiFilter -ne $null

    alle GPOs anzeigen, die mit einem WMI-Filter verknüpft sind. Ähnliches ließe sich mit dem Domänennamen (DomainName) oder dem GPO-Status vollführen. Damit sind jedoch die offensichtlichen Möglichkeiten zur Nutzung der GPO-Eigenschaften ausgeschöpft.

    Leere GPOs ermitteln

    Wie sich später anhand von XML-Reports herausstellen wird, lassen die Eigenschaften ComputerVersion und UserVersion Rückschlüsse darauf zu, ob ein GPO überhaupt Einstellungen enthält. Haben nämlich beide den Wert 0, dann ist es ein sicheres Indiz dafür, dass leere GPOs vorliegen. Diese kann man sich so anzeigen lassen:

    $AllGPOs = Get-GPO -all
    foreach($GP in $AllGPOs){if($GP.User.DSVersion -eq 0 -and $GP.Computer.DSVersion -eq 0)
    {Write-Host "Leere GPOs:" $GP.DisplayName}}

    Der erste Befehl liest alle GPOs in die Variable $AllGPOs ein, der zweite iteriert in einer foreach-Schleife über die einzelnen GPO-Objekte und prüft, ob die Eigenschaft DSVersion sowohl unter Computer als auch unter User gleich null ist.

    Reports analysieren

    Die relativ wenigen Eigenschaften der Objekte, die Get-GPO zurückgibt, erlauben kaum zusätzliche Abfragen. Diesen Mangel kann man einigermaßen ausgleichen, indem man Reports generiert. Sie enthalten praktisch alle Informationen zu den GPOs und lassen sich dank der XML-Funktionen von PowerShell gut auswerten.

    Get-GPOReport erzeugt wohlgeformte XML-Dokumente nur für einzelne GPOs.

    Hinderlich dabei ist jedoch die Eigenheit von Get-GPOReport, dass es wohlgeformte XML-Dokumente nur für einzelne Berichte erzeugt. Ruft man es dagegen in der Form

    Get-GPOReport -All -ReportType XML

    auf, um Reports zu allen GPOs zu erzeugen, dann fügt es einfach alle Einzelberichte in einer Ausgabe zusammen. Dabei bleibt jede einzelne XML-Deklaration erhalten, so dass sich das Ergebnis nicht mit XML-Mitteln, sondern nur mit Methoden zur Textauswertung (etwa RegEx) untersuchen lässt. Daher iterieren die folgenden Beispiele in einer Schleife über die Einzelreports.

    Verwaiste GPOs finden

    Eine wichtige Information, die man bei der Analyse von GPOs wahrscheinlich erhalten will, sind ihre Verknüpfungen zu Domänen oder OUs. Bei dieser Gelegenheit lässt sich gleich herausfinden, welche GPOs gar nicht zugeordnet und daher nutzlos sind. Diese Daten kann man so ermitteln:

    Get-GPO -All | %{[XML]$GPOs = Get-GPOReport -Name $_.DisplayName -ReportType XML; $GPOs.GPO.Name + ";" + $GPOs.GPO.LinksTo.SOMName}

    Der erste Befehl liest alle GPOs aus und übergibt sie über eine Pipe an eine foreach-Schleife (% als Alias für Foreach-Object). Diese erzeugt in jedem Durchlauf einen Bericht für ein GPO im XML-Format und speichert diesen in der Variable $GPOs. Letztere wird über den Cast [XML] in ein XML-Objekt konvertiert. Anschließend wird nur noch der Inhalt der Elemente /GPO/Name und /GPO/LinksTo/SOMName ausgegeben.

    Das Element LinksTo hat neben SOMName noch weitere Kindknoten, darunter Enabled. Sein Wert sagt aus, ob die Verknüpfung aktiviert oder deaktiviert wurde. Alle Werte der Knoten unter Enabled lassen sich auf diese Weise ermitteln:

    Get-GPO -All | %{[XML]$GPOs = Get-GPOReport -Name $_.DisplayName -ReportType XML; $GPOs.GPO.Name, $GPOs.GPO.LinksTo | fl}

    Die Ausgabe erfolgt im übersichtlicheren Listenformat, wobei den Daten aus dem Report jeweils der GPO-Name vorangestellt wird.

    2 Kommentare

    Bild von 12gang
    12gang sagt:
    17. März 2014 - 11:01

    Get-GPO -All | Where WmiFilter -ne $null liefert mir eine Fehlermeldung, mit get-gpo -all | Where-Object {$_.wmifilter -ne $null} geht es.

    Bild von Wolfgang Sommergut
    17. März 2014 - 11:08

    Danke für die Anmerkung! Mein Beispiel verwendet die in PowerShell 3.0 eingeführte Simplified Syntax. Wenn man unter Windows 7 noch PS2 nutzt, dann muss man die Variante mit den geschweiften Klammern wählen.