<< A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

–A–

–B–

–C–

–D–

–E–

ExtensionData in GPO xml file

While parsing a GPO XML file, you‘ll eventually run into something like this

<Extension xmlns:q1="http://www.microsoft.com/GroupPolicy/Settings/Security" xsi:type="q1:SecuritySettings">

followed by a whole pile more of "q1:" like this:

<q1:SecurityOptions>

how to parse?

[xml]$xml = Get-GPOReport -Name "Srvr-SecurityBaseLine" -ReportType xml
$namespaceManager = New-Object System.Xml.XmlNamespaceManager($xml.NameTable)
$namespaceManager.AddNamespace("q1", "http://www.microsoft.com/GroupPolicy/Settings/Security")
$xpath = "//q1:SecurityOptions"
$securityOptions = $xml.SelectNodes($xpath, $namespaceManager)
foreach ($securityOption in $securityOptions) {
    Write-Host "Found '$($securityOption.Display.Name)'" -ForegroundColor Blue
}

–F–

–G–

Get-GPO

Get-GPO -Guid 18f45a2d-317b-4669-84f7-02afacd3fe40 | fl
Get-GPO PCs-2023 | fl

There are no more properties besides what this command gets. That is, there is no -Properties available.

gpresult /r – see also rsop

command results in text output, supposedly more complete than rsop. But rsop easier to navigate GUI pop-up. Not only that, but it indicates which policy affects each setting.

If you omit /scope parameter for gpresult, it supposedly will display RSoP data for both the user and the computer. But in practice, I’ve never seen it return anything for the computer. If I specify /scope computer, usually returns ERROR: Access Denied.

group policy editor (local) - see local group policy editor

group policy hierarchy

Below may only apply to OU linis. I got it from here

$GPOPrecedence = (Get-ADOrganizationalUnit -filter * | Get-GPInheritance).GpoLinks  | Select -Property Target,DisplayName,Enabled,Enforced,Order

group policy management

gpmc.msc

sometimes when I run this, I get:

The permissions for this GPO in the SYSVOL folder are inconsistent with those in Active Directory. It is recommended that these permissions be consistent. To change the SYSVOL permissions to those in Active Directory, click OK.

I pretty much always click OK.

see also local group policy editor

group policy, show all

$AllGroupPolicies = Get-GPO -All
$AllGroupPolicies.Count
$AllGroupPolicies | ogv

group policy, XML

You can save a specific Group Policy as an XML file. Let’s put it in My Documents directory

$path = [environment]::getfolderpath("mydocuments")
Get-GPOReport -Name "Srvr-2016" -ReportType xml -Path "$path\Srvr-2016.xml"

and then read it back into an XML variable

[xml]$xml1 = Get-Content -Path "$($path)\Srvr-2016.xml"

But faster to just read directly into an XML variable

[xml]$xml = Get-GPOReport -Name "Srvr-2016" -ReportType xml

Here's an example that reads in registry stuff & put into CSV

$result = @()
foreach ($item in $xml.DocumentElement.Computer.ExtensionData.extension.RegistrySettings.ChildNodes) {
    $result += New-Object -TypeName PSObject -Property @{
        "name" = $item.Name
        #"clsid" = $item.clsid
        #"status" = $item.status
        "image" = $item.image
        #"changed" = $item.changed
        #"uid" = $item.uid
        "GPOSettingOrder" = $item.GPOSettingOrder
        "propertyName" = $item.properties.name
        "propertyAction" = $item.properties.action
        "propertyDisplayDecimal" = $item.properties.displayDecimal
        "propertyDefault" = $item.properties.default
        #"propertyHive" = $item.properties.hive
        "propertyKey" = $item.properties.key
        "propertyType" = $item.properties.type
        "propertyValue" = $item.properties.value
        #"propertyValues" = $item.properties.Values
        #"Filters" =$item.Filters
    }
}
$result = $result | select name, image, GPOSettingOrder, propertyName, propertyAction, propertyDisplayDecimal, propertyDefault, propertyKey, propertyType, propertyValue
$result | ogv
$result | Export-Csv -Path "$([environment]::getfolderpath("mydocuments"))\Registry1$((Get-Date).ToString('MM-dd-yyyy_hh-mm-ss')).csv" -Encoding UTF8 -NoTypeInformation

This example gets adds a namespace to be able to process “q1” XML elements to get security settings

$namespaceManager = New-Object System.Xml.XmlNamespaceManager($xml.NameTable)
$namespaceManager.AddNamespace("q1", "http://www.microsoft.com/GroupPolicy/Settings/Security")
$xpath = "//q1:SecurityOptions"
$securityOptions = $xml.SelectNodes($xpath, $namespaceManager)
foreach ($securityOption in $securityOptions) {
    Write-Host "Found '$($securityOption.Display.Name)'" -ForegroundColor Blue
}

Group Policies, which policies affect the server you are currently logged onto? – see rsop, gpresult

–H–

how to all the various Domain Group Policies combine to affect a server? – see rsop, gpresult

–I–

–J–

–K–

–L–

LinksTo, find for all GPOs

