📜 ⬆️ ⬇️

Build reports and analyze group policies using PowerShell

The topic of using PowerShell for administration is extremely relevant, and more and more articles on this topic appear on Habré. The previous translation of the article by Geoffrey Hicks, which we published last Friday, caused a wave of interest. And how can you not remember the remarkable performance of the same author on TechEd North America 2012. The report, which Jeffrey Hicks conducted with Jeremy Moskowitz (Jeremy Moskowitz), was devoted to the analysis of group policy objects and the formation of reports. The original material (video) is here , we also provide the short content + scripts. In any case, we recommend to watch the video itself.

The focus of the report was two questions:
  1. Build Group Policy Reports
  2. We carry out the analysis of group policies

Details - under the cut.


Using PowerShell in conjunction with group policies: what do you need for this?


To use PowerShell when working with group policies, we need:

')
The sequence of our actions:



Build Group Policy Reports


Problem number 1. It is necessary to obtain information about what is currently happening in group policies.


PS C:\> Import-Module GroupPolicy PS C:\> Get-GPO JeremyGPO 

In this case, instead of JeremyGPO appears the display name (DisplayName) of the group policy object. Such a sign is displayed.

 DisplayName : JeremyGPO DomainName : GLOBOMANTICS.local Owner : GLOBOMANTICS\Domain Admins Id : cd73c562-5bfe-40e2-b81e-28da10da425c GpoStatus : ComputerSettingsDisabled Description : CreationTime : 12/28/2011 2:52:37 PM ModificationTime : 5/21/2012 11:08:26 AM UserVersion : AD Version: 4, SysVol Version: 4 ComputerVersion : AD Version: 1, SysVol Version: 1 WmiFilter : 


Problem solving: create reports.

For example, we are faced with the task of obtaining a list of all group objects that have been changed in the last 30 days, sorted in descending order (the last ones at the top) with three values ​​(display name, time of change, description). The resulting information must be exported to a .csv file (GPOModReport.csv in this example). How it looks in PowerShell:

 PS C:\> get-gpo -all | Where {$_.ModificationTime -gt (Get-Date).AddDays(-30)} ... | Sort ModificationTime -Descending | Where {$_.ModificationTime -ge (Get-Date).AddDays(-30)} | Select Displayname,ModificationTime,Description ... | Export-CSV R:\GPOModReport.csv 


Examples of additional commands
 #      PS C:\>get-gpo -all | Sort CreationTime,Modificationtime | Select Displayname,*Time 


 #    ,    30  PS C:\>get-gpo -all | Where {$_.ModificationTime -ge (Get-Date).AddDays(-30)} 


 #       (Defaul Domain Policy) PS C:\>Get-GPOReport -name "Default Domain Policy" -ReportType HTML -Path "c:\work\ddp.htm" invoke-item "c:\work\ddp.htm" 


 #       PS C:\>Get-GPOReport -All -ReportType HTML -Path "c:\work\allgpo.htm" invoke-item "c:\work\allgpo.htm" 


 #        #   _   GPO PS C:\>Get-GPO -all | foreach { $f="{0}.htm" -f ($_.Displayname).Replace(" ","_") $htmfile=Join-Path -Path "C:\work" -ChildPath $f Get-GPOReport -Name $_.Displayname -ReportType HTML -Path $htmfile Get-Item $htmfile } 



Problem number 2. Too many GPOs that are not used.


Task: find empty GPOs




 PS C:\> Import-Module GroupPolicy PS C:\> [xml]$r = Get-GPOReport -Name MyGPO -ReportType XML PS C:\> if ((-Not $r.gpo.user.extensiondata) -AND (-not $r.gpo.computer.extensiondata)) { "GPO is empty" } 


Additional commands
 #requires -version 2.0 #find empty gpos in the domain Function Get-EmptyGPO { Param ( [Parameter(Position=0,ValueFromPipeline=$True, ValueFromPipelinebyPropertyName=$True)] [string]$DisplayName ) Begin { #import the GroupPolicy Module Import-Module GroupPolicy } Process { #create an XML report [xml]$report=Get-GPOReport -Name $displayname -ReportType XML #totally empty if ((-Not $report.gpo.user.extensiondata) -AND (-not $report.gpo.computer.extensiondata)) { #no extension data so write Get-GPO -Name $Displayname } } #process End {} } #function Function Test-EmptyGPO { Param ( [Parameter(Position=0,ValueFromPipeline=$True, ValueFromPipelinebyPropertyName=$True)] [string]$DisplayName ) Begin { #import the GroupPolicy Module Import-Module GroupPolicy } Process { #set default values $User=$False $Computer=$False #create an XML report [xml]$report=Get-GPOReport -Name $displayname -ReportType XML if ($report.gpo.user.extensiondata) { $User=$True } If ( $report.gpo.computer.extensiondata) { $Computer=$True } #write a custom object to the pipeline New-Object -TypeName PSObject -Property @{ Displayname=$report.gpo.name UserData=$User ComputerData=$Computer } } #Process End {} } #function #Get-GPO -All | Get-EmptyGPO #Get-GPO -All | Test-EmptyGPO 



