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') CompatiblePSEditions = @('Desktop')
Copyright = '(c) 2011 - 2020 Przemyslaw Klys @ Evotec. All rights reserved.' 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.' 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' GUID = 'f7d4c9e4-0298-4f51-ad77-e8e3febebbde'
ModuleVersion = '0.0.63' ModuleVersion = '0.0.63'
PowerShellVersion = '5.1' PowerShellVersion = '5.1'
+36 -34
View File
@@ -5,14 +5,15 @@
[string] $Server, [string] $Server,
[string] $Domain, [string] $Domain,
[System.Collections.IDictionary] $PoliciesAD, [System.Collections.IDictionary] $PoliciesAD,
$PoliciesSearchBase [string] $PoliciesSearchBase
) )
$Differences = @{ } $Differences = @{ }
$SysvolHash = @{ } $SysvolHash = @{ }
$GPOGUIDS = $GPOs.ID.GUID $GPOGUIDS = $GPOs.ID.GUID
$SysVolPath = "\\$($Server)\SYSVOL\$Domain\Policies"
try { try {
$SYSVOL = Get-ChildItem -Path "\\$($Server)\SYSVOL\$Domain\Policies" -ErrorAction Stop $SYSVOL = Get-ChildItem -Path "\\$($Server)\SYSVOL\$Domain\Policies" -Exclude 'PolicyDefinitions' -ErrorAction Stop
} catch { } catch {
$Sysvol = $Null $Sysvol = $Null
} }
@@ -59,7 +60,10 @@
$ErrorMessage = $_.Exception.Message $ErrorMessage = $_.Exception.Message
} }
} else { } else {
$FullPath = -join ($SysVolPath, "\{$($GPO.Id.Guid)}")
$ACL = $null $ACL = $null
$Owner = ''
$ErrorMessage = 'Not found on SYSVOL'
} }
if ($null -eq $Differences[$GPO.Id.Guid]) { if ($null -eq $Differences[$GPO.Id.Guid]) {
$SysVolStatus = 'Unknown Issue' $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 # 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) { foreach ($_ in $Differences.Keys) {
if ($Differences[$_] -in 'Not available in AD', 'Permissions issue') { if ($Differences[$_] -in 'Not available in AD', 'Permissions issue') {
if ($SysvolHash[$_].BaseName -notcontains 'PolicyDefinitions') { $FullPath = $SysvolHash[$_].FullName
$FullPath = $SysvolHash[$_].FullName try {
try { $ACL = Get-Acl -Path $FullPath -ErrorAction Stop
$ACL = Get-Acl -Path $FullPath -ErrorAction Stop $Owner = $ACL.Owner
$Owner = $ACL.Owner $ErrorMessage = ''
$ErrorMessage = '' } catch {
} catch { Write-Warning "Get-GPOZaurrSysvol - ACL reading (2) failed for $FullPath with error: $($_.Exception.Message)"
Write-Warning "Get-GPOZaurrSysvol - ACL reading (2) failed for $FullPath with error: $($_.Exception.Message)" $ACL = $null
$ACL = $null $Owner = $null
$Owner = $null $ErrorMessage = $_.Exception.Message
$ErrorMessage = $_.Exception.Message }
}
[PSCustomObject] @{ [PSCustomObject] @{
DisplayName = $SysvolHash[$_].BaseName DisplayName = $SysvolHash[$_].BaseName
Status = $Differences[$_] Status = $Differences[$_]
DomainName = $Domain DomainName = $Domain
SysvolServer = $Server SysvolServer = $Server
SysvolStatus = 'Exists' #$Differences[$GPO.Id.Guid] SysvolStatus = 'Exists' #$Differences[$GPO.Id.Guid]
GpoStatus = $Differences[$_] GpoStatus = $Differences[$_]
Owner = '' Owner = ''
FileOwner = $Owner FileOwner = $Owner
Id = $_ Id = $_
Path = $FullPath Path = $FullPath
DistinguishedName = -join ("CN={", $_, "},", $PoliciesSearchBase) DistinguishedName = -join ("CN={", $_, "},", $PoliciesSearchBase)
Description = $null Description = $null
CreationTime = $SysvolHash[$_].CreationTime CreationTime = $SysvolHash[$_].CreationTime
ModificationTime = $SysvolHash[$_].LastWriteTime ModificationTime = $SysvolHash[$_].LastWriteTime
UserVersion = $null UserVersion = $null
ComputerVersion = $null ComputerVersion = $null
WmiFilter = $null WmiFilter = $null
Error = $ErrorMessage Error = $ErrorMessage
}
} }
} }
} }
+105 -70
View File
@@ -2,9 +2,11 @@
[cmdletBinding()] [cmdletBinding()]
param( param(
[string] $FilePath, [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) { if ($Type -contains 'GPOList' -or $null -eq $Type) {
Write-Verbose -Message "Show-GPOZaurr - Processing GPO List" Write-Verbose -Message "Show-GPOZaurr - Processing GPO List"
$GPOSummary = Get-GPOZaurr $GPOSummary = Get-GPOZaurr
@@ -12,38 +14,38 @@
$GPOEmpty = $GPOSummary.Where( { $_.Empty -eq $true, 'split' }) $GPOEmpty = $GPOSummary.Where( { $_.Empty -eq $true, 'split' })
$GPOTotal = $GPOSummary.Count $GPOTotal = $GPOSummary.Count
} }
if ($Type -contains 'GPOOrphans' -or $null -eq $Type) { if ($Type -contains 'GPOOrphans' -or $null -eq $Type) {
Write-Verbose -Message "Show-GPOZaurr - Processing GPO Sysvol" Write-Verbose -Message "Show-GPOZaurr - Processing GPO Sysvol"
$GPOOrphans = Get-GPOZaurrSysvol $GPOOrphans = Get-GPOZaurrSysvol
} }
if ($Type -contains 'GPOPermissions' -or $null -eq $Type) {
Write-Verbose -Message "Show-GPOZaurr - Processing GPO Permissions" Write-Verbose -Message "Show-GPOZaurr - Processing GPO Permissions"
$GPOPermissions = Get-GPOZaurrPermission -Type All -IncludePermissionType GpoEditDeleteModifySecurity, GpoEdit, GpoCustom -IncludeOwner $GPOPermissions = Get-GPOZaurrPermission -Type All -IncludePermissionType GpoEditDeleteModifySecurity, GpoEdit, GpoCustom -IncludeOwner
}
Write-Verbose -Message "Show-GPOZaurr - Processing GPO Permissions Consistency" if ($Type -contains 'GPOConsistency' -or $null -eq $Type) {
$GPOPermissionsConsistency = Get-GPOZaurrPermissionConsistency -Type All -VerifyInheritance Write-Verbose -Message "Show-GPOZaurr - Processing GPO Permissions Consistency"
$GPOPermissionsConsistency = Get-GPOZaurrPermissionConsistency -Type All -VerifyInheritance
Write-Verbose -Message "Show-GPOZaurr - Processing GPO Permissions Root" [Array] $Inconsistent = $GPOPermissionsConsistency.Where( { $_.ACLConsistent -eq $true } , 'split' )
$GPOPermissionsRoot = Get-GPOZaurrPermissionRoot [Array] $InconsistentInside = $GPOPermissionsConsistency.Where( { $_.ACLConsistentInside -eq $true }, 'split' )
}
Write-Verbose "Show-GPOZaurr - Processing GPO Owners" if ($Type -contains 'GPOConsistency' -or $null -eq $Type) {
$GPOOwners = Get-GPOZaurrOwner -IncludeSysvol 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) { if ($Type -contains 'NetLogon' -or $null -eq $Type) {
Write-Verbose "Get-GPOZaurrNetLogon - Processing NETLOGON Share" Write-Verbose "Get-GPOZaurrNetLogon - Processing NETLOGON Share"
$Netlogon = Get-GPOZaurrNetlogon $Netlogon = Get-GPOZaurrNetlogon
} }
Write-Verbose "Show-GPOZaurr - Processing GPO Analysis" if ($Type -contains 'GPOAnalysis' -or $null -eq $Type) {
$GPOContent = Invoke-GPOZaurr 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' )
Write-Verbose "Show-GPOZaurr - Generating HTML" Write-Verbose "Show-GPOZaurr - Generating HTML"
New-HTML { New-HTML {
@@ -51,49 +53,64 @@
New-HTMLSectionStyle -BorderRadius 0px -HeaderBackGroundColor Grey -RemoveShadow New-HTMLSectionStyle -BorderRadius 0px -HeaderBackGroundColor Grey -RemoveShadow
New-HTMLTableOption -DataStore JavaScript New-HTMLTableOption -DataStore JavaScript
New-HTMLTab -Name 'Overview' { New-HTMLTab -Name 'Overview' {
New-HTMLSection -Invisible { if ($Type -contains 'GPOConsistency' -or $Type -contains 'GPOList' -or $null -eq $Type) {
New-HTMLPanel { New-HTMLSection -Invisible {
New-HTMLChart -Title 'Group Policies Summary' { if ($Type -contains 'GPOList' -or $null -eq $Type) {
New-ChartLegend -Names 'Unlinked', 'Linked', 'Empty', 'Total' -Color Salmon, PaleGreen, PaleVioletRed, PaleTurquoise New-HTMLPanel {
New-ChartBar -Name 'Group Policies' -Value $GPOLinked[1].Count, $GPOLinked[0].Count, $GPOEmpty[1].Count, $GPOTotal New-HTMLChart -Title 'Group Policies Summary' {
} -TitleAlignment center 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
New-HTMLPanel { } -TitleAlignment center
New-HTMLChart { }
New-ChartBarOptions -Type barStacked }
New-ChartLegend -Name 'Consistent', 'Inconsistent' if ($Type -contains 'GPOConsistency' -or $null -eq $Type) {
New-ChartBar -Name 'TopLevel' -Value $Inconsistent[0].Count, $Inconsistent[1].Count New-HTMLPanel {
New-ChartBar -Name 'Inherited' -Value $InconsistentInside[0].Count, $InconsistentInside[1].Count New-HTMLChart {
} -Title 'Permissions Consistency' -TitleAlignment center 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 { if ($Type -contains 'GPOOwners' -or $Type -contains 'GPOOwners' -or $null -eq $Type) {
New-HTMLPanel { New-HTMLSection -Invisible {
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. ', ` if ($Type -contains 'GPOOwners' -or $null -eq $Type) {
"It's also important that owner in Active Directory matches owner on SYSVOL (file system)." New-HTMLPanel {
New-HTMLChart { 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. ', `
New-ChartBarOptions -Type barStacked "It's also important that owner in Active Directory matches owner on SYSVOL (file system)."
New-ChartLegend -Name 'Yes', 'No' -Color PaleGreen, Orchid New-HTMLChart {
New-ChartBar -Name 'Is administrative' -Value $IsOwnerAdministrative[0].Count, $IsOwnerAdministrative[1].Count New-ChartBarOptions -Type barStacked
New-ChartBar -Name 'Is consistent' -Value $IsOwnerConsistent[0].Count, $IsOwnerConsistent[1].Count New-ChartLegend -Name 'Yes', 'No' -Color PaleGreen, Orchid
} -Title 'Group Policy Owners' New-ChartBar -Name 'Is administrative' -Value $IsOwnerAdministrative[0].Count, $IsOwnerAdministrative[1].Count
} New-ChartBar -Name 'Is consistent' -Value $IsOwnerConsistent[0].Count, $IsOwnerConsistent[1].Count
New-HTMLPanel { } -Title 'Group Policy Owners'
}
}
if ($Type -contains 'GPOOwners' -or $null -eq $Type) {
New-HTMLPanel {
}
}
} }
} }
} }
if ($Type -contains 'GPOList' -or $null -eq $Type) { if ($Type -contains 'GPOList' -or $null -eq $Type) {
New-HTMLTab -Name 'Group Policies Summary' { New-HTMLTab -Name 'Group Policies Summary' {
New-HTMLTable -DataTable $GPOSummary -Filtering { 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 New-HTMLTableCondition -Name 'Linked' -Value $false -BackgroundColor Salmon -TextTransform capitalize -ComparisonType bool
} }
} }
} }
if ($Type -contains 'GPOOrphans' -or $null -eq $Type) { if ($Type -contains 'GPOOrphans' -or $null -eq $Type) {
New-HTMLTab -Name 'Sysvol' { 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) { if ($Type -contains 'NetLogon' -or $null -eq $Type) {
@@ -101,24 +118,42 @@
New-HTMLTable -DataTable $Netlogon -Filtering New-HTMLTable -DataTable $Netlogon -Filtering
} }
} }
New-HTMLTab -Name 'Permissions' { if ($Type -contains 'GPOPermissionsRoot' -or $Type -contains 'GPOOwners' -or
New-HTMLTab -Name 'Root' { $Type -contains 'GPOPermissions' -or $Type -contains 'GPOConsistency' -or
New-HTMLTable -DataTable $GPOPermissionsRoot -Filtering $null -eq $Type
} ) {
New-HTMLTab -Name 'Owners' { New-HTMLTab -Name 'Permissions' {
New-HTMLTable -DataTable $GPOOwners -Filtering if ($Type -contains 'GPOPermissionsRoot' -or $null -eq $Type) {
} New-HTMLTab -Name 'Root' {
New-HTMLTab -Name 'Edit & Modify' { New-HTMLTable -DataTable $GPOPermissionsRoot -Filtering
New-HTMLTable -DataTable $GPOPermissions -Filtering }
} }
New-HTMLTab -Name 'Inconsistent' { if ($Type -contains 'GPOOwners' -or $null -eq $Type) {
New-HTMLTable -DataTable $GPOPermissionsConsistency -Filtering 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' { if ($Type -contains 'GPOAnalysis' -or $null -eq $Type) {
foreach ($Key in $GPOContent.Keys) { New-HTMLTab -Name 'Analysis' {
New-HTMLTab -Name $Key { foreach ($Key in $GPOContent.Keys) {
New-HTMLTable -DataTable $GPOContent[$Key] -Filtering -Title $Key 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 `OutputType`,`OutputType`,`Open`,`Online` parameters to `Invoke-GPOZaurr`
- Added `Get-GPOZaurrNetLogon` - Added `Get-GPOZaurrNetLogon`
- Improved `Get-GPOZaurrOwner` - Improved `Get-GPOZaurrOwner`
- Fixes `Get-GPOZaurrSysvol`
- 0.0.62 - 14.10.2020 - 0.0.62 - 14.10.2020
- Renamed `Invoke-GPOZaurr` to `Invoke-GPOZaurrContent` - I want to use `Invoke-GPOZaurr` for something else - 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 - Improvements to `Get-GPOZaurrPermissionConsistency` for GPOs without SYSVOL to be reported properly