From 4ca5c8f1e7c59290ec9e1c6f3afcf1b5500dc738 Mon Sep 17 00:00:00 2001 From: Przemyslaw Klys Date: Sat, 17 Oct 2020 09:28:58 +0200 Subject: [PATCH] Update --- GPOZaurr.psd1 | 8 +- Private/Invoke-GPOZaurr.ps1 | 20 ---- Public/Get-GPOZaurrOwner.ps1 | 3 + ...POZaurrContent.ps1 => Invoke-GPOZaurr.ps1} | 31 ++++-- Public/Show-GPOZaurr.ps1 | 98 +++++++++++++++++++ README.md | 5 + 6 files changed, 135 insertions(+), 30 deletions(-) delete mode 100644 Private/Invoke-GPOZaurr.ps1 rename Public/{Invoke-GPOZaurrContent.ps1 => Invoke-GPOZaurr.ps1} (90%) create mode 100644 Public/Show-GPOZaurr.ps1 diff --git a/GPOZaurr.psd1 b/GPOZaurr.psd1 index d1d2900..fdae137 100644 --- a/GPOZaurr.psd1 +++ b/GPOZaurr.psd1 @@ -6,9 +6,9 @@ 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-GPOZaurrOwner', 'Get-GPOZaurrPassword', 'Get-GPOZaurrPermission', 'Get-GPOZaurrPermissionConsistency', 'Get-GPOZaurrPermissionRoot', 'Get-GPOZaurrPermissionSummary', 'Get-GPOZaurrSysvol', 'Get-GPOZaurrSysvolDFSR', 'Get-GPOZaurrWMI', 'Invoke-GPOZaurrContent', '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') + 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-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.62' + ModuleVersion = '0.0.63' PowerShellVersion = '5.1' PrivateData = @{ PSData = @{ @@ -18,11 +18,11 @@ } } RequiredModules = @(@{ - ModuleVersion = '0.0.181' + ModuleVersion = '0.0.182' ModuleName = 'PSSharedGoods' Guid = 'ee272aa8-baaa-4edf-9f45-b6d6f7d844fe' }, @{ - ModuleVersion = '0.0.98' + ModuleVersion = '0.0.99' ModuleName = 'ADEssentials' Guid = '9fc9fd61-7f11-4f4b-a527-084086f1905f' }, @{ diff --git a/Private/Invoke-GPOZaurr.ps1 b/Private/Invoke-GPOZaurr.ps1 deleted file mode 100644 index 8de0d81..0000000 --- a/Private/Invoke-GPOZaurr.ps1 +++ /dev/null @@ -1,20 +0,0 @@ -function Invoke-GPOZaurr { - [cmdletBinding()] - param( - - ) - New-HTML { - New-HTMLTab -Name 'Permissions' { - New-HTMLTab -Name 'Root' { - - } - New-HTMLTab -Name 'Edit & Modify' { - - } - New-HTMLTab -Name 'Consistency' { - - } - } - New-HTMLTab -Name '' - } -Online -ShowHTML -} \ No newline at end of file diff --git a/Public/Get-GPOZaurrOwner.ps1 b/Public/Get-GPOZaurrOwner.ps1 index 3f877ed..faa6d77 100644 --- a/Public/Get-GPOZaurrOwner.ps1 +++ b/Public/Get-GPOZaurrOwner.ps1 @@ -49,6 +49,9 @@ $Object['SysvolType'] = $FileOwner.OwnerType $Object['SysvolPath'] = $_.Path $Object['IsOwnerConsistent'] = if ($ACL.OwnerName -eq $FileOwner.OwnerName) { $true } else { $false } + $Object['IsOwnerAdministrative'] = if ($Object['SysvolType'] -eq 'Administrative' -and $Object['OwnerType'] -eq 'Administrative') { $true } else { $false } + } else { + $Object['IsOwnerAdministrative'] = if ($Object['OwnerType'] -eq 'Administrative') { $true } else { $false } } $Object['DistinguishedName'] = $_.GPODistinguishedName [PSCUstomObject] $Object diff --git a/Public/Invoke-GPOZaurrContent.ps1 b/Public/Invoke-GPOZaurr.ps1 similarity index 90% rename from Public/Invoke-GPOZaurrContent.ps1 rename to Public/Invoke-GPOZaurr.ps1 index 3af9a8e..43aaa91 100644 --- a/Public/Invoke-GPOZaurrContent.ps1 +++ b/Public/Invoke-GPOZaurr.ps1 @@ -1,4 +1,4 @@ -function Invoke-GPOZaurrContent { +function Invoke-GPOZaurr { [alias('Find-GPO')] [cmdletBinding(DefaultParameterSetName = 'Default')] param( @@ -21,11 +21,9 @@ [Parameter(ParameterSetName = 'Local')] [switch] $FullObjects, - <# [Parameter(ParameterSetName = 'Default')] [Parameter(ParameterSetName = 'Local')] - [ValidateSet('HTML', 'Object', 'Excel')][string[]] $OutputType = 'Object', - + [ValidateSet('HTML', 'Object')][string[]] $OutputType = 'Object', [Parameter(ParameterSetName = 'Default')] [Parameter(ParameterSetName = 'Local')] @@ -34,7 +32,10 @@ [Parameter(ParameterSetName = 'Default')] [Parameter(ParameterSetName = 'Local')] [switch] $Open, - #> + + [Parameter(ParameterSetName = 'Default')] + [Parameter(ParameterSetName = 'Local')] + [switch] $Online, [Parameter(ParameterSetName = 'Default')] [Parameter(ParameterSetName = 'Local')] @@ -228,7 +229,25 @@ $Output } else { if ($Output.Reports) { - $Output.Reports + if ($OutputType -eq 'Object') { + $Output.Reports + } + if ($OutputType -eq 'HTML') { + if (-not $OutputPath) { + $OutputPath = Get-FileName -Extension 'html' -Temporary + Write-Warning "Invoke-GPOZaurr - OutputPath not given. Using $OutputPath" + } + New-HTML { + New-HTMLSectionStyle -BorderRadius 0px -HeaderBackGroundColor Grey -RemoveShadow + New-HTMLTabStyle -BorderRadius 0px -TextTransform capitalize -BackgroundColorActive SlateGrey + New-HTMLTableOption -DataStore JavaScript + foreach ($Key in $Output.Reports.Keys) { + New-HTMLTab -Name $Key { + New-HTMLTable -DataTable $Output.Reports[$Key] -Filtering -Title $Key + } + } + } -FilePath $OutputPath -ShowHTML:$Open -Online:$Online + } } else { Write-Warning "Invoke-GPOZaurr - There was no data output for requested types." } diff --git a/Public/Show-GPOZaurr.ps1 b/Public/Show-GPOZaurr.ps1 new file mode 100644 index 0000000..4093df2 --- /dev/null +++ b/Public/Show-GPOZaurr.ps1 @@ -0,0 +1,98 @@ +function Show-GPOZaurr { + [cmdletBinding()] + param( + [string] $FilePath + ) + + $GPOContent = Invoke-GPOZaurr + $GPOSummary = Get-GPOZaurr + $GPOOrphans = Get-GPOZaurrSysvol + $GPOPermissions = Get-GPOZaurrPermission -Type All -IncludePermissionType GpoEditDeleteModifySecurity, GpoEdit, GpoCustom -IncludeOwner + $GPOPermissionsConsistency = Get-GPOZaurrPermissionConsistency -Type All -VerifyInheritance + $GPOPermissionsRoot = Get-GPOZaurrPermissionRoot + + $GPOOwners = Get-GPOZaurrOwner -IncludeSysvol + + $GPOLinked = $GPOSummary.Where( { $_.Linked -eq $true }, 'split') + $GPOEmpty = $GPOSummary.Where( { $_.Empty -eq $true, 'split' }) + $GPOTotal = $GPOSummary.Count + + $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' ) + + New-HTML { + New-HTMLTabStyle -BorderRadius 0px -TextTransform capitalize -BackgroundColorActive SlateGrey + 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 FireEngineRed, MediumSpringGreen, RedRobin, BlueDiamond + New-ChartBar -Name 'Group Policies' -Value $GPOLinked[1].Count, $GPOLinked[0].Count, $GPOEmpty[1].Count, $GPOTotal + + #New-ChartBar -Name 'Linked' -Value $GPOLinked[0].Count + #New-ChartBar -Name 'Empty' -Value $GPOEmpty[1].Count + #New-ChartBar -Name 'Total' -Value $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 + } + } + 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 Green, Red + 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 { + + } + } + } + New-HTMLTab -Name 'Group Policies Summary' { + New-HTMLTable -DataTable $GPOSummary -Filtering { + New-HTMLTableCondition -Name 'Empty' -Value $false -BackgroundColor RedOxide -TextTransform capitalize -ComparisonType bool + New-HTMLTableCondition -Name 'Linked' -Value $false -BackgroundColor RedOxide -TextTransform capitalize -ComparisonType bool + } + } + New-HTMLTab -Name 'Sysvol' { + New-HTMLTable -DataTable $GPOOrphans -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 + } + } + New-HTMLTab -Name 'Analysis' { + foreach ($Key in $GPOContent.Keys) { + New-HTMLTab -Name $Key { + New-HTMLTable -DataTable $GPOContent[$Key] -Filtering -Title $Key + } + } + } + } -Online -ShowHTML -FilePath $FilePath +} \ No newline at end of file diff --git a/README.md b/README.md index e7e0c9f..598338b 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,11 @@ That's it. Whenever there's a new version, you run the command, and you can enjo ## Changelog +- 0.0.63 - Unreleased + - Renamed `Invoke-GPOZaurrContent` back to `Invoke-GPOZaurr` + - Added `Show-GPOZaurr` (WIP) + - Added `OutputType`,`OutputType`,`Open`,`Online` parameters to `Invoke-GPOZaurr` + - Improved `Get-GPOZaurrOwner` - 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