$allGPOs = Get-GPO -All
$GPOLinks = @()
$i=0 ; $gpocount = $allGPOs.Count
foreach ($gpo in $allGPOs) {
    $i++; $percentGPOTxt = ($i/$gpocount).ToString("P")
    $gpoName = $gpo.DisplayName
    Write-Host "$i of $($gpocount) ($percentGPOTxt): $gponame" -ForegroundColor Green
    [xml]$xml = Get-GPOReport -Name $gpoName -ReportType xml
    $LinksTo = $null
    $LinksTo =  $xml.gpo.LinksTo
    $j=0; $linkcount = $LinksTo.Count
    foreach ($node in $LinksTo) {
        $j++; $percentLinkTxtj = ($j/$linkcount).ToString("P")
        if ($null -ne $node.SOMName) { # there always seem to be some null records that aren't visible in XML file
            $SOMPath = $node.SOMPath
            $domain, $SOMPathArrayElements = $SOMPath -split "/" # convenient one-liner to get everything except $domain; we dont really care about $domain
            $OU = $SOMPathArrayElements -join "\"
            $NoOverride = $node.NoOverride
            Write-Host "  $j of $($linkcount) ($percentLinkTxtj): $SOMName $SOMPath $NoOverride" -ForegroundColor Cyan
            $GPOLinks += New-Object -TypeName PSObject -Property @{
                gpoCount = $i; gponame = $gpoName; created = $gpo.CreationTime; modified = $gpo.ModificationTime; owner = $gpo.Owner; id = $gpo.Id; GPOstatus=$gpo.GPOStatus; description = $gpo.Description
                LinksCount = $j
                SOMName = $node.SOMName
                SOMPath = $node.SOMPath
                OU = $OU
                NoOverride = $node.NoOverride
            }
        }
        else {
            $GPOLinks += New-Object -TypeName PSObject -Property @{
                gpoCount = $i; gponame = $gpoName; created = $gpo.CreationTime; modified = $gpo.ModificationTime; owner = $gpo.Owner; id = $gpo.Id; GPOstatus=$gpo.GPOStatus; description = $gpo.Description
                LinksCount = 0; SOMName = $null; SOMPath = $null; NoOverride = $null
            }
        }
    }
}
$GPOLinks = $GPOLinks | sort gponame, LinksCount | select gponame, GPOstatus, created, modified, owner, id, LinksCount, SOMName, SOMPath, OU, NoOverride, description
$GPOLinks | ogv

now that we have the $GPOLinks variable, let's get some useful info out of it

no links or GPOStatus -eq “AllSettingsDisabled”

$GPOLinks | ?{$_.LinksCount -eq 0 -or $_.GPOstatus -eq "AllSettingsDisabled"} | sort gponame, LinksCount | select gponame, GPOstatus, created, modified, owner, id, LinksCount, SOMName, OU | ogv

the opposite: have at least 1 link and GPOStatus -ne “AllSettingsDisabled”; only links to OUs, not the whole domain

$GPOLinks | ? {$_.LinksCount -ne 0 -and $_.GPOstatus -ne "AllSettingsDisabled" -and $_.OU -ne ""} | sort OU, gponame, LinksCount | select gponame, GPOstatus, created, modified, owner, id, LinksCount, SOMName, OU, SOMpath | ogv

Local Computer policy, which group policies affect? – see rsop, gpresult

local group policy editor

open

gpedit.msc

after making any changes

gpupdate /force

see also group policy management editor

–M–

–N–

namespace

Read a group policy object into an XML variable

[xml]$xml = Get-GPOReport -Name "Srvr-2016" -ReportType xml

add a namespace to be able to process “q1” XML elements to get security settings

$namespaceManager = New-Object System.Xml.XmlNamespaceManager($xml.NameTable)
$namespaceManager.AddNamespace("q1", "http://www.microsoft.com/GroupPolicy/Settings/Security")
$xpath = "//q1:SecurityOptions"
$securityOptions = $xml.SelectNodes($xpath, $namespaceManager)

–O–

OUs, which GPOs link to – see LinksTo, find for all GPOs

–P–

–Q–

“q1:” tags in GPO XML – see ExtensionData in GPO xml file

–R–

registry settings, find for all GPOs

# Get all the GPOs in the domain
$allGPOs = Get-GPO -All
 
