This commit is contained in:
Przemyslaw Klys
2020-10-19 10:38:55 +02:00
parent a0723227c0
commit 13e5672b3f
4 changed files with 143 additions and 105 deletions
+1 -1
View File
@@ -6,7 +6,7 @@
CompatiblePSEditions = @('Desktop')
Copyright = '(c) 2011 - 2020 Przemyslaw Klys @ Evotec. All rights reserved.'
Description = 'Group Policy Eater is a PowerShell module that aims to gather information about Group Policies but also allows fixing issues that you may find in them.'
FunctionsToExport = @('Add-GPOPermission', 'Add-GPOZaurrPermission', 'Backup-GPOZaurr', 'Clear-GPOZaurrSysvolDFSR', 'ConvertFrom-CSExtension', 'Find-CSExtension', 'Get-GPOZaurr', 'Get-GPOZaurrAD', 'Get-GPOZaurrBackupInformation', 'Get-GPOZaurrDictionary', 'Get-GPOZaurrFiles', 'Get-GPOZaurrFilesPolicyDefinition', 'Get-GPOZaurrFolders', 'Get-GPOZaurrInheritance', 'Get-GPOZaurrLegacyFiles', 'Get-GPOZaurrLink', 'Get-GPOZaurrLinkSummary', 'Get-GPOZaurrNetlogon', 'Get-GPOZaurrOwner', 'Get-GPOZaurrPassword', 'Get-GPOZaurrPermission', 'Get-GPOZaurrPermissionConsistency', 'Get-GPOZaurrPermissionRoot', 'Get-GPOZaurrPermissionSummary', 'Get-GPOZaurrSysvol', 'Get-GPOZaurrSysvolDFSR', 'Get-GPOZaurrWMI', 'Invoke-GPOZaurr', 'Invoke-GPOZaurrPermission', 'Invoke-GPOZaurrSupport', 'New-GPOZaurrWMI', 'Remove-GPOPermission', 'Remove-GPOZaurr', 'Remove-GPOZaurrFolders', 'Remove-GPOZaurrLegacyFiles', 'Remove-GPOZaurrOrphaned', 'Remove-GPOZaurrPermission', 'Remove-GPOZaurrWMI', 'Repair-GPOZaurrPermissionConsistency', 'Restore-GPOZaurr', 'Save-GPOZaurrFiles', 'Set-GPOOwner', 'Set-GPOZaurrOwner', 'Show-GPOZaurr')
FunctionsToExport = @('Add-GPOPermission', 'Add-GPOZaurrPermission', 'Backup-GPOZaurr', 'Clear-GPOZaurrSysvolDFSR', 'ConvertFrom-CSExtension', 'Find-CSExtension', 'Get-GPOZaurr', 'Get-GPOZaurrAD', 'Get-GPOZaurrBackupInformation', 'Get-GPOZaurrDictionary', 'Get-GPOZaurrFiles', 'Get-GPOZaurrFilesPolicyDefinition', 'Get-GPOZaurrFolders', 'Get-GPOZaurrInheritance', 'Get-GPOZaurrLegacyFiles', 'Get-GPOZaurrLink', 'Get-GPOZaurrLinkSummary', 'Get-GPOZaurrNetLogon', 'Get-GPOZaurrOwner', 'Get-GPOZaurrPassword', 'Get-GPOZaurrPermission', 'Get-GPOZaurrPermissionConsistency', 'Get-GPOZaurrPermissionRoot', 'Get-GPOZaurrPermissionSummary', 'Get-GPOZaurrSysvol', 'Get-GPOZaurrSysvolDFSR', 'Get-GPOZaurrWMI', 'Invoke-GPOZaurr', 'Invoke-GPOZaurrPermission', 'Invoke-GPOZaurrSupport', 'New-GPOZaurrWMI', 'Remove-GPOPermission', 'Remove-GPOZaurr', 'Remove-GPOZaurrFolders', 'Remove-GPOZaurrLegacyFiles', 'Remove-GPOZaurrOrphaned', 'Remove-GPOZaurrPermission', 'Remove-GPOZaurrWMI', 'Repair-GPOZaurrPermissionConsistency', 'Restore-GPOZaurr', 'Save-GPOZaurrFiles', 'Set-GPOOwner', 'Set-GPOZaurrOwner', 'Show-GPOZaurr')
GUID = 'f7d4c9e4-0298-4f51-ad77-e8e3febebbde'
ModuleVersion = '0.0.63'
PowerShellVersion = '5.1'
+36 -34
View File
@@ -5,14 +5,15 @@
[string] $Server,
[string] $Domain,
[System.Collections.IDictionary] $PoliciesAD,
$PoliciesSearchBase
[string] $PoliciesSearchBase
)
$Differences = @{ }
$SysvolHash = @{ }
$GPOGUIDS = $GPOs.ID.GUID
$SysVolPath = "\\$($Server)\SYSVOL\$Domain\Policies"
try {
$SYSVOL = Get-ChildItem -Path "\\$($Server)\SYSVOL\$Domain\Policies" -ErrorAction Stop
$SYSVOL = Get-ChildItem -Path "\\$($Server)\SYSVOL\$Domain\Policies" -Exclude 'PolicyDefinitions' -ErrorAction Stop
} catch {
$Sysvol = $Null
}
@@ -59,7 +60,10 @@
$ErrorMessage = $_.Exception.Message
}
} else {
$FullPath = -join ($SysVolPath, "\{$($GPO.Id.Guid)}")
$ACL = $null
$Owner = ''
$ErrorMessage = 'Not found on SYSVOL'
}
if ($null -eq $Differences[$GPO.Id.Guid]) {
$SysVolStatus = 'Unknown Issue'
@@ -90,39 +94,37 @@
# Now we need to list thru Sysvol files and fine those that do not exists as GPO and create dummy GPO objects to show orphaned gpos
foreach ($_ in $Differences.Keys) {
if ($Differences[$_] -in 'Not available in AD', 'Permissions issue') {
if ($SysvolHash[$_].BaseName -notcontains 'PolicyDefinitions') {
$FullPath = $SysvolHash[$_].FullName
try {
$ACL = Get-Acl -Path $FullPath -ErrorAction Stop
$Owner = $ACL.Owner
$ErrorMessage = ''
} catch {
Write-Warning "Get-GPOZaurrSysvol - ACL reading (2) failed for $FullPath with error: $($_.Exception.Message)"
$ACL = $null
$Owner = $null
$ErrorMessage = $_.Exception.Message
}
$FullPath = $SysvolHash[$_].FullName
try {
$ACL = Get-Acl -Path $FullPath -ErrorAction Stop
$Owner = $ACL.Owner
$ErrorMessage = ''
} catch {
Write-Warning "Get-GPOZaurrSysvol - ACL reading (2) failed for $FullPath with error: $($_.Exception.Message)"
$ACL = $null
$Owner = $null
$ErrorMessage = $_.Exception.Message
}
[PSCustomObject] @{
DisplayName = $SysvolHash[$_].BaseName
Status = $Differences[$_]
DomainName = $Domain
SysvolServer = $Server
SysvolStatus = 'Exists' #$Differences[$GPO.Id.Guid]
GpoStatus = $Differences[$_]
Owner = ''
FileOwner = $Owner
Id = $_
Path = $FullPath
DistinguishedName = -join ("CN={", $_, "},", $PoliciesSearchBase)
Description = $null
CreationTime = $SysvolHash[$_].CreationTime
ModificationTime = $SysvolHash[$_].LastWriteTime
UserVersion = $null
ComputerVersion = $null
WmiFilter = $null
Error = $ErrorMessage
}
[PSCustomObject] @{
DisplayName = $SysvolHash[$_].BaseName
Status = $Differences[$_]
DomainName = $Domain
SysvolServer = $Server
SysvolStatus = 'Exists' #$Differences[$GPO.Id.Guid]
GpoStatus = $Differences[$_]
Owner = ''
FileOwner = $Owner
Id = $_
Path = $FullPath
DistinguishedName = -join ("CN={", $_, "},", $PoliciesSearchBase)
Description = $null
CreationTime = $SysvolHash[$_].CreationTime
ModificationTime = $SysvolHash[$_].LastWriteTime
UserVersion = $null
ComputerVersion = $null
WmiFilter = $null
Error = $ErrorMessage
}
}
}
+105 -70
View File
@@ -2,9 +2,11 @@
[cmdletBinding()]
param(
[string] $FilePath,
[ValidateSet('GPOList', 'GPOOrphans', 'NetLogon')][string[]] $Type
[ValidateSet(
'GPOList', 'GPOOrphans', 'GPOPermissions', 'GPOPermissionsRoot',
'GPOConsistency', 'GPOOwners', 'GPOAnalysis', 'NetLogon'
)][string[]] $Type
)
if ($Type -contains 'GPOList' -or $null -eq $Type) {
Write-Verbose -Message "Show-GPOZaurr - Processing GPO List"
$GPOSummary = Get-GPOZaurr
@@ -12,38 +14,38 @@
$GPOEmpty = $GPOSummary.Where( { $_.Empty -eq $true, 'split' })
$GPOTotal = $GPOSummary.Count
}
if ($Type -contains 'GPOOrphans' -or $null -eq $Type) {
Write-Verbose -Message "Show-GPOZaurr - Processing GPO Sysvol"
$GPOOrphans = Get-GPOZaurrSysvol
}
Write-Verbose -Message "Show-GPOZaurr - Processing GPO Permissions"
$GPOPermissions = Get-GPOZaurrPermission -Type All -IncludePermissionType GpoEditDeleteModifySecurity, GpoEdit, GpoCustom -IncludeOwner
Write-Verbose -Message "Show-GPOZaurr - Processing GPO Permissions Consistency"
$GPOPermissionsConsistency = Get-GPOZaurrPermissionConsistency -Type All -VerifyInheritance
Write-Verbose -Message "Show-GPOZaurr - Processing GPO Permissions Root"
$GPOPermissionsRoot = Get-GPOZaurrPermissionRoot
Write-Verbose "Show-GPOZaurr - Processing GPO Owners"
$GPOOwners = Get-GPOZaurrOwner -IncludeSysvol
if ($Type -contains 'GPOPermissions' -or $null -eq $Type) {
Write-Verbose -Message "Show-GPOZaurr - Processing GPO Permissions"
$GPOPermissions = Get-GPOZaurrPermission -Type All -IncludePermissionType GpoEditDeleteModifySecurity, GpoEdit, GpoCustom -IncludeOwner
}
if ($Type -contains 'GPOConsistency' -or $null -eq $Type) {
Write-Verbose -Message "Show-GPOZaurr - Processing GPO Permissions Consistency"
$GPOPermissionsConsistency = Get-GPOZaurrPermissionConsistency -Type All -VerifyInheritance
[Array] $Inconsistent = $GPOPermissionsConsistency.Where( { $_.ACLConsistent -eq $true } , 'split' )
[Array] $InconsistentInside = $GPOPermissionsConsistency.Where( { $_.ACLConsistentInside -eq $true }, 'split' )
}
if ($Type -contains 'GPOConsistency' -or $null -eq $Type) {
Write-Verbose -Message "Show-GPOZaurr - Processing GPO Permissions Root"
$GPOPermissionsRoot = Get-GPOZaurrPermissionRoot
}
if ($Type -contains 'GPOOwners' -or $null -eq $Type) {
Write-Verbose "Show-GPOZaurr - Processing GPO Owners"
$GPOOwners = Get-GPOZaurrOwner -IncludeSysvol
$IsOwnerConsistent = $GPOOwners.Where( { $_.IsOwnerConsistent -eq $true } , 'split' )
$IsOwnerAdministrative = $GPOOwners.Where( { $_.IsOwnerAdministrative -eq $true } , 'split' )
}
if ($Type -contains 'NetLogon' -or $null -eq $Type) {
Write-Verbose "Get-GPOZaurrNetLogon - Processing NETLOGON Share"
$Netlogon = Get-GPOZaurrNetlogon
}
Write-Verbose "Show-GPOZaurr - Processing GPO Analysis"
$GPOContent = Invoke-GPOZaurr
$IsOwnerConsistent = $GPOOwners.Where( { $_.IsOwnerConsistent -eq $true } , 'split' )
$IsOwnerAdministrative = $GPOOwners.Where( { $_.IsOwnerAdministrative -eq $true } , 'split' )
[Array] $Inconsistent = $GPOPermissionsConsistency.Where( { $_.ACLConsistent -eq $true } , 'split' )
[Array] $InconsistentInside = $GPOPermissionsConsistency.Where( { $_.ACLConsistentInside -eq $true }, 'split' )
if ($Type -contains 'GPOAnalysis' -or $null -eq $Type) {
Write-Verbose "Show-GPOZaurr - Processing GPO Analysis"
$GPOContent = Invoke-GPOZaurr
}
Write-Verbose "Show-GPOZaurr - Generating HTML"
New-HTML {
@@ -51,49 +53,64 @@
New-HTMLSectionStyle -BorderRadius 0px -HeaderBackGroundColor Grey -RemoveShadow
New-HTMLTableOption -DataStore JavaScript
New-HTMLTab -Name 'Overview' {
New-HTMLSection -Invisible {
New-HTMLPanel {
New-HTMLChart -Title 'Group Policies Summary' {
New-ChartLegend -Names 'Unlinked', 'Linked', 'Empty', 'Total' -Color Salmon, PaleGreen, PaleVioletRed, PaleTurquoise
New-ChartBar -Name 'Group Policies' -Value $GPOLinked[1].Count, $GPOLinked[0].Count, $GPOEmpty[1].Count, $GPOTotal
} -TitleAlignment center
}
New-HTMLPanel {
New-HTMLChart {
New-ChartBarOptions -Type barStacked
New-ChartLegend -Name 'Consistent', 'Inconsistent'
New-ChartBar -Name 'TopLevel' -Value $Inconsistent[0].Count, $Inconsistent[1].Count
New-ChartBar -Name 'Inherited' -Value $InconsistentInside[0].Count, $InconsistentInside[1].Count
} -Title 'Permissions Consistency' -TitleAlignment center
if ($Type -contains 'GPOConsistency' -or $Type -contains 'GPOList' -or $null -eq $Type) {
New-HTMLSection -Invisible {
if ($Type -contains 'GPOList' -or $null -eq $Type) {
New-HTMLPanel {
New-HTMLChart -Title 'Group Policies Summary' {
New-ChartLegend -Names 'Unlinked', 'Linked', 'Empty', 'Total' -Color Salmon, PaleGreen, PaleVioletRed, PaleTurquoise
New-ChartBar -Name 'Group Policies' -Value $GPOLinked[1].Count, $GPOLinked[0].Count, $GPOEmpty[1].Count, $GPOTotal
} -TitleAlignment center
}
}
if ($Type -contains 'GPOConsistency' -or $null -eq $Type) {
New-HTMLPanel {
New-HTMLChart {
New-ChartBarOptions -Type barStacked
New-ChartLegend -Name 'Consistent', 'Inconsistent'
New-ChartBar -Name 'TopLevel' -Value $Inconsistent[0].Count, $Inconsistent[1].Count
New-ChartBar -Name 'Inherited' -Value $InconsistentInside[0].Count, $InconsistentInside[1].Count
} -Title 'Permissions Consistency' -TitleAlignment center
}
}
}
}
New-HTMLSection -Invisible {
New-HTMLPanel {
New-HTMLText -Text 'Following chart presents Group Policy owners and whether they are administrative and consistent. By design an owner of Group Policy should be Domain Admins or Enterprise Admins group only to prevent malicious takeover. ', `
"It's also important that owner in Active Directory matches owner on SYSVOL (file system)."
New-HTMLChart {
New-ChartBarOptions -Type barStacked
New-ChartLegend -Name 'Yes', 'No' -Color PaleGreen, Orchid
New-ChartBar -Name 'Is administrative' -Value $IsOwnerAdministrative[0].Count, $IsOwnerAdministrative[1].Count
New-ChartBar -Name 'Is consistent' -Value $IsOwnerConsistent[0].Count, $IsOwnerConsistent[1].Count
} -Title 'Group Policy Owners'
}
New-HTMLPanel {
if ($Type -contains 'GPOOwners' -or $Type -contains 'GPOOwners' -or $null -eq $Type) {
New-HTMLSection -Invisible {
if ($Type -contains 'GPOOwners' -or $null -eq $Type) {
New-HTMLPanel {
New-HTMLText -Text 'Following chart presents Group Policy owners and whether they are administrative and consistent. By design an owner of Group Policy should be Domain Admins or Enterprise Admins group only to prevent malicious takeover. ', `
"It's also important that owner in Active Directory matches owner on SYSVOL (file system)."
New-HTMLChart {
New-ChartBarOptions -Type barStacked
New-ChartLegend -Name 'Yes', 'No' -Color PaleGreen, Orchid
New-ChartBar -Name 'Is administrative' -Value $IsOwnerAdministrative[0].Count, $IsOwnerAdministrative[1].Count
New-ChartBar -Name 'Is consistent' -Value $IsOwnerConsistent[0].Count, $IsOwnerConsistent[1].Count
} -Title 'Group Policy Owners'
}
}
if ($Type -contains 'GPOOwners' -or $null -eq $Type) {
New-HTMLPanel {
}
}
}
}
}
if ($Type -contains 'GPOList' -or $null -eq $Type) {
New-HTMLTab -Name 'Group Policies Summary' {
New-HTMLTable -DataTable $GPOSummary -Filtering {
New-HTMLTableCondition -Name 'Empty' -Value $false -BackgroundColor Salmon -TextTransform capitalize -ComparisonType bool
New-HTMLTableCondition -Name 'Empty' -Value $true -BackgroundColor Salmon -TextTransform capitalize -ComparisonType bool
New-HTMLTableCondition -Name 'Linked' -Value $false -BackgroundColor Salmon -TextTransform capitalize -ComparisonType bool
}
}
}
if ($Type -contains 'GPOOrphans' -or $null -eq $Type) {
New-HTMLTab -Name 'Sysvol' {
New-HTMLTable -DataTable $GPOOrphans -Filtering
New-HTMLTable -DataTable $GPOOrphans -Filtering {
New-HTMLTableCondition -Name 'Status' -Value "Not available in AD" -BackgroundColor Salmon -ComparisonType string
New-HTMLTableCondition -Name 'Status' -Value "Not available on SYSVOL" -BackgroundColor Salmon -ComparisonType string
}
}
}
if ($Type -contains 'NetLogon' -or $null -eq $Type) {
@@ -101,24 +118,42 @@
New-HTMLTable -DataTable $Netlogon -Filtering
}
}
New-HTMLTab -Name 'Permissions' {
New-HTMLTab -Name 'Root' {
New-HTMLTable -DataTable $GPOPermissionsRoot -Filtering
}
New-HTMLTab -Name 'Owners' {
New-HTMLTable -DataTable $GPOOwners -Filtering
}
New-HTMLTab -Name 'Edit & Modify' {
New-HTMLTable -DataTable $GPOPermissions -Filtering
}
New-HTMLTab -Name 'Inconsistent' {
New-HTMLTable -DataTable $GPOPermissionsConsistency -Filtering
if ($Type -contains 'GPOPermissionsRoot' -or $Type -contains 'GPOOwners' -or
$Type -contains 'GPOPermissions' -or $Type -contains 'GPOConsistency' -or
$null -eq $Type
) {
New-HTMLTab -Name 'Permissions' {
if ($Type -contains 'GPOPermissionsRoot' -or $null -eq $Type) {
New-HTMLTab -Name 'Root' {
New-HTMLTable -DataTable $GPOPermissionsRoot -Filtering
}
}
if ($Type -contains 'GPOOwners' -or $null -eq $Type) {
New-HTMLTab -Name 'Owners' {
New-HTMLTable -DataTable $GPOOwners -Filtering
}
}
if ($Type -contains 'GPOPermissions' -or $null -eq $Type) {
New-HTMLTab -Name 'Edit & Modify' {
New-HTMLTable -DataTable $GPOPermissions -Filtering
}
}
if ($Type -contains 'GPOConsistency' -or $null -eq $Type) {
New-HTMLTab -Name 'Permissions Consistency' {
New-HTMLTable -DataTable $GPOPermissionsConsistency -Filtering {
New-HTMLTableCondition -Name 'ACLConsistent' -Value $false -BackgroundColor Salmon -TextTransform capitalize -ComparisonType bool
New-HTMLTableCondition -Name 'ACLConsistentInside' -Value $false -BackgroundColor Salmon -TextTransform capitalize -ComparisonType bool
}
}
}
}
}
New-HTMLTab -Name 'Analysis' {
foreach ($Key in $GPOContent.Keys) {
New-HTMLTab -Name $Key {
New-HTMLTable -DataTable $GPOContent[$Key] -Filtering -Title $Key
if ($Type -contains 'GPOAnalysis' -or $null -eq $Type) {
New-HTMLTab -Name 'Analysis' {
foreach ($Key in $GPOContent.Keys) {
New-HTMLTab -Name $Key {
New-HTMLTable -DataTable $GPOContent[$Key] -Filtering -Title $Key
}
}
}
}
+1
View File
@@ -55,6 +55,7 @@ That's it. Whenever there's a new version, you run the command, and you can enjo
- Added `OutputType`,`OutputType`,`Open`,`Online` parameters to `Invoke-GPOZaurr`
- Added `Get-GPOZaurrNetLogon`
- Improved `Get-GPOZaurrOwner`
- Fixes `Get-GPOZaurrSysvol`
- 0.0.62 - 14.10.2020
- Renamed `Invoke-GPOZaurr` to `Invoke-GPOZaurrContent` - I want to use `Invoke-GPOZaurr` for something else
- Improvements to `Get-GPOZaurrPermissionConsistency` for GPOs without SYSVOL to be reported properly