Link to home
Start Free TrialLog in
Avatar of Can
Can

asked on

Check if a GPO is applied to all computers.

Hi All,

I want to check if a specific GPO is applied to all servers in my environment. Is there a way to automate this with powershell?

For example:

Import all servers from CSV then check if TESTGPO is applied?

Thanks in advance.
Avatar of David Johnson, CD
David Johnson, CD
Flag of Canada image

what does the gpo do? if it modifies a registry value then query the registry value.
Click on Start and type: CMD
Right click and Run as Admin.
CD \Temp (create if not there)
GPResult /H MyGPResults.HTML

Open the file in IE or Edge.

Applied and Denied GPOs will be listed.

EDIT: Note, this will tell you exactly what GPO is applying where.
Avatar of Can
Can

ASKER

Thank you for your reply's
@David: The GPO has around 500+ policy's. Contains hardening policy's
@Philip: I have around 700 servers in my environment. I cant do this server by server. That why i am looking for a powershell script to automate this. 
Something like this?
$scangpo = "this is the name of the gpo to scan for"
$ComputerList  = Get-Content ".\computerlist.txt"
foreach ($Computer in $ComputerList) {
   Get-GPResultantSetOpPolicy -ReportType XML -Computer $Computer -Path ".\$($Computer).xml"
   $temp = Get-Content ".\$($Computer).xml"
   $rsop = [xml] $temp
   # filter applied GPOs
   $appliedgpos = $rsop.Rsop.Computerresults.GPO | Where {($_.Enabled -eq $true) -and ($_.Isvalid -eq $true) -and ($_.FilterAllowed -eq $true) -and ($_.AccessDenied -eq $false) -and ($_.Link.Enabled -eq $true)}
# check if GPO name is found
  if($appliedgpos.Name -eq $scangpo) {
    Write-Host "$($Computer): GPO detected"
  } else {
    Write-Host "$($Computer): GPO not detected"
  }
}

Open in new window


Wasn't able to really test it ..
pray tell where do we get the module that contains  Get-GPResultantSetOpPolicy
Typo
get-gpresultantsetofpolicy
Avatar of Can

ASKER

Thank you Michael Pfister. This script seems usefull. yet im getting the following error on a lot of servers:
The Resultant Set of Policy (RSoP) report cannot be generated for user Domain\user on the Servername computer because there is no RSoP logging data  for that user on that
computer.

Which seems logical. Is there a way just to create rsop for computer policy's and not for user policy's? I havent logged in on maybe 100+ computers. 
I wonder, because the doc's saying it won't report user policy if you don't provide a user name with param -user

https://docs.microsoft.com/en-us/powershell/module/grouppolicy/get-gpresultantsetofpolicy?view=win10-ps

But I'v just tested and yes, it errors in case you've never logged on... very useful
Using the GPMgmt object looks better:
adapted from https://techcommunity.microsoft.com/t5/core-infrastructure-and-security/exporting-resultant-set-of-policy-rsop-data-using-powershell/ba-p/1217934
$scangpo = "this is the name of the gpo to scan for"

$gpmObject = New-Object –ComObject GPMgmt.GPM
$gpmConstants = $gpmObject.GetConstants()
$rsopObject = $gpmObject.GetRSOP($gpmConstants.RSOPModeLogging,$null,0)

$ComputerList  = Get-Content ".\computerlist.txt"
foreach ($Computer in $ComputerList) {
   $rsopObject.LoggingComputer = $Computer
   $rsopObject.LoggingFlags = 131072 # Only computer; no user
   $rsopObject.CreateQueryResults()       
   $rsopReport = $rsopObject.GenerateReportToFile($gpmConstants.ReportXML , "$($env:temp)\$($Computer).xml")
   $rsopObject.ReleaseQueryResults()

   $temp = Get-Content "$($env:temp)\$($Computer).xml"

   $rsop = [xml] $temp
   # filter applied GPOs
   $appliedgpos = $rsop.Rsop.Computerresults.GPO | Where {($_.Enabled -eq $true) -and ($_.Isvalid -eq $true) -and ($_.FilterAllowed -eq $true) -and ($_.AccessDenied -eq $false) -and ($_.Link.Enabled -eq $true)}
# check if GPO name is found
  if($appliedgpos.Name -eq $scangpo) {
    Write-Host "$($Computer): GPO detected"
  } else {
    Write-Host "$($Computer): GPO not detected"
  }
  remove-item "$($env:temp)\$($Computer).xml"
}

Open in new window

Avatar of Can

ASKER

Thanks Michael Pfister, this looks way better! Im now stuck with 2 things:

1. I have 6 levels of policy's. I can now search for just one GPO. Is it possible to search for a GPO containing a name?
Example: search for "Server hardening " instead of "server hardening policy lvl1"? I tried this:
$scangpo = "*Server hardening*"

Open in new window

but that doesnt seem to work.

2. Some servers are offline, therefor powershell gives the following RPC errors. Is there a way to filter out offline computers? 
The RPC server is unavailable. (Exception from HRESULT: 0x800706BA)
At line:11 char:4
+    $rsopObject.CreateQueryResults()
+    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : OperationStopped: (:) [], COMException
    + FullyQualifiedErrorId : System.Runtime.InteropServices.COMException
 
Value does not fall within the expected range.
At line:12 char:93
+ ... portToFile($gpmConstants.ReportXML , "$($env:temp)\$($Computer).xml")
+                                                          ~~~~~~~~~
    + CategoryInfo          : OperationStopped: (:) [], ArgumentException
    + FullyQualifiedErrorId : System.ArgumentException
 
Get-Content : Cannot find path 'C:\Users\ADMIN~1.PHA\AppData\Local\Temp\3\SERVER.xml' because it does not exist.
At line:15 char:12
+    $temp = Get-Content "$($env:temp)\$($Computer).xml"
+            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (C:\Users\ADMIN...SERVER.xml:String) [Get-Content], ItemNotFoundException
    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetContentCommand
 
SERVER: GPO not detected
remove-item : Cannot find path 'C:\Users\ADMIN~1.PHA\AppData\Local\Temp\3\SERVER.xml' because it does not exist.
At line:26 char:3
+   remove-item "$($env:temp)\$($Computer).xml"
+   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (C:\Users\ADMIN...SERVER.xml:String) [Remove-Item], ItemNotFoundException
    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.RemoveItemCommand

Open in new window



Can you run

gpresult /x test.xml /Scope Computer /S Remote-SERVER 

Open in new window


?
Avatar of Can

ASKER

Yes i can run this. But a lot of servers (around 30) are shutdown. So the RPC errors are legit. I would like to filter out offline computers. 
Replace
if($appliedgpos.Name -eq $scangpo)

with
$appliedgpos.Name -like $scangpo)

and you can use wildcards in $scangpo
ASKER CERTIFIED SOLUTION
Avatar of Michael Pfister
Michael Pfister
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Can

ASKER

Thank you very much Michael!
Glad it works