# Loop through each GPO
$GPORegistrySettings = @()
$i=0; $gpocount = $allGPOs.Count
foreach ($GPO in $allGPOs) {
    $i++; $percentGPOTxt = ($i/$gpocount).ToString("P")
    $gpoName = $gpo.DisplayName
    Write-Host "$i of $($gpocount) ($percentGPOTxt): $gponame" -ForegroundColor Green
    [xml]$xml = Get-GPOReport -Name $gpoName -ReportType xml
 
    $registrySettings = Select-Xml - Xml$xml -XPath "//q2:RegistrySettings/q2:Registry" -Namespace @{"q2"="http://www.microsoft.com/GroupPolicy/Settings/Windows/Registry"}
    $GPOSettingOrder = Select-Xml -Xml $xml -XPath "//q2:RegistrySettings/q2:Registry/q2:GPOSettingOrder" -Namespace @{"q2"="http://www.microsoft.com/GroupPolicy/Settings/Windows/Registry"}
    $properties = Select-Xml -Xml $xml -XPath "//q2:RegistrySettings/q2:Registry/q2:Properties" -Namespace @{"q2"="http://www.microsoft.com/GroupPolicy/Settings/Windows/Registry"}
   
    for ($j = 0; $j -lt $registrySettings.Count; $j++) {
        $percentRegTxt = ($j/$registrySettings.Count).ToString("P")
        Write-Host "  $j of $($registrySettings.Count) ($percentRegTxt): $($registrySettings[$j].Node.name)" -ForegroundColor Blue
        $GPORegistrySettings += [pscustomobject]@{
            gponame = $gpoName
            Name = $registrySettings[$j].Node.name
            Image = $registrySettings[$j].Node.image
            Changed = $registrySettings[$j].Node.changed
            GPOSettingOrder = $GPOSettingOrder[$j].Node."#text"
            Action = $properties[$j].Node.action
            DisplayDecimal = $properties[$j].Node.displayDecimal
            Default = $properties[$j].Node.default
            Hive = $properties[$j].Node.hive
            Key = $properties[$j].Node.key
            Type = $properties[$j].Node.type
            Value = $properties[$j].Node.value
        }
    }
$GPORegistrySettings | sort hive, key, Name, gponame | select Hive, Key, Name, gponame, Type, Value, Action, Default, DisplayDecimal | ogv

report, generate for a single GP

HTML

Get-GPOReport -Name "MonroeDoctrine" -ReportType HTML -Path "$([environment]::getfolderpath("mydocuments"))\MonroeDoctrine.html"

XML

Get-GPOReport -Name "MonroeDoctrine" -ReportType XML -Path "$([environment]::getfolderpath("mydocuments"))\MonroeDoctrine.xml"

rsop – command to pop up a window displaying Result of Policy – see also gpresult /r

Running this command pop-s up GUI window that’s easier to navigate than gpresult’s text output. Not only that, but it indicates which policy affects each setting.

gpresult supposedly returns more complete information than rsop. If you omit /scope parameter for gpresult, it supposedly will display RSoP data for both the user and the computer. But in practice, I’ve never seen it return anything for the computer. If I specify /scope computer, usually returns ERROR: Access Denied.

–S–

scope of management

list scopes of management (OUs) for all GPOs

$allGPOs = Get-GPO -All
$result = @()
$i=0; $gpocount = $allGPOs.Count
foreach ($gpo in $allGPOs) {
    $i++; $percentGPOTxt = ($i/$gpocount).ToString("P")
    $gpoName = $gpo.DisplayName
    Write-Host "$i of $($gpocount) ($percentGPOTxt): $gponame" -ForegroundColor Green
    [xml]$xml = Get-GPOReport -Name $gpoName -ReportType xml
    $LinksTo = $null
    $LinksTo =  $xml.gpo.LinksTo
    $j=0; $linkcount = $LinksTo.Count
    foreach ($node in $LinksTo) {
        $j++; $percentLinkTxt = ($j/$linkcount).ToString("P")
        if ($null -ne $node.SOMName ) { # there always seem to be some null records that aren't visible in XML file
            $SOMPath = $node.SOMPath
            $NoOverride = $node.NoOverride
            Write-Host "  $j of $($linkcount) ($percentLinkTxt): $SOMName $SOMPath $NoOverride" -ForegroundColor Cyan
            $result += New-Object -TypeName PSObject -Property @{
                "gpoCount" = $i
                "gponame" = $gpoName
                "LinksCount" = $j
                "SOMName" = $node.SOMName
                "SOMPath" = $node.SOMPath
                "NoOverride" = $node.NoOverride
            }
        }
    }
    #if ($i -gt 3) {break}
}
$result = $result | select gpoCount, LinksCount, gponame, SOMName, SOMPath, NoOverride
$result | ogv
$result | Export-Csv -Path "$([environment]::getfolderpath("mydocuments"))\GPOAllLinksTo$((Get-Date).ToString('MM-dd-yyyy_hh-mm-ss')).csv" -Encoding UTF8 -NoTypeInformation

server, which Domain Group Policies affect? – see rsop, gpresult

SOM - scope of management - see scope of management

Servers

–T–

–U–

–V–

–W–

which Domain Group Policies affect a server? – see rsop, gpresult

WMI Filters, list

$WmiFilters = Get-ADObject -LDAPFilter "(objectClass=msWMI-Som)" -Properties *

$WmiFilters | select @{n="name";e={$_."msWMI-Parm1"}}, @{n="query";e={($_."msWMI-Parm2" -split(";"))[-2]}} | ft -a

The last line above “beautifies” the two parameters so we humans can understand better. If instead we run the simpler “raw” query below, we’d see that the last property buries the query in the second-to-last member of an array separated by semicolons unless we isolate it like the line above above.

$WmiFilters | select msWMI-Parm1, msWMI-Parm2 | ft -a

–X–

XML, read Group Policy XML file - see group policy, XML

–Y–

–Z–