Compare commits

...

6 Commits

Author SHA1 Message Date
Przemyslaw Klys dc53cb36e0 Update readme 2020-10-22 14:55:25 +02:00
Przemyslaw Klys 7ff834fbfa Update 2020-10-22 14:55:04 +02:00
Przemyslaw Klys f5cf5dac4d Update 2020-10-22 14:00:46 +02:00
Przemyslaw Klys 5ffe89dec3 Update 2020-10-22 14:00:15 +02:00
Przemyslaw Klys 191b709ccf Update 2020-10-22 13:42:27 +02:00
Przemyslaw Klys b3e15d66ea Update 2020-10-22 10:51:37 +02:00
7 changed files with 108 additions and 34 deletions
+2 -2
View File
@@ -8,7 +8,7 @@
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-GPOZaurrBroken', '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-GPOZaurrSysvolDFSR', 'Get-GPOZaurrWMI', 'Invoke-GPOZaurr', 'Invoke-GPOZaurrPermission', 'Invoke-GPOZaurrSupport', 'New-GPOZaurrWMI', 'Remove-GPOPermission', 'Remove-GPOZaurr', 'Remove-GPOZaurrBroken', 'Remove-GPOZaurrFolders', 'Remove-GPOZaurrLegacyFiles', '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.65'
ModuleVersion = '0.0.67'
PowerShellVersion = '5.1'
PrivateData = @{
PSData = @{
@@ -18,7 +18,7 @@
}
}
RequiredModules = @(@{
ModuleVersion = '0.0.185'
ModuleVersion = '0.0.186'
ModuleName = 'PSSharedGoods'
Guid = 'ee272aa8-baaa-4edf-9f45-b6d6f7d844fe'
}, @{
+4 -4
View File
@@ -13,7 +13,7 @@
$GPOGUIDS = $GPOs.ID.GUID
$SysVolPath = "\\$($Server)\SYSVOL\$Domain\Policies"
try {
$SYSVOL = Get-ChildItem -Path "\\$($Server)\SYSVOL\$Domain\Policies" -Exclude 'PolicyDefinitions' -ErrorAction Stop
$SYSVOL = Get-ChildItem -Path "\\$($Server)\SYSVOL\$Domain\Policies" -Exclude 'PolicyDefinitions' -ErrorAction Stop -Verbose:$false
} catch {
$Sysvol = $Null
}
@@ -50,11 +50,11 @@
if ($null -ne $SysvolHash[$GPO.Id.GUID].FullName) {
$FullPath = $SysvolHash[$GPO.Id.GUID].FullName
try {
$ACL = Get-Acl -Path $SysvolHash[$GPO.Id.GUID].FullName -ErrorAction Stop
$ACL = Get-Acl -Path $SysvolHash[$GPO.Id.GUID].FullName -ErrorAction Stop -Verbose:$false
$Owner = $ACL.Owner
$ErrorMessage = ''
} catch {
Write-Warning "Get-GPOZaurrSysvol - ACL reading (1) failed for $FullPath with error: $($_.Exception.Message)"
Write-Warning "Get-GPOZaurrBroken - ACL reading (1) failed for $FullPath with error: $($_.Exception.Message)"
$ACL = $null
$Owner = ''
$ErrorMessage = $_.Exception.Message
@@ -100,7 +100,7 @@
$Owner = $ACL.Owner
$ErrorMessage = ''
} catch {
Write-Warning "Get-GPOZaurrSysvol - ACL reading (2) failed for $FullPath with error: $($_.Exception.Message)"
Write-Warning "Get-GPOZaurrBroken - ACL reading (2) failed for $FullPath with error: $($_.Exception.Message)"
$ACL = $null
$Owner = $null
$ErrorMessage = $_.Exception.Message
+7 -4
View File
@@ -14,7 +14,8 @@
)
$ForestInformation = Get-WinADForestDetails -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExcludeDomainControllers $ExcludeDomainControllers -IncludeDomainControllers $IncludeDomainControllers -SkipRODC:$SkipRODC -ExtendedForestInformation $ExtendedForestInformation -Extended
foreach ($Domain in $ForestInformation.Domains) {
Write-Verbose "Get-WinADGPOSysvolFolders - Processing $Domain"
$TimeLog = Start-TimeLog
Write-Verbose "Get-GPOZaurrBroken - Starting process for $Domain"
$QueryServer = $ForestInformation['QueryServers']["$Domain"].HostName[0]
$SystemsContainer = $ForestInformation['DomainsExtended'][$Domain].SystemsContainer
$PoliciesAD = @{}
@@ -35,7 +36,7 @@
Try {
[Array]$GPOs = Get-GPO -All -Domain $Domain -Server $QueryServer
} catch {
Write-Warning "Get-GPOZaurrSysvol - Couldn't get GPOs from $Domain. Error: $($_.Exception.Message)"
Write-Warning "Get-GPOZaurrBroken - Couldn't get GPOs from $Domain. Error: $($_.Exception.Message)"
continue
}
if ($GPOs.Count -ge 2) {
@@ -43,12 +44,14 @@
Test-SysVolFolders -GPOs $GPOs -Server $Domain -Domain $Domain -PoliciesAD $PoliciesAD -PoliciesSearchBase $PoliciesSearchBase
} else {
foreach ($Server in $ForestInformation['DomainDomainControllers']["$Domain"]) {
Write-Verbose "Get-GPOZaurrSysvol - Processing $Domain \ $($Server.HostName.Trim())"
Write-Verbose "Get-GPOZaurrBroken - Processing $Domain \ $($Server.HostName.Trim())"
Test-SysVolFolders -GPOs $GPOs -Server $Server.Hostname -Domain $Domain -PoliciesAD $PoliciesAD -PoliciesSearchBase $PoliciesSearchBase
}
}
} else {
Write-Warning "Get-GPOZaurrSysvol - GPO count for $Domain is less then 2. This is not expected for fully functioning domain. Skipping processing SYSVOL folder."
Write-Warning "Get-GPOZaurrBroken - GPO count for $Domain is less then 2. This is not expected for fully functioning domain. Skipping processing SYSVOL folder."
}
$TimeEnd = Stop-TimeLog -Time $TimeLog -Option OneLiner
Write-Verbose "Get-GPOZaurrBroken - Finishing process for $Domain (Time to process: $TimeEnd)"
}
}
@@ -16,6 +16,8 @@
}
Process {
foreach ($Domain in $ForestInformation.Domains) {
$TimeLog = Start-TimeLog
Write-Verbose "Get-GPOZaurrPermissionConsistency - Starting process for $Domain"
$QueryServer = $ForestInformation['QueryServers'][$Domain]['HostName'][0]
if ($GPOName) {
$getGPOSplat = @{
@@ -120,6 +122,8 @@
}
}
}
$TimeEnd = Stop-TimeLog -Time $TimeLog -Option OneLiner
Write-Verbose "Get-GPOZaurrPermissionConsistency - Finishing process for $Domain (Time to process: $TimeEnd)"
}
}
End {
+10 -7
View File
@@ -6,7 +6,8 @@
[alias('ForestName')][string] $Forest,
[string[]] $ExcludeDomains,
[alias('Domain', 'Domains')][string[]] $IncludeDomains,
[System.Collections.IDictionary] $ExtendedForestInformation
[System.Collections.IDictionary] $ExtendedForestInformation,
[switch] $SkipNames
)
Begin {
$ForestInformation = Get-WinADForestDetails -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExtendedForestInformation $ExtendedForestInformation -Extended
@@ -23,9 +24,8 @@
ADRightsAsArray = $true
ResolveTypes = $true
}
$GPOPermissionsGlobal = Get-ADACL @getADACLSplat #-Verbose
$GPOs = Get-ADObject -SearchBase "CN=Policies,CN=System,$DomainDistinguishedName" -SearchScope OneLevel -Filter * -Properties DisplayName -Server $QueryServer
$GPOPermissionsGlobal = Get-ADACL @getADACLSplat -Verbose:$false
$GPOs = Get-ADObject -SearchBase "CN=Policies,CN=System,$DomainDistinguishedName" -SearchScope OneLevel -Filter * -Properties DisplayName -Server $QueryServer -Verbose:$false
foreach ($Permission in $GPOPermissionsGlobal) {
$CustomPermission = foreach ($_ in $Permission.ActiveDirectoryRights) {
if ($_ -in 'WriteDACL', 'WriteOwner', 'GenericAll' ) {
@@ -43,7 +43,7 @@
if ($IncludePermissionType.Count -gt 0 -and $SinglePermission -notin $IncludePermissionType) {
continue
}
[PSCustomObject] @{
$OutputEntry = [ordered] @{
PrincipalName = $Permission.Principal
Permission = $SinglePermission
PermissionType = $Permission.AccessControlType
@@ -51,10 +51,13 @@
PrincipalObjectClass = $Permission.PrincipalObjectType
PrincipalDomainName = $Permission.PrincipalObjectDomain
PrincipalSid = $Permission.PrincipalObjectSid
GPOCount = $GPOs.Count
GPONames = $GPOs.DisplayName
DomainName = $Domain
GPOCount = $GPOs.Count
}
if (-not $SkipNames) {
$OutputEntry['GPONames'] = $GPOs.DisplayName
}
[PSCustomObject] $OutputEntry
}
}
}
+77 -17
View File
@@ -3,17 +3,45 @@
param(
[string] $FilePath,
[ValidateSet(
'GPOList', 'GPOOrphans', 'GPOPermissions', 'GPOPermissionsRoot',
'GPOList', 'GPOOrphans', 'GPOPermissions', 'GPOPermissionsRoot', 'GPOFiles',
'GPOConsistency', 'GPOOwners', 'GPOAnalysis', 'NetLogon'
)][string[]] $Type
)
$Script:Reporting = [ordered] @{
}
# Provide version check for easy use
$GPOZaurrVersion = Get-Command -Name 'Show-GPOZaurr' -ErrorAction SilentlyContinue
[Array] $GitHubReleases = (Get-GitHubLatestRelease -Url "https://api.github.com/repos/evotecit/GpoZaurr/releases" -Verbose:$false)
$LatestVersion = $GitHubReleases[0]
if (-not $LatestVersion.Errors) {
if ($GPOZaurrVersion.Version -eq $LatestVersion.Version) {
$Script:Reporting['Version'] = "GPOZaurr Current/Latest: $($LatestVersion.Version) at $($LatestVersion.PublishDate)"
} elseif ($GPOZaurrVersion.Version -lt $LatestVersion.Version) {
$Script:Reporting['Version'] = "GPOZaurr Current: $($GPOZaurrVersion.Version), Published: $($LatestVersion.Version) at $($LatestVersion.PublishDate). Update?"
} elseif ($GPOZaurrVersion.Version -gt $LatestVersion.Version) {
$Script:Reporting['Version'] = "GPOZaurr Current: $($GPOZaurrVersion.Version), Published: $($LatestVersion.Version) at $($LatestVersion.PublishDate). Lucky you!"
}
} else {
$Script:Reporting['Version'] = "GPOZaurr Current: $($GPOZaurrVersion.Version)"
}
# Gather data
$TimeLog = Start-TimeLog
if ($Type -contains 'GPOList' -or $null -eq $Type) {
#Write-Color -Text "[Info] ", "Processing GPO List" -Color Yellow, White
$TimeLogGPOList = Start-TimeLog
Write-Verbose -Message "Show-GPOZaurr - Processing GPO List"
$GPOSummary = Get-GPOZaurr
$GPOLinked = $GPOSummary.Where( { $_.Linked -eq $true }, 'split')
$GPOEmpty = $GPOSummary.Where( { $_.Empty -eq $true }, 'split' )
$GPOLinkedStatus = $GPOSummary.Where( { $_.Linked -eq $true }, 'split')
[Array] $GPONotLinked = $GPOLinkedStatus[1]
[Array] $GPOLinked = $GPOLinkedStatus[0]
$GPOEmptyStatus = $GPOSummary.Where( { $_.Empty -eq $true }, 'split' )
[Array] $GPOEmpty = $GPOEmptyStatus[0]
[Array] $GPONotEmpty = $GPOEmptyStatus[1]
$GPOTotal = $GPOSummary.Count
$TimeEndGPOList = Stop-TimeLog -Time $TimeLog -Option OneLiner
}
if ($Type -contains 'GPOOrphans' -or $null -eq $Type) {
#Write-Color -Text "[Info] ", "Processing GPOOrphans" -Color Yellow, White
@@ -46,7 +74,7 @@
}
if ($Type -contains 'GPOPermissionsRoot' -or $null -eq $Type) {
Write-Verbose -Message "Show-GPOZaurr - Processing GPO Permissions Root"
$GPOPermissionsRoot = Get-GPOZaurrPermissionRoot
$GPOPermissionsRoot = Get-GPOZaurrPermissionRoot -SkipNames
}
if ($Type -contains 'GPOOwners' -or $null -eq $Type) {
Write-Verbose "Show-GPOZaurr - Processing GPO Owners"
@@ -62,13 +90,31 @@
Write-Verbose "Show-GPOZaurr - Processing GPO Analysis"
$GPOContent = Invoke-GPOZaurr
}
if ($Type -contains 'GPOFiles') {
Write-Verbose "Show-GPOZaurr - Processing GPOFiles"
$GPOFiles = Get-GPOZaurrFiles
}
$TimeEnd = Stop-TimeLog -Time $TimeLog -Option OneLiner
# Generate pretty HTML
Write-Verbose "Show-GPOZaurr - Generating HTML"
New-HTML {
New-HTMLTabStyle -BorderRadius 0px -TextTransform capitalize -BackgroundColorActive SlateGrey
New-HTMLSectionStyle -BorderRadius 0px -HeaderBackGroundColor Grey -RemoveShadow
New-HTMLPanelStyle -BorderRadius 0px -RemoveShadow
New-HTMLPanelStyle -BorderRadius 0px
New-HTMLTableOption -DataStore JavaScript -BoolAsString
New-HTMLHeader {
New-HTMLSection -Invisible {
New-HTMLSection {
New-HTMLText -Text "Report generated on $(Get-Date)" -Color Blue
} -JustifyContent flex-start -Invisible
New-HTMLSection {
New-HTMLText -Text $Script:Reporting['Version'] -Color Blue
} -JustifyContent flex-end -Invisible
}
}
New-HTMLTab -Name 'Overview' {
if ($Type -contains 'GPOConsistency' -or $Type -contains 'GPOList' -or $null -eq $Type) {
New-HTMLSection -Invisible {
@@ -77,14 +123,18 @@
New-HTMLText -Text 'Following chart presents ', 'Linked / Empty and Unlinked Group Policies' -FontSize 10pt -FontWeight normal, bold
New-HTMLList -Type Unordered {
New-HTMLListItem -Text 'Group Policies total: ', $GPOTotal -FontWeight normal, bold
New-HTMLListItem -Text 'Group Policies linked: ', $GPOLinked[0].Count -FontWeight normal, bold
New-HTMLListItem -Text 'Group Policies that are unlinked (are not doing anything currently): ', $GPOLinked[1].Count -FontWeight normal, bold
New-HTMLListItem -Text "Group Policies that are empty (have no settings): ", $GPOEmpty[1].Count -FontWeight normal, bold
New-HTMLListItem -Text 'Group Policies linked: ', $GPOLinked.Count -FontWeight normal, bold
New-HTMLListItem -Text 'Group Policies that are unlinked (are not doing anything currently): ', $GPONotLinked.Count -FontWeight normal, bold
New-HTMLListItem -Text "Group Policies that are empty (have no settings): ", $GPOEmpty.Count -FontWeight normal, bold
} -FontSize 10pt
New-HTMLText -FontSize 10pt -Text 'Usually empty or unlinked Group Policies are safe to delete.'
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
New-ChartBarOptions -Type barStacked
#New-ChartLegend -Names 'Unlinked', 'Linked', 'Empty', 'Total' -Color Salmon, PaleGreen, PaleVioletRed, PaleTurquoise
New-ChartLegend -Names 'Good', 'Bad' -Color PaleGreen, Salmon
#New-ChartBar -Name 'Group Policies' -Value $GPONotLinked.Count, $GPOLinked.Count, $GPOEmpty.Count, $GPOTotal
New-ChartBar -Name 'Linked' -Value $GPOLinked.Count, $GPONotLinked.Count
New-ChartBar -Name 'Empty' -Value $GPONotEmpty.Count, $GPOEmpty.Count
} -TitleAlignment center
}
}
@@ -99,6 +149,7 @@
} -FontSize 10pt
New-HTMLText -FontSize 10pt -Text 'Having incosistent permissions on AD in comparison to those on SYSVOL can lead to uncontrolled ability to modify them.'
New-HTMLChart {
New-ChartLegend -Names 'Bad', 'Good' -Color PaleGreen, Salmon
New-ChartBarOptions -Type barStacked
New-ChartLegend -Name 'Consistent', 'Inconsistent'
New-ChartBar -Name 'TopLevel' -Value $Inconsistent[0].Count, $Inconsistent[1].Count
@@ -147,9 +198,9 @@
New-HTMLText -Text 'Following table shows a list of group policies. ', 'By using following table you can easily find which GPOs can be safely deleted because those are empty or unlinked.' -FontSize 10pt -FontWeight normal, bold
New-HTMLList -Type Unordered {
New-HTMLListItem -Text 'Group Policies total: ', $GPOTotal -FontWeight normal, bold
New-HTMLListItem -Text 'Group Policies linked: ', $GPOLinked[0].Count -FontWeight normal, bold
New-HTMLListItem -Text 'Group Policies that are unlinked (are not doing anything currently): ', $GPOLinked[1].Count -FontWeight normal, bold
New-HTMLListItem -Text "Group Policies that are empty (have no settings): ", $GPOEmpty[1].Count -FontWeight normal, bold
New-HTMLListItem -Text 'Group Policies linked: ', $GPOLinked.Count -FontWeight normal, bold
New-HTMLListItem -Text 'Group Policies that are unlinked (are not doing anything currently): ', $GPONotLinked.Count -FontWeight normal, bold
New-HTMLListItem -Text "Group Policies that are empty (have no settings): ", $GPOEmpty.Count -FontWeight normal, bold
} -FontSize 10pt
}
New-HTMLSection -Name 'Group Policies List' {
@@ -275,9 +326,18 @@
}
}
}
if ($Type -contains 'NetLogon' -or $null -eq $Type) {
New-HTMLTab -Name 'NetLogon' {
New-HTMLTable -DataTable $Netlogon -Filtering
if ($Type -contains 'NetLogon' -or $Type -contains 'GPOFiles' -or $null -eq $Type) {
New-HTMLTab -Name 'Files (SysVol / NetLogon)' {
if ($Type -contains 'NetLogon' -or $null -eq $Type) {
New-HTMLTab -Name 'NetLogon Permissions' {
New-HTMLTable -DataTable $Netlogon -Filtering
}
}
if ($Type -contains 'GPOFiles' -or $null -eq $Type) {
New-HTMLTab -Name 'SysVol Files Assesment' {
New-HTMLTable -DataTable $GPOFiles -Filtering
}
}
}
}
if ($Type -contains 'GPOPermissionsRoot' -or $Type -contains 'GPOOwners' -or
+4
View File
@@ -49,6 +49,10 @@ That's it. Whenever there's a new version, you run the command, and you can enjo
## Changelog
- 0.0.67 - 22.10.2020
- Improved `Show-GPOZaurr` (WIP)
- 0.0.66 - 22.10.2020
- Improved `Show-GPOZaurr` (WIP)
- 0.0.65 - 22.10.2020
- Improved `Show-GPOZaurr` (WIP)
- 0.0.64 - 21.10.2020