Problem number 3.
Who accessed the GPO?
Are there GPOs where half of the policy is deactivated (“Are there any GPOs with 'half' the policy disabled?”)
Are there GPOs in which all policies are deactivated (“Are there any GPOs with 'all' the policy disabled?”)

Apply a filter by GPO status (GPOStatus). Three commands correspond to each of the three questions above:

 PS C:\> get-gpo -all | Sort GPOStatus | format-table -GroupBy GPOStatus Displayname,*Time PS C:\> get-gpo -all | where {$_.GPOStatus -match "disabled"} | Select GPOStatus,Displayname PS C:\> get-gpo -all | where {$_.GPOStatus -match "AllSettingsDisabled"} 


Analyzing Group Policy Objects


Problem number 4. Discover GPO without connections


 PS C:\> Import-Module ActiveDirectory Get-ADOrganizationalUnit -filter * | select-object -ExpandProperty DistinguishedName | get-adobject -prop gplink | where {$_.gplink} | Select-object -expand gplink | foreach-object { foreach ($item in ($_.Split("]["))) { $links+=$regex.match($item).Value } } Get-GPO -All | Where {$links -notcontains $_.id} 


Additional commands
 #requires -version 2.0 <# Find unlinked GPOs. This requires the Active Directory Module This version does not query for site links #> Import-Module ActiveDirectory,GroupPolicy #GUID regular expression pattern [Regex]$RegEx = "(([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12})" #create an array of distinguishednames $dn=@() $dn+=Get-ADDomain | select -ExpandProperty DistinguishedName $dn+=Get-ADOrganizationalUnit -filter * | select -ExpandProperty DistinguishedName $links=@() #get domain and OU links foreach ($container in $dn) { #pull the GUID and add it to the array of links get-adobject -identity $container -prop gplink | where {$_.gplink} | Select -expand gplink | foreach { #there might be multiple GPO links so split foreach ($item in ($_.Split("]["))) { $links+=$regex.match($item).Value } #foreach item } #foreach } #foreach container #$links <# get all gpos where the ID doesn't belong to the array write the GPO to the pipeline #> Get-GPO -All | Where {$links -notcontains $_.id} 



Problem 5. Group Policy Objects with Excess Registry Settings (“Extra Registry Settings”)

We find unnecessary settings in the registry
 #Use Xpath with the XML report data PS C:\> [xml]$report = Get-GPOReport -Name MyGPO -ReportType XML PS C:\> $ns = @{q3 = "http://www.microsoft.com/GroupPolicy/Settings/Registry"} PS C:\> $nodes = Select-Xml -Xml $report -Namespace $ns -XPath "//q3:RegistrySetting" | select -expand Node | Where {$_.AdmSetting -eq 'false'} 


Additional commands
 #requires -version 2.0 #find GPOs with extra registry, ie non-ADM settings Function Test-GPOExtraRegistry { Param ( [Parameter(Position=0,ValueFromPipeline=$True, ValueFromPipelinebyPropertyName=$True)] [string]$DisplayName ) Begin { #import the GroupPolicy Module Import-Module GroupPolicy } Process { #create an XML report [xml]$report=Get-GPOReport -Name $displayname -ReportType XML #define the XML namespace $ns=@{q3="http://www.microsoft.com/GroupPolicy/Settings/Registry"} $nodes=Select-Xml -Xml $report -Namespace $ns -XPath "//q3:RegistrySetting" | select -expand Node | Where {$_.AdmSetting -eq 'false'} if ($nodes) { #extra settings were found so get the GPO and write it to the pipeline Get-GPO -Name $Displayname } } End {} } #function #Import-Module GroupPolicy #Get-GPO -all | Test-GPOExtraRegistry 



Let us once again denote that we have only post the dry residue of what was shown in the report. The report itself can be viewed here .

Bonuses:


You can also use our NetWrix Group Policy Change Reporter program to build group policy reports.

Source: https://habr.com/ru/post/161533/


All Articles