none
Parse GPRESULT XML for applied settings

    Question

  • I am attempting to parse the output from a gpresult XML file, in order to retrieve the values for specific applied settings. I have generated the XML and imported it as a variable:

    gpresult.exe /x C:\Temp\results.xml /f
    
    $results = [xml] (Get-Content C:\Temp\results.xml)


    I need to capture the password policy settings, which are contained in the Default Domain Policy. Here's an excerpt of the XML that shows these settings:

        <ExtensionData>
          <Extension xmlns:q2="http://www.microsoft.com/GroupPolicy/Settings/Security" xsi:type="q2:SecuritySettings" xmlns="http://www.microsoft.com/GroupPolicy/Settings">
            <q2:Account>
              <GPO xmlns="http://www.microsoft.com/GroupPolicy/Settings/Base">
                <Identifier xmlns="http://www.microsoft.com/GroupPolicy/Types">{31B2F340-016D-11D2-945F-00C04FB984F9}</Identifier>
                <Domain xmlns="http://www.microsoft.com/GroupPolicy/Types">tailspintoys.com</Domain>
              </GPO>
              <Precedence xmlns="http://www.microsoft.com/GroupPolicy/Settings/Base">1</Precedence>
              <q2:Name>MaximumPasswordAge</q2:Name>
              <q2:SettingNumber>42</q2:SettingNumber>
              <q2:Type>Password</q2:Type>
            </q2:Account>
            <q2:Account>
              <GPO xmlns="http://www.microsoft.com/GroupPolicy/Settings/Base">
                <Identifier xmlns="http://www.microsoft.com/GroupPolicy/Types">{31B2F340-016D-11D2-945F-00C04FB984F9}</Identifier>
                <Domain xmlns="http://www.microsoft.com/GroupPolicy/Types">tailspintoys.com</Domain>
              </GPO>
              <Precedence xmlns="http://www.microsoft.com/GroupPolicy/Settings/Base">1</Precedence>
              <q2:Name>MinimumPasswordAge</q2:Name>
              <q2:SettingNumber>1</q2:SettingNumber>
              <q2:Type>Password</q2:Type>
            </q2:Account>
            <q2:Account>
              <GPO xmlns="http://www.microsoft.com/GroupPolicy/Settings/Base">
                <Identifier xmlns="http://www.microsoft.com/GroupPolicy/Types">{31B2F340-016D-11D2-945F-00C04FB984F9}</Identifier>
                <Domain xmlns="http://www.microsoft.com/GroupPolicy/Types">tailspintoys.com</Domain>
              </GPO>
              <Precedence xmlns="http://www.microsoft.com/GroupPolicy/Settings/Base">1</Precedence>
              <q2:Name>LockoutBadCount</q2:Name>
              <q2:SettingNumber>0</q2:SettingNumber>
              <q2:Type>Account Lockout</q2:Type>
            </q2:Account>
            <q2:Account>
              <GPO xmlns="http://www.microsoft.com/GroupPolicy/Settings/Base">
                <Identifier xmlns="http://www.microsoft.com/GroupPolicy/Types">{31B2F340-016D-11D2-945F-00C04FB984F9}</Identifier>
                <Domain xmlns="http://www.microsoft.com/GroupPolicy/Types">tailspintoys.com</Domain>
              </GPO>
              <Precedence xmlns="http://www.microsoft.com/GroupPolicy/Settings/Base">1</Precedence>
              <q2:Name>PasswordHistorySize</q2:Name>
              <q2:SettingNumber>24</q2:SettingNumber>
              <q2:Type>Password</q2:Type>
            </q2:Account>
            <q2:Account>
              <GPO xmlns="http://www.microsoft.com/GroupPolicy/Settings/Base">
                <Identifier xmlns="http://www.microsoft.com/GroupPolicy/Types">{31B2F340-016D-11D2-945F-00C04FB984F9}</Identifier>
                <Domain xmlns="http://www.microsoft.com/GroupPolicy/Types">tailspintoys.com</Domain>
              </GPO>
              <Precedence xmlns="http://www.microsoft.com/GroupPolicy/Settings/Base">1</Precedence>
              <q2:Name>MinimumPasswordLength</q2:Name>
              <q2:SettingNumber>7</q2:SettingNumber>
              <q2:Type>Password</q2:Type>
            </q2:Account>
            <q2:Account>
              <GPO xmlns="http://www.microsoft.com/GroupPolicy/Settings/Base">
                <Identifier xmlns="http://www.microsoft.com/GroupPolicy/Types">{31B2F340-016D-11D2-945F-00C04FB984F9}</Identifier>
                <Domain xmlns="http://www.microsoft.com/GroupPolicy/Types">tailspintoys.com</Domain>
              </GPO>
              <Precedence xmlns="http://www.microsoft.com/GroupPolicy/Settings/Base">1</Precedence>
              <q2:Name>PasswordComplexity</q2:Name>
              <q2:SettingBoolean>true</q2:SettingBoolean>
              <q2:Type>Password</q2:Type>
            </q2:Account>
            <q2:Account>
              <GPO xmlns="http://www.microsoft.com/GroupPolicy/Settings/Base">
                <Identifier xmlns="http://www.microsoft.com/GroupPolicy/Types">{31B2F340-016D-11D2-945F-00C04FB984F9}</Identifier>
                <Domain xmlns="http://www.microsoft.com/GroupPolicy/Types">tailspintoys.com</Domain>
              </GPO>
              <Precedence xmlns="http://www.microsoft.com/GroupPolicy/Settings/Base">1</Precedence>
              <q2:Name>ClearTextPassword</q2:Name>
              <q2:SettingBoolean>false</q2:SettingBoolean>
              <q2:Type>Password</q2:Type> 

    I've been exploring the dot-notation, and can see the Default Domain Policy. But how do I drill down and capture the values I need?

    $results.DocumentElement.ComputerResults.GPO | Where-Object {$_.Name -eq "Default Domain Policy"}

    Name             : Default Domain Policy
    Path             : Path
    VersionDirectory : 9
    VersionSysvol    : 9
    Enabled          : true
    IsValid          : true
    FilterAllowed    : true
    AccessDenied     : false
    Link             : Link
    SecurityFilter   : NT AUTHORITY\Authenticated Users
    ExtensionName    : {{B1BE8D72-6EAC-11D2-A4EA-00C04F79F83A}, Security, Registry}


    Saturday, July 23, 2016 4:51 PM

