From c73c5ca48a19bb07fc17521ba78c1c2e4e53df5e Mon Sep 17 00:00:00 2001 From: Przemyslaw Klys Date: Thu, 3 Dec 2020 09:43:27 +0100 Subject: [PATCH] Update --- Private/Get-XMLGPO.ps1 | 12 +++++++++++- Private/Invoke.GPOZaurrList.ps1 | 20 ++++++++++++++++---- Public/Get-GPOZaurr.ps1 | 26 ++++++++++++++++++++++---- Public/Invoke-GPOZaurr.ps1 | 25 +++++++++++++++++++++++++ Public/Skip-GroupPolicy.ps1 | 14 ++++++++++++++ 5 files changed, 88 insertions(+), 9 deletions(-) create mode 100644 Public/Skip-GroupPolicy.ps1 diff --git a/Private/Get-XMLGPO.ps1 b/Private/Get-XMLGPO.ps1 index 1390982..273046a 100644 --- a/Private/Get-XMLGPO.ps1 +++ b/Private/Get-XMLGPO.ps1 @@ -7,7 +7,8 @@ [switch] $OwnerOnly, [System.Collections.IDictionary] $ADAdministrativeGroups, [string] $Splitter = [System.Environment]::NewLine, - [switch] $ReturnObject + [switch] $ReturnObject, + [System.Collections.IDictionary] $ExcludeGroupPolicies ) if ($XMLContent.GPO.LinksTo) { $LinkSplit = ([Array] $XMLContent.GPO.LinksTo).Where( { $_.Enabled -eq $true }, 'Split') @@ -159,6 +160,14 @@ $OwnerType = 'Unable to asses (local files?)' } } + # Mark GPO as excluded + $Exclude = $false + if ($ExcludeGroupPolicies) { + $PolicyWithDomain = -join ($XMLContent.GPO.Identifier.Domain.'#text', $XMLContent.GPO.Name) + if ($ExcludeGroupPolicies[$XMLContent.GPO.Name] -or $ExcludeGroupPolicies[$PolicyWithDomain]) { + $Exclude = $true + } + } if ($PermissionsOnly) { [PsCustomObject] @{ 'DisplayName' = $XMLContent.GPO.Name @@ -211,6 +220,7 @@ 'Enabled' = $EnabledBool 'Optimized' = $Optimized 'Problem' = $Problem + 'Exclude' = $Exclude 'ComputerPolicies' = $XMLContent.GPO.Computer.ExtensionData.Name -join ", " 'UserPolicies' = $XMLContent.GPO.User.ExtensionData.Name -join ", " 'LinksCount' = $LinksTotalCount diff --git a/Private/Invoke.GPOZaurrList.ps1 b/Private/Invoke.GPOZaurrList.ps1 index 1ec9454..9a091a4 100644 --- a/Private/Invoke.GPOZaurrList.ps1 +++ b/Private/Invoke.GPOZaurrList.ps1 @@ -154,8 +154,8 @@ ) -FontSize 10pt -FontWeight normal, bold, normal, bold, normal, bold, normal, normal, normal, normal New-HTMLText -LineBreak - <# - New-HTMLText -Text "Additionally, we're reviewing Group Policies that have their section disabled, but contain data. Please review them and make sure this configuration is as expected!" -FontSize 10pt + + New-HTMLText -Text "Additionally, we're reviewing Group Policies that have their section disabled, but contain data." -FontSize 10pt New-HTMLList -Type Unordered { New-HTMLListItem -Text 'Group Policies with problems: ', $Script:Reporting['GPOList']['Variables']['GPOWithProblems'] -FontWeight normal, bold { New-HTMLList -Type Unordered { @@ -164,7 +164,15 @@ } } } -FontSize 10pt - New-HTMLText -Text "For best performance it's recommended that if there are no settings of certain kind (Computer or User settings) it's best to disable them. " -FontSize 10pt + New-HTMLText -Text @( + "Such policies require manual review from whoever owns them. " + "It could be a mistake tha section was disabled while containing data or that content is no longer needed in which case it should be deleted. " + "This can't be auto-handled and is INFORMATIONAL only. " + ) -FontSize 10pt + + New-HTMLText -LineBreak + + New-HTMLText -Text "Moreover, for best performance it's recommended that if there are no settings of certain kind (Computer or User settings) it's best to disable whole section. " -FontSize 10pt New-HTMLList -Type Unordered { New-HTMLListItem -Text 'Group Policies with optimization: ' -FontWeight normal, bold { New-HTMLList -Type Unordered { @@ -179,7 +187,11 @@ } } } -FontSize 10pt - #> + New-HTMLText -Text @( + "This means " + $Script:Reporting['GPOList']['Variables']['GPONotOptimized'] + " could be optimized for performance reasons. " + ) -FontSize 10pt -FontWeight normal, bold, normal } Solution = { New-HTMLSection -Invisible { diff --git a/Public/Get-GPOZaurr.ps1 b/Public/Get-GPOZaurr.ps1 index 7f334ca..76f55a9 100644 --- a/Public/Get-GPOZaurr.ps1 +++ b/Public/Get-GPOZaurr.ps1 @@ -10,6 +10,8 @@ [System.Collections.IDictionary] $ExtendedForestInformation, [string[]] $GPOPath, + [Array] $ExcludeGroupPolicies, + [switch] $PermissionsOnly, [switch] $OwnerOnly, [switch] $Limited, @@ -24,6 +26,22 @@ if (-not $GPOPath) { $ForestInformation = Get-WinADForestDetails -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExtendedForestInformation $ExtendedForestInformation } + $ExcludeGPO = [ordered] @{} + if ($ExcludeGroupPolicies) { + foreach ($GroupPolicy in $ExcludeGroupPolicies) { + if ($GroupPolicy -is [string]) { + $ExcludeGPO[$GroupPolicy] = $true + } elseif ($GroupPolicy -is [System.Collections.IDictionary] -and $GroupPolicy.Name -and $GroupPolicy.DomainName) { + $PolicyName = -join ($GroupPolicy.DomainName, $GroupPolicy.Name) + $ExcludeGPO[$PolicyName] = $true + } elseif ($GroupPolicy -is [System.Collections.IDictionary] -and $GroupPolicy.Name) { + $ExcludeGPO[$GroupPolicy.Name] = $true + } else { + Write-Warning "Get-GPOZaurr - Exclusion takes only Group Policy Name as string, or as hashtable with domain name @{ Name = 'Group Policy Name'; DomainName = 'Domain' }." + continue + } + } + } } Process { if (-not $GPOPath) { @@ -43,7 +61,7 @@ Write-Warning "Get-GPOZaurr - Failed to get GPOReport: $($_.Exception.Message). Skipping." continue } - Get-XMLGPO -OwnerOnly:$OwnerOnly.IsPresent -XMLContent $XMLContent -GPO $_ -PermissionsOnly:$PermissionsOnly.IsPresent -ADAdministrativeGroups $ADAdministrativeGroups -ReturnObject:$ReturnObject.IsPresent + Get-XMLGPO -OwnerOnly:$OwnerOnly.IsPresent -XMLContent $XMLContent -GPO $_ -PermissionsOnly:$PermissionsOnly.IsPresent -ADAdministrativeGroups $ADAdministrativeGroups -ReturnObject:$ReturnObject.IsPresent -ExcludeGroupPolicies $ExcludeGPO } else { $_ } @@ -61,7 +79,7 @@ Write-Warning "Get-GPOZaurr - Failed to get GPOReport: $($_.Exception.Message). Skipping." continue } - Get-XMLGPO -OwnerOnly:$OwnerOnly.IsPresent -XMLContent $XMLContent -GPO $_ -PermissionsOnly:$PermissionsOnly.IsPresent -ADAdministrativeGroups $ADAdministrativeGroups -ReturnObject:$ReturnObject.IsPresent + Get-XMLGPO -OwnerOnly:$OwnerOnly.IsPresent -XMLContent $XMLContent -GPO $_ -PermissionsOnly:$PermissionsOnly.IsPresent -ADAdministrativeGroups $ADAdministrativeGroups -ReturnObject:$ReturnObject.IsPresent -ExcludeGroupPolicies $ExcludeGPO } else { $_ } @@ -79,7 +97,7 @@ Write-Warning "Get-GPOZaurr - Failed to get GPOReport: $($_.Exception.Message). Skipping." continue } - Get-XMLGPO -OwnerOnly:$OwnerOnly.IsPresent -XMLContent $XMLContent -GPO $_ -PermissionsOnly:$PermissionsOnly.IsPresent -ADAdministrativeGroups $ADAdministrativeGroups -ReturnObject:$ReturnObject.IsPresent + Get-XMLGPO -OwnerOnly:$OwnerOnly.IsPresent -XMLContent $XMLContent -GPO $_ -PermissionsOnly:$PermissionsOnly.IsPresent -ADAdministrativeGroups $ADAdministrativeGroups -ReturnObject:$ReturnObject.IsPresent -ExcludeGroupPolicies $ExcludeGPO } else { $_ } @@ -92,7 +110,7 @@ Get-ChildItem -LiteralPath $Path -Recurse -Filter *.xml | ForEach-Object { $XMLContent = [XML]::new() $XMLContent.Load($_.FullName) - Get-XMLGPO -OwnerOnly:$OwnerOnly.IsPresent -XMLContent $XMLContent -PermissionsOnly:$PermissionsOnly.IsPresent + Get-XMLGPO -OwnerOnly:$OwnerOnly.IsPresent -XMLContent $XMLContent -PermissionsOnly:$PermissionsOnly.IsPresent -ExcludeGroupPolicies $ExcludeGPO } Write-Verbose "Get-GPOZaurr - Finished GPO content from XML files" } diff --git a/Public/Invoke-GPOZaurr.ps1 b/Public/Invoke-GPOZaurr.ps1 index a382063..fb56176 100644 --- a/Public/Invoke-GPOZaurr.ps1 +++ b/Public/Invoke-GPOZaurr.ps1 @@ -2,6 +2,7 @@ [alias('Show-GPOZaurr', 'Show-GPO')] [cmdletBinding()] param( + [scriptblock] $Extension, [string] $FilePath, [string[]] $Type, [switch] $PassThru, @@ -41,6 +42,25 @@ Write-Color '[i]', "[GPOZaurr] ", 'Domain Information', ' [Informative] ', "Included Domains: ", $DisplayIncludedDomains -Color Yellow, DarkGray, Yellow, DarkGray, Yellow, Magenta Write-Color '[i]', "[GPOZaurr] ", 'Domain Information', ' [Informative] ', "Excluded Domains: ", $DisplayExcludedDomains -Color Yellow, DarkGray, Yellow, DarkGray, Yellow, Magenta + # Exclusions support, converts ScriptBlock into list of GPOs + $Exclusions = [ordered]@{} + if ($Extension) { + $Exclusions['All'] = [System.Collections.Generic.List[PSCustomObject]]::new() + [Array] $ExecuteExtension = & $Extension + foreach ($Ext in $ExecuteExtension) { + if ($Ext.Type -eq 'Exclusion') { + if ($Ext.Type) { + if (-not $Exclusions[$Ext.Type]) { + $Exclusions[$Ext.Type] = [System.Collections.Generic.List[PSCustomObject]]::new() + } + $Exclusions[$Ext.Type].Add($Ext) + } else { + $Exclusions['All'].Add($Ext) + } + } + } + } + # Lets make sure we only enable those types which are requestd by user if ($Type) { foreach ($T in $Script:GPOConfiguration.Keys) { @@ -59,11 +79,16 @@ Name = $Script:GPOConfiguration[$T].Name ActionRequired = $null Data = $null + Exclusions = $null WarningsAndErrors = $null Time = $null Summary = $null Variables = Copy-Dictionary -Dictionary $Script:GPOConfiguration[$T]['Variables'] } + if ($Exclusions) { + $Script:Reporting[$T]['Exclusions'] = $Extension + } + $TimeLogGPOList = Start-TimeLog Write-Color -Text '[i]', '[Start] ', $($Script:GPOConfiguration[$T]['Name']) -Color Yellow, DarkGray, Yellow $OutputCommand = Invoke-Command -ScriptBlock $Script:GPOConfiguration[$T]['Execute'] -WarningVariable CommandWarnings -ErrorVariable CommandErrors -ArgumentList $Forest, $ExcludeDomains, $IncludeDomains diff --git a/Public/Skip-GroupPolicy.ps1 b/Public/Skip-GroupPolicy.ps1 new file mode 100644 index 0000000..b6a6a2f --- /dev/null +++ b/Public/Skip-GroupPolicy.ps1 @@ -0,0 +1,14 @@ +function Skip-GroupPolicy { + [cmdletBinding()] + param( + [ValidateSet('GPOList')][string] $Type, + [string] $Name, + [string] $DomaiName + ) + @{ + Type = 'Exclusion' + ReportType = $Type + Name = $Name + DomainName = $DomaiName + } +} \ No newline at end of file