xmlpowershellgpo

Use PowerShell to extract linking of a specific GPO from XML


I am attempting to use PowerShell to extract link information(SOMPath) from a GPO using the Get-GPOreport command and report type XML without exporting the GPO XML to a file first. I am struggling to get it to give me the results I need.

here is the code I am working with.

 $reports2 = Get-GPOReport -name "GPO-Name" -ReportType XML
 select-xml -content $reports2 -XPath "//SOMPath" | foreach {$_.node.InnerXML}

it is not returning any data nor is it returning any errors

the variable $reports2 does return and properly formatted XML and it does have the SOMPath data in it that I need to extract but I cant seam to get it to give me the SOMPath data. example of the SOMPath data I am looking to extract: Domain/OU/OU/OU

the ultimate goal is I will be running this against a list of GPOs and need it to list something like the following:

 GPO1:
 SOMPath1
 SOMPath2
 SOMPath3

 GPO2:
 SOMPath1
 SOMPath2

per the guidance from Microsoft website, it should be relatively simple (as seen in the MS example below)

(Begin MS XML example)

 $Xml = @"
 <?xml version="1.0" encoding="utf-8"?>
 <Book>
   <projects>
     <project name="Book1" date="2009-01-20">
       <editions>
         <edition language="English">En.Book1.com</edition>
         <edition language="German">Ge.Book1.Com</edition>
         <edition language="French">Fr.Book1.com</edition>
         <edition language="Polish">Pl.Book1.com</edition>
       </editions>
     </project>
   </projects>
 </Book>
 "@

(Begin MS Code example)

 Select-Xml -Content $Xml -XPath "//edition" | foreach {$_.node.InnerXML}

(begin MS results example)

 En.Book1.com
 Ge.Book1.Com
 Fr.Book1.com
 Pl.Book1.com

thank you for your time and help


Solution

  • I was able to do this with the following code:

    $allGpos = Get-GPO -All
    foreach ($gpo in $allGpos) { 
       [xml]$report = Get-GPOReport -Guid $GPO.ID -ReportType Xml
       $report.GPO.Name
       $report.GPO.LinksTo.SOMPath
    }
    

    It outputs a string object. Don't know if that's what you're looking for or not. Hope it helps. I've never been too good with that Select-Xml cmdlet, lol.

    Edit: I was able to come up with something like putting it into a PS Custom Object so that it has properties you can reference later. Or when you output it, it looks like a fairly nice table

    using namespace System.Collections.Generic
    $GPOLinkReport = [List[PSObject]]::new()
    $allGposInDomain = Get-GPO -All
    foreach ($gpo in $allGposInDomain) { 
       [xml]$report = Get-GPOReport -Guid $gpo.Id -ReportType Xml
       $GPOLinks = [String]::Join(",",$report.GPO.LinksTo.SOMPath)
       $GPOLinkReportObj = [PSCustomObject]@{
          Name = $report.GPO.Name
          Links = $GPOLinks
       }
       $GPOLinkReport.Add($GPOLinkReportObj)
    }
    
    $GPOLinkReport
    

    Edit2: Here's yet another block that puts one link per name per row

    $GPOLinkReport = [List[PSObject]]::new()
    $allGposInDomain = Get-GPO -All
    foreach ($gpo in $allGposInDomain) { 
        [xml]$report = Get-GPOReport -Guid $gpo.Id -ReportType Xml
        $GPOLinks = $report.GPO.LinksTo.SOMPath
        foreach ($link in $GPOLinks) {
            $GPOLinkReportObj = [PSCustomObject]@{
                Name = $report.GPO.Name
                Links = $link
            }
            $GPOLinkReport.Add($GPOLinkReportObj)
        }
    }
    $GPOLinkReport #| Export-csv c:\temp\GPOLinks.csv -NoTypeInformation
    

    Choose your poison, lol.