Answers

  • @JRV thank you for the deeper analysis into this request.

    I ended up wrenching on the dot-notation a bit more and was eventually able to drill down to the settings I needed after expanding a few properties. This is the code I'm using currently, but please feel free to critique if you think it could be done better.

    # Retrieve the current applied policies (must be run from an elevated PS window in order to retrieve computer results) gpresult.exe /x C:\Temp\results.xml /f

    # Import the XML file $results = [xml] (Get-Content C:\temp\results_before.xml) # Output the results $results.DocumentElement.ComputerResults.ExtensionData | select -ExpandProperty extension | select Account | select -ExpandProperty * | select Name, SettingNumber, SettingBoolean, Type | FT -AutoSize



    Sunday, July 24, 2016 4:40 AM

All replies

  • Yu have to know the structure.  Just keep dotting your way down to settings.


    \_(ツ)_/

    Saturday, July 23, 2016 5:22 PM
    Moderator
  • Using XPath or Select-Xml you have to query down at least 4 namespaces and filter on the GUID for the GPO.

    To get the GUID we would do the following:

    [xml]$results = cat results.xml
    [System.Xml.XmlNamespaceManager]$nsmgr = $results.NameTable;
    
    # set up namespaces for queries
    $nsmgr.AddNamespace('df',$results.Rsop.xmlns);
    $nsmgr.AddNamespace('base','http://www.microsoft.com/GroupPolicy/Settings/Base')
    $nsmgr.AddNamespace('ex', 'http://www.microsoft.com/GroupPolicy/Settings')
    $nsmgr.AddNamespace('types', 'http://www.microsoft.com/GroupPolicy/Types')
    
    # get the GUID of a GPO
    $node=$results.selectSingleNode('//df:Rsop/df:ComputerResults/df:GPO/df:Name[text()="Default Domain Policy"]', $nsmgr)
    $node | select *
    $xpath='//df:Rsop/df:ComputerResults/df:GPO/df:Name[text()="Default Domain Policy"]/../df:Path/types:Identifier'
    $guid=$results.selectSingleNode($xpath, $nsmgr).'#text'
    
    # get extensions
    $extensions = $results.selectNodes('//df:Rsop/df:ComputerResults/df:ExtensionData/ex:Extension', $nsmgr)
    
    # next we have to update our extensions query to extract only yhe entries associated with our target policy
    Now just add the search by GUID and all of the GPO associated ExtensionData will be visible.


    \_(ツ)_/


    Saturday, July 23, 2016 6:43 PM
    Moderator
  • @JRV thank you for the deeper analysis into this request.

    I ended up wrenching on the dot-notation a bit more and was eventually able to drill down to the settings I needed after expanding a few properties. This is the code I'm using currently, but please feel free to critique if you think it could be done better.

    # Retrieve the current applied policies (must be run from an elevated PS window in order to retrieve computer results) gpresult.exe /x C:\Temp\results.xml /f

    # Import the XML file $results = [xml] (Get-Content C:\temp\results_before.xml) # Output the results $results.DocumentElement.ComputerResults.ExtensionData | select -ExpandProperty extension | select Account | select -ExpandProperty * | select Name, SettingNumber, SettingBoolean, Type | FT -AutoSize



    Sunday, July 24, 2016 4:40 AM
  • The stated solution does NOT find by GPO.  It finds all settings for one type of rule.   It includes settings from ALL GPOs and not just the requested GPO.  Filtering still needs to be done via the Policy GUID.


    \_(ツ)_/

    Friday, July 29, 2016 10:20 AM
    Moderator
  • "Filtering still needs to be done via the Policy GUID."

    This is not accurate. Per my example, I am capturing policies by running gpresult on the local system. This outputs all applied policies for the system. In which case, filtering isn't a requirement.

    Example: I have 2 GPOs linked to my OU that both contain password policy settings. The gpresult output is only going to contain the settings from the policy that took precedence.

    Friday, July 29, 2016 3:13 PM
  • Sorry that is how your initial question was worded.  If you only want password policy settings then you are set.


    \_(ツ)_/

    Friday, July 29, 2016 4:07 PM
    Moderator
  • Here is my go at it:

    [XML]$GPResultXML = Get-Content -path 'C:\report.xml'

    ($GPResultXML.rsop.computerresults.extensiondata.extension).account | ft Name,SettingNumber,SettingBoolean

    This gave me things like the password length and age

    Thursday, July 12, 2018 7:30 PM