#Requires -module GroupPolicy <# Get a report of deployment status of a GPO in all domains within forest Alan Kaplan 10/1/20 #> [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string] $GPOName ) WorkFlow Invoke-wfADQuery { param( [string[]]$Domains, [string]$GPOName ) ForEach -parallel ($Domain in $Domains) { InLineScript { $delim = '; ' Write-verbose $using:domain Try { $GPOReport = Get-GPOReport -Domain $using:Domain -name $Using:GPOName -reporttype XML -ErrorAction stop Write-verbose "Found $Using:GPOName in $using:domain" $bFound = $true #Converts it to an XML variable for manipulation $GPOXML = [xml]$GPOReport #Get info from XML #General Information [DateTime]$Modified = $GPOXML.GPO.ModifiedTime #WMI Filter if ($GPOXML.GPO.FilterName) { $WMIFilter = $GPOXML.GPO.FilterName } else { $WMIFilter = "" } #Links if ($GPOXML.GPO.LinksTo) { $Links = ($GPOXML.GPO.LinksTo | ForEach-Object { $l = $_.SOMPath $e = $_.Enabled "$l `($e`)" }) -join $delim } else { $Links = "" } #Security Info $Owner = $GPOXML.GPO.SecurityDescriptor.Owner.Name.'#text' $SecurityInfo = ($GPOXML.GPO.SecurityDescriptor.Permissions.TrusteePermissions | Where-Object { $_.Standard.GPOGroupedAccessEnum -match 'Apply Group Policy' } | ForEach-Object { $tn = $_.Trustee.Name.'#text' $tp = $_.Type.PermissionType "$tn `($tp`)" }) -join $delim } Catch { Write-verbose "$Using:GPOName not found in $using:domain" $bFound = $false } [PsCustomObject]@{ Domain = $using:Domain GPO_Name = $Using:GPOName Deployed = $bFound DeployedBy = $Owner Last_Modified = $Modified WMI_Filter = $WMIFilter Links_Enabled = $Links SecFilter = $SecurityInfo } }#End Inline } #End Foreach Parallel }#End WorkFlow ### Start Script #logfile on desktop with date $logfile = [environment]::GetFolderPath('Desktop') + "\$GPOName`_Status_" + $(Get-Date).ToString("yyyyMMdd_HHmm") + '.csv' #list of domains for script to query $Forest = ([System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest()) $Domains = ($Forest.Domains).Name | Sort-Object -CaseSensitive Write-Host "Collecting GPO report on all domains, please wait ..." Invoke-wfADQuery -domains $Domains -GPOName $GPOName | Sort-Object Domain | Select-Object * -ExcludeProperty PS* | export-csv $logfile -NoTypeInformation write-host "Done, see $logfile"