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.
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.
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.
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.
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.
@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?
Wasn't able to really test it ..
$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"
}
}
Wasn't able to really test it ..
pray tell where do we get the module that contains Get-GPResultantSetOpPolicy
Typo
get-gpresultantsetofpolicy
get-gpresultantsetofpolicy
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.
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/pow ershell/mo dule/group policy/get -gpresulta ntsetofpol icy?view=w in10-ps
But I'v just tested and yes, it errors in case you've never logged on... very useful
https://docs.microsoft.com
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.micr osoft.com/ t5/core-in frastructu re-and-sec urity/expo rting-resu ltant-set- of-policy- rsop-data- using-powe rshell/ba- p/1217934
adapted from https://techcommunity.micr
$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"
}
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:
2. Some servers are offline, therefor powershell gives the following RPC errors. Is there a way to filter out offline computers?
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*"
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
Can you run
?
gpresult /x test.xml /Scope Computer /S Remote-SERVER
?
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
if($appliedgpos.Name -eq $scangpo)
with
$appliedgpos.Name -like $scangpo)
and you can use wildcards in $scangpo
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thank you very much Michael!
Glad it works