mirror of
https://github.com/EvotecIT/GPOZaurr.git
synced 2026-07-26 11:49:17 +00:00
Compare commits
18 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| dc53cb36e0 | |||
| 7ff834fbfa | |||
| f5cf5dac4d | |||
| 5ffe89dec3 | |||
| 191b709ccf | |||
| b3e15d66ea | |||
| b3751d1dcc | |||
| 928d66eb9d | |||
| 72ecf97497 | |||
| aa8773ce73 | |||
| 6f11155914 | |||
| fd5413164a | |||
| 295f2e0a48 | |||
| 13e5672b3f | |||
| a0723227c0 | |||
| 72b2d2482b | |||
| 0c12761601 | |||
| 4ca5c8f1e7 |
@@ -1,4 +1,4 @@
|
||||
Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
|
||||
|
||||
$Output = Invoke-GPOZaurr -Verbose #-SingleObject
|
||||
$Output = Invoke-GPOZaurr -Verbose -OutputType HTML, Object -Open
|
||||
$Output | Format-Table
|
||||
@@ -1,9 +1,10 @@
|
||||
Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
|
||||
|
||||
# Asses GPO based on exported data
|
||||
$Output = Invoke-GPOZaurr -GPOPath $Env:USERPROFILE\Desktop\GPOExport_2020.10.12 -Verbose
|
||||
$Output = Invoke-GPOZaurr -GPOPath $Env:USERPROFILE\Desktop\GPOExport_2020.10.12 -Verbose -Type RegistrySetting
|
||||
$Output | Format-Table *
|
||||
|
||||
|
||||
# Export to Excel
|
||||
foreach ($Key in $Output.Keys) {
|
||||
$Output[$Key] | ConvertTo-Excel -FilePath $Env:USERPROFILE\Desktop\EFGPOAnalysis.xlsx -ExcelWorkSheetName $Key -AutoFilter -AutoFit -FreezeTopRowFirstColumn
|
||||
@@ -0,0 +1,4 @@
|
||||
Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
|
||||
|
||||
$FilesAll = Get-GPOZaurrNetlogon
|
||||
$FilesAll | Format-Table -a *
|
||||
+6
-6
@@ -1,14 +1,14 @@
|
||||
@{
|
||||
AliasesToExport = @('Get-GPOZaurrFilesPolicyDefinitions', 'Find-GPO')
|
||||
AliasesToExport = @('Get-GPOZaurrSysvol', 'Get-GPOZaurrFilesPolicyDefinitions', 'Find-GPO', 'Remove-GPOZaurrOrphaned')
|
||||
Author = 'Przemyslaw Klys'
|
||||
CmdletsToExport = @()
|
||||
CompanyName = 'Evotec'
|
||||
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-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.62'
|
||||
ModuleVersion = '0.0.67'
|
||||
PowerShellVersion = '5.1'
|
||||
PrivateData = @{
|
||||
PSData = @{
|
||||
@@ -18,15 +18,15 @@
|
||||
}
|
||||
}
|
||||
RequiredModules = @(@{
|
||||
ModuleVersion = '0.0.181'
|
||||
ModuleVersion = '0.0.186'
|
||||
ModuleName = 'PSSharedGoods'
|
||||
Guid = 'ee272aa8-baaa-4edf-9f45-b6d6f7d844fe'
|
||||
}, @{
|
||||
ModuleVersion = '0.0.98'
|
||||
ModuleVersion = '0.0.99'
|
||||
ModuleName = 'ADEssentials'
|
||||
Guid = '9fc9fd61-7f11-4f4b-a527-084086f1905f'
|
||||
}, @{
|
||||
ModuleVersion = '0.0.112'
|
||||
ModuleVersion = '0.0.116'
|
||||
ModuleName = 'PSWriteHTML'
|
||||
Guid = 'a7bdf640-f5cb-4acf-9de0-365b322d245c'
|
||||
}, 'CimCmdlets', 'Microsoft.PowerShell.Management', 'Microsoft.PowerShell.Utility')
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -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 -Verbose:$false
|
||||
} catch {
|
||||
$Sysvol = $Null
|
||||
}
|
||||
@@ -49,17 +50,20 @@
|
||||
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
|
||||
}
|
||||
} 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-GPOZaurrBroken - 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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+18
-6
@@ -29,9 +29,13 @@
|
||||
if (-not $GPOPath) {
|
||||
foreach ($Domain in $ForestInformation.Domains) {
|
||||
$QueryServer = $ForestInformation.QueryServers[$Domain]['HostName'][0]
|
||||
$Count = 0
|
||||
if ($GPOName) {
|
||||
Get-GPO -Name $GPOName -Domain $Domain -Server $QueryServer -ErrorAction SilentlyContinue | ForEach-Object {
|
||||
Write-Verbose "Get-GPOZaurr - Getting GPO $($_.DisplayName) / ID: $($_.ID) from $Domain"
|
||||
$GroupPolicies = Get-GPO -Name $GPOName -Domain $Domain -Server $QueryServer -ErrorAction SilentlyContinue
|
||||
$GroupPolicies | ForEach-Object {
|
||||
$Count++
|
||||
#Write-Verbose "Get-GPOZaurr - Getting GPO $($_.DisplayName) / ID: $($_.ID) from $Domain"
|
||||
Write-Verbose "Get-GPOZaurr - Processing [$($_.DomainName)]($Count/$($GroupPolicies.Count)) $($_.DisplayName)"
|
||||
if (-not $Limited) {
|
||||
try {
|
||||
$XMLContent = Get-GPOReport -ID $_.ID -ReportType XML -Server $ForestInformation.QueryServers[$Domain].HostName[0] -Domain $Domain -ErrorAction Stop
|
||||
@@ -45,8 +49,11 @@
|
||||
}
|
||||
}
|
||||
} elseif ($GPOGuid) {
|
||||
Get-GPO -Guid $GPOGuid -Domain $Domain -Server $QueryServer -ErrorAction SilentlyContinue | ForEach-Object {
|
||||
Write-Verbose "Get-GPOZaurr - Getting GPO $($_.DisplayName) / ID: $($_.ID) from $Domain"
|
||||
$GroupPolicies = Get-GPO -Guid $GPOGuid -Domain $Domain -Server $QueryServer -ErrorAction SilentlyContinue
|
||||
$GroupPolicies | ForEach-Object {
|
||||
$Count++
|
||||
#Write-Verbose "Get-GPOZaurr - Getting GPO $($_.DisplayName) / ID: $($_.ID) from $Domain"
|
||||
Write-Verbose "Get-GPOZaurr - Processing [$($_.DomainName)]($Count/$($GroupPolicies.Count)) $($_.DisplayName)"
|
||||
if (-not $Limited) {
|
||||
try {
|
||||
$XMLContent = Get-GPOReport -ID $_.ID -ReportType XML -Server $ForestInformation.QueryServers[$Domain].HostName[0] -Domain $Domain -ErrorAction Stop
|
||||
@@ -60,8 +67,11 @@
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Get-GPO -All -Server $QueryServer -Domain $Domain -ErrorAction SilentlyContinue | ForEach-Object {
|
||||
Write-Verbose "Get-GPOZaurr - Getting GPO $($_.DisplayName) / ID: $($_.ID) from $Domain"
|
||||
$GroupPolicies = Get-GPO -All -Server $QueryServer -Domain $Domain -ErrorAction SilentlyContinue
|
||||
$GroupPolicies | ForEach-Object {
|
||||
$Count++
|
||||
#Write-Verbose "Get-GPOZaurr - Getting GPO $($_.DisplayName) / ID: $($_.ID) from $Domain"
|
||||
Write-Verbose "Get-GPOZaurr - Processing [$($_.DomainName)]($Count/$($GroupPolicies.Count)) $($_.DisplayName)"
|
||||
if (-not $Limited) {
|
||||
try {
|
||||
$XMLContent = Get-GPOReport -ID $_.ID -ReportType XML -Server $ForestInformation.QueryServers[$Domain].HostName[0] -Domain $Domain -ErrorAction Stop
|
||||
@@ -78,11 +88,13 @@
|
||||
}
|
||||
} else {
|
||||
foreach ($Path in $GPOPath) {
|
||||
Write-Verbose "Get-GPOZaurr - Getting GPO content from XML files"
|
||||
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
|
||||
}
|
||||
Write-Verbose "Get-GPOZaurr - Finished GPO content from XML files"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
function Get-GPOZaurrSysvol {
|
||||
function Get-GPOZaurrBroken {
|
||||
[alias('Get-GPOZaurrSysvol')]
|
||||
[cmdletBinding()]
|
||||
param(
|
||||
[alias('ForestName')][string] $Forest,
|
||||
@@ -13,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 = @{}
|
||||
@@ -34,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) {
|
||||
@@ -42,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)"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
function Get-GPOZaurrNetLogon {
|
||||
[cmdletBinding(DefaultParameterSetName = 'Default')]
|
||||
param(
|
||||
[parameter(ParameterSetName = 'OwnerOnly')][switch] $OwnerOnly,
|
||||
[parameter(ParameterSetName = 'SkipOwner')][switch] $SkipOwner
|
||||
)
|
||||
$ForestInformation = Get-WinADForestDetails -Extended
|
||||
$FilesAll = foreach ($Domain in $ForestInformation.Domains) {
|
||||
$Path = -join ("\\", $Domain, '\Netlogon')
|
||||
$Files = Get-ChildItem -LiteralPath $Path -Recurse
|
||||
foreach ($_ in $Files) {
|
||||
$ACL = Get-Acl -Path $_.FullName
|
||||
if ($ACL.Owner) {
|
||||
$IdentityOwner = Convert-Identity -Identity $ACL.Owner
|
||||
} else {
|
||||
$IdentityOwner = [PSCustomObject] @{ SID = ''; Type = 'Uknown' }
|
||||
}
|
||||
if (-not $OwnerOnly) {
|
||||
if (-not $SkipOwner) {
|
||||
[PSCustomObject] @{
|
||||
FullName = $_.FullName
|
||||
Extension = $_.Extension
|
||||
CreationTime = $_.CreationTime
|
||||
LastAccessTime = $_.LastAccessTime
|
||||
LastWriteTime = $_.LastWriteTime
|
||||
Attributes = $_.Attributes
|
||||
AccessControlType = 'Allow' # : Allow
|
||||
Principal = $IdentityOwner.Name # : BUILTIN\Administrators
|
||||
PrincipalSid = $IdentityOwner.SID
|
||||
PrincipalType = $IdentityOwner.Type
|
||||
FileSystemRights = 'Owner' # : FullControl
|
||||
IsInherited = $false
|
||||
#Owner = $ACL.Owner
|
||||
}
|
||||
}
|
||||
$FilePermission = Get-FilePermissions -Path $_.FullName -ACLS $ACL
|
||||
foreach ($Perm in $FilePermission) {
|
||||
$Identity = Convert-Identity -Identity $Perm.Principal
|
||||
[PSCustomObject] @{
|
||||
FullName = $_.FullName
|
||||
Extension = $_.Extension
|
||||
CreationTime = $_.CreationTime
|
||||
LastAccessTime = $_.LastAccessTime
|
||||
LastWriteTime = $_.LastWriteTime
|
||||
Attributes = $_.Attributes
|
||||
AccessControlType = $Perm.AccessControlType # : Allow
|
||||
Principal = $Identity.Name # : BUILTIN\Administrators
|
||||
PrincipalSid = $Identity.SID
|
||||
PrincipalType = $Identity.Type
|
||||
FileSystemRights = $Perm.FileSystemRights # : FullControl
|
||||
IsInherited = $Perm.IsInherited # : True
|
||||
}
|
||||
}
|
||||
} else {
|
||||
[PSCustomObject] @{
|
||||
FullName = $_.FullName
|
||||
Extension = $_.Extension
|
||||
CreationTime = $_.CreationTime
|
||||
LastAccessTime = $_.LastAccessTime
|
||||
LastWriteTime = $_.LastWriteTime
|
||||
Attributes = $_.Attributes
|
||||
Owner = $IdentityOwner.Name
|
||||
OwnerSid = $IdentityOwner.SID
|
||||
OwnerType = $IdentityOwner.Type
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$FilesAll
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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 = @{
|
||||
@@ -39,7 +41,11 @@
|
||||
ErrorAction = 'SilentlyContinue'
|
||||
}
|
||||
}
|
||||
Get-GPO @getGPOSplat | ForEach-Object -Process {
|
||||
$GroupPolicies = Get-GPO @getGPOSplat
|
||||
$Count = 0
|
||||
$GroupPolicies | ForEach-Object -Process {
|
||||
$Count++
|
||||
Write-Verbose "Get-GPOZaurrPermissionConsistency - Processing [$($_.DomainName)]($Count/$($GroupPolicies.Count)) $($_.DisplayName)"
|
||||
try {
|
||||
$IsConsistent = $_.IsAclConsistent()
|
||||
$ErrorMessage = ''
|
||||
@@ -50,7 +56,7 @@
|
||||
}
|
||||
$SysVolpath = -join ('\\', $Domain, '\sysvol\', $Domain, '\Policies\{', $_.ID.GUID, '}')
|
||||
if ($VerifyInheritance) {
|
||||
$FolderPermissions = Get-WinADSharePermission -Path $SysVolpath
|
||||
$FolderPermissions = Get-WinADSharePermission -Path $SysVolpath -Verbose:$false
|
||||
if ($FolderPermissions) {
|
||||
[Array] $NotInheritedPermissions = foreach ($File in $FolderPermissions) {
|
||||
if ($File.Path -ne $SysVolpath -and $File.IsInherited -eq $false) {
|
||||
@@ -116,6 +122,8 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
$TimeEnd = Stop-TimeLog -Time $TimeLog -Option OneLiner
|
||||
Write-Verbose "Get-GPOZaurrPermissionConsistency - Finishing process for $Domain (Time to process: $TimeEnd)"
|
||||
}
|
||||
}
|
||||
End {
|
||||
|
||||
@@ -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,49 +51,14 @@
|
||||
PrincipalObjectClass = $Permission.PrincipalObjectType
|
||||
PrincipalDomainName = $Permission.PrincipalObjectDomain
|
||||
PrincipalSid = $Permission.PrincipalObjectSid
|
||||
DomainName = $Domain
|
||||
GPOCount = $GPOs.Count
|
||||
GPONames = $GPOs.DisplayName
|
||||
DomainName = $Domain
|
||||
}
|
||||
}
|
||||
|
||||
<#
|
||||
|
||||
if ($Permission.ActiveDirectoryRights | ForEach-Object {
|
||||
$_
|
||||
}) {
|
||||
|
||||
[PSCustomObject] @{
|
||||
PrincipalName = $Permission.Principal
|
||||
Permission = 'GpoCustomOwner'
|
||||
PermissionType = $Permission.AccessControlType
|
||||
PrincipalSidType = $Permission.PrincipalType
|
||||
PrincipalObjectClass = $Permission.PrincipalObjectType
|
||||
PrincipalDomainName = $Permission.PrincipalObjectDomain
|
||||
PrincipalSid = $Permission.PrincipalObjectSid
|
||||
GPOCount = 'N/A'
|
||||
GPONames = -join ("All-", $Domain.ToUpper())
|
||||
DomainName = $Domain
|
||||
if (-not $SkipNames) {
|
||||
$OutputEntry['GPONames'] = $GPOs.DisplayName
|
||||
}
|
||||
[PSCustomObject] $OutputEntry
|
||||
}
|
||||
if ($Permission.ActiveDirectoryRights | ForEach-Object {
|
||||
$_ -in 'CreateChild', 'GenericAll'
|
||||
}) {
|
||||
[PSCustomObject] @{
|
||||
PrincipalName = $Permission.Principal
|
||||
Permission = 'GpoCustomCreate'
|
||||
PermissionType = $Permission.AccessControlType
|
||||
PrincipalSidType = $Permission.PrincipalType
|
||||
PrincipalObjectClass = $Permission.PrincipalObjectType
|
||||
PrincipalDomainName = $Permission.PrincipalObjectDomain
|
||||
PrincipalSid = $Permission.PrincipalObjectSid
|
||||
GPOCount = 'N/A'
|
||||
GPONames = -join ("All-", $Domain.ToUpper())
|
||||
DomainName = $Domain
|
||||
}
|
||||
|
||||
}
|
||||
#>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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')]
|
||||
@@ -188,7 +189,6 @@
|
||||
$FindReport = $ReportType.Report
|
||||
Write-Verbose "Invoke-GPOZaurr - Processing reports based on other report $Report ($FindReport)"
|
||||
foreach ($GPO in $TemporaryCachedSingleReports['ReportsSingle'][$FindReport]) {
|
||||
Write-Verbose "Invoke-GPOZaurr - Processing $Report"
|
||||
$TranslatedGpo = Invoke-Command -ScriptBlock $Script:GPODitionary[$Report]['CodeReport']
|
||||
foreach ($T in $TranslatedGpo) {
|
||||
$Output['Reports'][$Report].Add($T)
|
||||
@@ -228,7 +228,27 @@
|
||||
$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"
|
||||
}
|
||||
Write-Verbose "Invoke-GPOZaurr - Generating HTML output"
|
||||
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 {
|
||||
Write-Verbose "Invoke-GPOZaurr - Generating HTML Table for $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."
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
function Remove-GPOZaurrOrphaned {
|
||||
function Remove-GPOZaurrBroken {
|
||||
[alias('Remove-GPOZaurrOrphaned')]
|
||||
[cmdletBinding(SupportsShouldProcess)]
|
||||
param(
|
||||
[ValidateSet('SYSVOL', 'AD')][string[]] $Type = @('SYSVOL', 'AD'),
|
||||
@@ -33,41 +34,41 @@
|
||||
}
|
||||
} | Select-Object | Select-Object -First $LimitProcessing | ForEach-Object {
|
||||
if ($_.Status -eq 'Not available in AD') {
|
||||
Write-Verbose "Remove-GPOZaurrOrphaned - Processing $($_.Path)"
|
||||
Write-Verbose "Remove-GPOZaurrBroken - Processing $($_.Path)"
|
||||
if ($BackupFinalPath) {
|
||||
Try {
|
||||
Write-Verbose "Remove-GPOZaurrOrphaned - Backing up $($_.Path)"
|
||||
Write-Verbose "Remove-GPOZaurrBroken - Backing up $($_.Path)"
|
||||
Copy-Item -LiteralPath $_.Path -Recurse -Destination $BackupFinalPath -ErrorAction Stop
|
||||
$BackupWorked = $true
|
||||
} catch {
|
||||
Write-Warning "Remove-GPOZaurrOrphaned - Error backing up error: $($_.Exception.Message)"
|
||||
Write-Warning "Remove-GPOZaurrBroken - Error backing up error: $($_.Exception.Message)"
|
||||
$BackupWorked = $false
|
||||
}
|
||||
}
|
||||
if ($BackupWorked -or $BackupFinalPath -eq '') {
|
||||
Write-Verbose "Remove-GPOZaurrOrphaned - Deleting $($_.Path)"
|
||||
Write-Verbose "Remove-GPOZaurrBroken - Deleting $($_.Path)"
|
||||
try {
|
||||
Remove-Item -Recurse -Force -LiteralPath $_.Path
|
||||
} catch {
|
||||
Write-Warning "Remove-GPOZaurrOrphaned - Failed to remove file $($_.Path): $($_.Exception.Message)."
|
||||
Write-Warning "Remove-GPOZaurrBroken - Failed to remove file $($_.Path): $($_.Exception.Message)."
|
||||
}
|
||||
}
|
||||
} elseif ($_.Status -eq 'Not available on SYSVOL') {
|
||||
try {
|
||||
$ExistingObject = Get-ADObject -Identity $_.DistinguishedName -Server $_.DomainName -ErrorAction Stop
|
||||
} catch {
|
||||
Write-Warning "Remove-GPOZaurrOrphaned - Error getting $($_.DistinguishedName) from AD error: $($_.Exception.Message)"
|
||||
Write-Warning "Remove-GPOZaurrBroken - Error getting $($_.DistinguishedName) from AD error: $($_.Exception.Message)"
|
||||
$ExistingObject = $null
|
||||
}
|
||||
if ($ExistingObject -and $ExistingObject.ObjectClass -eq 'groupPolicyContainer') {
|
||||
Write-Verbose "Remove-GPOZaurrOrphaned - Removing DN: $($_.DistinguishedName) / ObjectClass: $($ExistingObject.ObjectClass)"
|
||||
Write-Verbose "Remove-GPOZaurrBroken - Removing DN: $($_.DistinguishedName) / ObjectClass: $($ExistingObject.ObjectClass)"
|
||||
try {
|
||||
Remove-ADObject -Server $_.DomainName -Identity $_.DistinguishedName -Recursive -Confirm:$false
|
||||
} catch {
|
||||
Write-Warning "Remove-GPOZaurrOrphaned - Failed to remove $($_.DistinguishedName) from AD error: $($_.Exception.Message)"
|
||||
Write-Warning "Remove-GPOZaurrBroken - Failed to remove $($_.DistinguishedName) from AD error: $($_.Exception.Message)"
|
||||
}
|
||||
} else {
|
||||
Write-Warning "Remove-GPOZaurrOrphaned - DistinguishedName $($_.DistinguishedName) not found or ObjectClass is not groupPolicyContainer ($($ExistingObject.ObjectClass))"
|
||||
Write-Warning "Remove-GPOZaurrBroken - DistinguishedName $($_.DistinguishedName) not found or ObjectClass is not groupPolicyContainer ($($ExistingObject.ObjectClass))"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,466 @@
|
||||
function Show-GPOZaurr {
|
||||
[cmdletBinding()]
|
||||
param(
|
||||
[string] $FilePath,
|
||||
[ValidateSet(
|
||||
'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) {
|
||||
$TimeLogGPOList = Start-TimeLog
|
||||
Write-Verbose -Message "Show-GPOZaurr - Processing GPO List"
|
||||
$GPOSummary = Get-GPOZaurr
|
||||
$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
|
||||
Write-Verbose -Message "Show-GPOZaurr - Processing GPO Sysvol"
|
||||
$GPOOrphans = Get-GPOZaurrBroken
|
||||
|
||||
$NotAvailableInAD = [System.Collections.Generic.List[PSCustomObject]]::new()
|
||||
$NotAvailableOnSysvol = [System.Collections.Generic.List[PSCustomObject]]::new()
|
||||
$NotAvailablePermissionIssue = [System.Collections.Generic.List[PSCustomObject]]::new()
|
||||
foreach ($_ in $GPOOrphans) {
|
||||
if ($_.Status -eq 'Not available in AD') {
|
||||
$NotAvailableInAD.Add($NotAvailableInAD)
|
||||
} elseif ($_.Status -eq 'Not available on SYSVOL') {
|
||||
$NotAvailableOnSysvol.Add($NotAvailableInAD)
|
||||
} elseif ( $_.Status -eq 'Permissions issue') {
|
||||
$NotAvailablePermissionIssue.Add($NotAvailableInAD)
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($Type -contains 'GPOPermissions' -or $null -eq $Type) {
|
||||
#Write-Color -Text "[Info] ", "Processing GPOPermissions" -Color Yellow, White
|
||||
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 'GPOPermissionsRoot' -or $null -eq $Type) {
|
||||
Write-Verbose -Message "Show-GPOZaurr - Processing GPO Permissions Root"
|
||||
$GPOPermissionsRoot = Get-GPOZaurrPermissionRoot -SkipNames
|
||||
}
|
||||
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
|
||||
}
|
||||
if ($Type -contains 'GPOAnalysis' -or $null -eq $Type) {
|
||||
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
|
||||
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 {
|
||||
if ($Type -contains 'GPOList' -or $null -eq $Type) {
|
||||
New-HTMLPanel {
|
||||
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.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-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
|
||||
}
|
||||
}
|
||||
if ($Type -contains 'GPOConsistency' -or $null -eq $Type) {
|
||||
New-HTMLPanel {
|
||||
New-HTMLText -Text 'Following chart presents ', 'permissions consistency between Active Directory and SYSVOL for Group Policies' -FontSize 10pt -FontWeight normal, bold
|
||||
New-HTMLList -Type Unordered {
|
||||
New-HTMLListItem -Text 'Top level permissions consistency: ', $Inconsistent[0].Count -FontWeight normal, bold
|
||||
New-HTMLListItem -Text 'Inherited permissions consistency: ', $InconsistentInside[0].Count -FontWeight normal, bold
|
||||
New-HTMLListItem -Text 'Inconsistent top level permissions: ', $Inconsistent[1].Count -FontWeight normal, bold
|
||||
New-HTMLListItem -Text "Inconsistent inherited permissions: ", $InconsistentInside[1].Count -FontWeight normal, bold
|
||||
} -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
|
||||
New-ChartBar -Name 'Inherited' -Value $InconsistentInside[0].Count, $InconsistentInside[1].Count
|
||||
} -Title 'Permissions Consistency' -TitleAlignment center
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($Type -contains 'GPOOwners' -or $Type -contains 'GPOOrphans' -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 'GPOOrphans' -or $null -eq $Type) {
|
||||
New-HTMLPanel {
|
||||
New-HTMLText -Text 'Following chart presents ', 'Broken / Orphaned Group Policies' -FontSize 10pt -FontWeight normal, bold
|
||||
New-HTMLList -Type Unordered {
|
||||
New-HTMLListItem -Text 'Group Policies on SYSVOL, but no details in AD: ', $NotAvailableInAD.Count -FontWeight normal, bold
|
||||
New-HTMLListItem -Text 'Group Policies in AD, but no content on SYSVOL: ', $NotAvailableOnSysvol.Count -FontWeight normal, bold
|
||||
New-HTMLListItem -Text "Group Policies which couldn't be assed due to permissions issue: ", $NotAvailablePermissionIssue.Count -FontWeight normal, bold
|
||||
} -FontSize 10pt
|
||||
New-HTMLText -FontSize 10pt -Text 'Those problems must be resolved before doing other clenaup activities.'
|
||||
New-HTMLChart {
|
||||
New-ChartBarOptions -Type barStacked
|
||||
New-ChartLegend -Name 'Not in AD', 'Not on SYSVOL', 'Permissions Issue' -Color Crimson, LightCoral, IndianRed
|
||||
New-ChartBar -Name 'Orphans' -Value $NotAvailableInAD.Count, $NotAvailableOnSysvol.Count, $NotAvailablePermissionIssue.Count
|
||||
} -Title 'Broken / Orphaned Group Policies' -TitleAlignment center
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($Type -contains 'GPOList' -or $null -eq $Type) {
|
||||
New-HTMLTab -Name 'Group Policies Summary' {
|
||||
New-HTMLPanel {
|
||||
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.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' {
|
||||
New-HTMLTable -DataTable $GPOSummary -Filtering {
|
||||
New-HTMLTableCondition -Name 'Empty' -Value $true -BackgroundColor Salmon -TextTransform capitalize -ComparisonType string
|
||||
New-HTMLTableCondition -Name 'Linked' -Value $false -BackgroundColor Salmon -TextTransform capitalize -ComparisonType string
|
||||
} -PagingOptions 10, 20, 30, 40, 50
|
||||
}
|
||||
New-HTMLSection -Name 'Steps to fix - Empty & Unlinked Group Policies' {
|
||||
New-HTMLContainer {
|
||||
New-HTMLSpanStyle -FontSize 10pt {
|
||||
New-HTMLText -Text 'Following steps will guide you how to remove empty or unlinked group policies'
|
||||
New-HTMLWizard {
|
||||
New-HTMLWizardStep {
|
||||
|
||||
}
|
||||
} -RemoveDoneStepOnNavigateBack -Theme arrows -ToolbarButtonPosition center
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($Type -contains 'GPOOrphans' -or $null -eq $Type) {
|
||||
New-HTMLTab -Name 'Health State' {
|
||||
New-HTMLPanel {
|
||||
New-HTMLText -TextBlock {
|
||||
"Following table shows list of all group policies and their status in AD and SYSVOL. Due to different reasons it's "
|
||||
"possible that "
|
||||
} -FontSize 10pt
|
||||
New-HTMLList -Type Unordered {
|
||||
New-HTMLListItem -Text 'Group Policies on SYSVOL, but no details in AD: ', $NotAvailableInAD.Count -FontWeight normal, bold
|
||||
New-HTMLListItem -Text 'Group Policies in AD, but no content on SYSVOL: ', $NotAvailableOnSysvol.Count -FontWeight normal, bold
|
||||
New-HTMLListItem -Text "Group Policies which couldn't be assed due to permissions issue: ", $NotAvailablePermissionIssue.Count -FontWeight normal, bold
|
||||
} -FontSize 10pt
|
||||
New-HTMLText -Text "Follow the steps below table to get Active Directory Group Policies in healthy state." -FontSize 10pt
|
||||
}
|
||||
New-HTMLSection -Name 'Health State of Group Policies' {
|
||||
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 LightCoral -ComparisonType string
|
||||
New-HTMLTableCondition -Name 'Status' -Value "Permissions issue" -BackgroundColor MediumVioletRed -ComparisonType string -Color White
|
||||
} -PagingOptions 10, 20, 30, 40, 50
|
||||
}
|
||||
New-HTMLSection -Name 'Steps to fix - Not available on SYSVOL / Active Directory' {
|
||||
New-HTMLContainer {
|
||||
New-HTMLSpanStyle -FontSize 10pt {
|
||||
New-HTMLText -Text 'Following steps will guide you how to fix GPOs which are not available on SYSVOL or AD.'
|
||||
New-HTMLWizard {
|
||||
New-HTMLWizardStep -Name 'Prepare environment' {
|
||||
New-HTMLText -Text "To be able to execute actions in automated way please install required modules. Those modules will be installed straight from Microsoft PowerShell Gallery."
|
||||
New-HTMLCodeBlock -Code {
|
||||
Install-Module GPOZaurr -Force
|
||||
Import-Module GPOZaurr -Force
|
||||
} -Style powershell
|
||||
New-HTMLText -Text "Using force makes sure newest version is downloaded from PowerShellGallery regardless of what is currently installed. Once installed you're ready for next step."
|
||||
}
|
||||
New-HTMLWizardStep -Name 'Prepare report' {
|
||||
New-HTMLText -Text "Depending when this report was run you may want to prepare new report before proceeding with removal. To generate new report please use:"
|
||||
New-HTMLCodeBlock -Code {
|
||||
Show-GPOZaurr -FilePath $Env:UserProfile\Desktop\GPOZaurrBrokenGpoBefore.html -Verbose -Type GPOOrphans
|
||||
}
|
||||
New-HTMLText -Text {
|
||||
"When executed it will take a while to generate all data and provide you with new report depending on size of environment."
|
||||
"Once confirmed that data is still showing issues and requires fixing please proceed with next step."
|
||||
}
|
||||
New-HTMLText -Text "Alternatively if you prefer working with console you can run: "
|
||||
New-HTMLCodeBlock -Code {
|
||||
$GPOOutput = Get-GPOZaurrBroken
|
||||
$GPOOutput | Format-Table
|
||||
}
|
||||
New-HTMLText -Text "It provides same data as you see in table above just doesn't prettify it for you."
|
||||
}
|
||||
New-HTMLWizardStep -Name 'Fix GPOs not available on SYSVOL' {
|
||||
New-HTMLText -Text "Following command when executed runs cleanup procedure that removes all broken GPOs on SYSVOL side."
|
||||
New-HTMLText -Text "Make sure when running it for the first time to run it with ", "WhatIf", " parameter as shown below to prevent accidental removal." -FontWeight normal, bold, normal -Color Black, Red, Black
|
||||
|
||||
New-HTMLCodeBlock -Code {
|
||||
Remove-GPOZaurrBroken -Type SYSVOL -WhatIf
|
||||
}
|
||||
New-HTMLText -TextBlock {
|
||||
"After execution please make sure there are no errors, make sure to review provided output, and confirm that what is about to be deleted matches expected data. Once happy with results please follow with command: "
|
||||
}
|
||||
New-HTMLCodeBlock -Code {
|
||||
Remove-GPOZaurrBroken -Type SYSVOL -LimitProcessing 2 -BackupPath $Env:UserProfile\Desktop\GPOSYSVOLBackup
|
||||
}
|
||||
New-HTMLText -TextBlock {
|
||||
"This command when executed deletes only first X broken GPOs. Use LimitProcessing parameter to prevent mass delete and increase the counter when no errors occur."
|
||||
"Repeat step above as much as needed increasing LimitProcessing count till there's nothing left. In case of any issues please review and action accordingly."
|
||||
}
|
||||
New-HTMLText -Text "If there's nothing else to be deleted on SYSVOL side, we can skip to next step step"
|
||||
}
|
||||
New-HTMLWizardStep -Name 'Fix GPOs not available on AD' {
|
||||
New-HTMLText -Text "Following command when executed runs cleanup procedure that removes all broken GPOs on Active Directory side."
|
||||
New-HTMLText -Text "Make sure when running it for the first time to run it with ", "WhatIf", " parameter as shown below to prevent accidental removal." -FontWeight normal, bold, normal -Color Black, Red, Black
|
||||
|
||||
New-HTMLCodeBlock -Code {
|
||||
Remove-GPOZaurrBroken -Type AD -WhatIf
|
||||
}
|
||||
New-HTMLText -TextBlock {
|
||||
"After execution please make sure there are no errors, make sure to review provided output, and confirm that what is about to be deleted matches expected data. Once happy with results please follow with command: "
|
||||
}
|
||||
New-HTMLCodeBlock -Code {
|
||||
Remove-GPOZaurrBroken -Type AD -LimitProcessing 2 -BackupPath $Env:UserProfile\Desktop\GPOSYSVOLBackup
|
||||
}
|
||||
New-HTMLText -TextBlock {
|
||||
"This command when executed deletes only first X broken GPOs. Use LimitProcessing parameter to prevent mass delete and increase the counter when no errors occur."
|
||||
"Repeat step above as much as needed increasing LimitProcessing count till there's nothing left. In case of any issues please review and action accordingly."
|
||||
}
|
||||
New-HTMLText -Text "If there's nothing else to be deleted on AD side, we can skip to next step step"
|
||||
}
|
||||
New-HTMLWizardStep -Name 'Verification report' {
|
||||
New-HTMLText -TextBlock {
|
||||
"Once cleanup task was executed properly, we need to verify that report now shows no problems."
|
||||
}
|
||||
New-HTMLCodeBlock -Code {
|
||||
Show-GPOZaurr -FilePath $Env:UserProfile\Desktop\GPOZaurrBrokenGpoAfter.html -Verbose -Type GPOOrphans
|
||||
}
|
||||
New-HTMLText -Text "If everything is health in the report you're done! Enjoy rest of the day!" -Color BlueDiamond
|
||||
}
|
||||
} -RemoveDoneStepOnNavigateBack -Theme arrows -ToolbarButtonPosition center
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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
|
||||
$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-HTMLPanel {
|
||||
New-HTMLText -Text 'Following table presents ', 'permissions consistency between Active Directory and SYSVOL for Group Policies' -FontSize 10pt -FontWeight normal, bold
|
||||
New-HTMLList -Type Unordered {
|
||||
New-HTMLListItem -Text 'Top level permissions consistency: ', $Inconsistent[0].Count -FontWeight normal, bold
|
||||
New-HTMLListItem -Text 'Inherited permissions consistency: ', $InconsistentInside[0].Count -FontWeight normal, bold
|
||||
New-HTMLListItem -Text 'Inconsistent top level permissions: ', $Inconsistent[1].Count -FontWeight normal, bold
|
||||
New-HTMLListItem -Text "Inconsistent inherited permissions: ", $InconsistentInside[1].Count -FontWeight normal, bold
|
||||
} -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. Please notice that if ', `
|
||||
' Not available ', 'is visible in the table you should first fix related, more pressing issue, before fixing permissions inconsistency.' -FontWeight normal, bold, normal
|
||||
}
|
||||
New-HTMLSection -Name 'Group Policy Permissions Consistency' {
|
||||
New-HTMLTable -DataTable $GPOPermissionsConsistency -Filtering {
|
||||
New-HTMLTableCondition -Name 'ACLConsistent' -Value $false -BackgroundColor Salmon -TextTransform capitalize -ComparisonType string
|
||||
New-HTMLTableCondition -Name 'ACLConsistentInside' -Value $false -BackgroundColor Salmon -TextTransform capitalize -ComparisonType string
|
||||
New-HTMLTableCondition -Name 'ACLConsistent' -Value $true -BackgroundColor PaleGreen -TextTransform capitalize -ComparisonType string
|
||||
New-HTMLTableCondition -Name 'ACLConsistentInside' -Value $true -BackgroundColor PaleGreen -TextTransform capitalize -ComparisonType string
|
||||
New-HTMLTableCondition -Name 'ACLConsistent' -Value 'Not available' -BackgroundColor Crimson -ComparisonType string
|
||||
New-HTMLTableCondition -Name 'ACLConsistentInside' -Value 'Not available' -BackgroundColor Crimson -ComparisonType string
|
||||
} -PagingOptions 10, 20, 30, 40, 50
|
||||
}
|
||||
New-HTMLSection -Name 'Steps to fix - Permissions Consistency' {
|
||||
New-HTMLContainer {
|
||||
New-HTMLSpanStyle -FontSize 10pt {
|
||||
New-HTMLText -Text 'Following steps will guide you how to fix permissions consistency'
|
||||
New-HTMLWizard {
|
||||
New-HTMLWizardStep -Name 'Prepare environment' {
|
||||
New-HTMLText -Text "To be able to execute actions in automated way please install required modules. Those modules will be installed straight from Microsoft PowerShell Gallery."
|
||||
New-HTMLCodeBlock -Code {
|
||||
Install-Module GPOZaurr -Force
|
||||
Import-Module GPOZaurr -Force
|
||||
} -Style powershell
|
||||
New-HTMLText -Text "Using force makes sure newest version is downloaded from PowerShellGallery regardless of what is currently installed. Once installed you're ready for next step."
|
||||
}
|
||||
New-HTMLWizardStep -Name 'Prepare report' {
|
||||
New-HTMLText -Text "Depending when this report was run you may want to prepare new report before proceeding fixing permissions inconsistencies. To generate new report please use:"
|
||||
New-HTMLCodeBlock -Code {
|
||||
Show-GPOZaurr -FilePath $Env:UserProfile\Desktop\GPOZaurrPermissionsInconsistentBefore.html -Verbose -Type GPOConsistency
|
||||
}
|
||||
New-HTMLText -Text {
|
||||
"When executed it will take a while to generate all data and provide you with new report depending on size of environment."
|
||||
"Once confirmed that data is still showing issues and requires fixing please proceed with next step."
|
||||
}
|
||||
New-HTMLText -Text "Alternatively if you prefer working with console you can run: "
|
||||
New-HTMLCodeBlock -Code {
|
||||
$GPOOutput = Get-GPOZaurrPermissionConsistency
|
||||
$GPOOutput | Format-Table # do your actions as desired
|
||||
}
|
||||
New-HTMLText -Text "It provides same data as you see in table above just doesn't prettify it for you."
|
||||
}
|
||||
New-HTMLWizardStep -Name 'Fix inconsistent permissions' {
|
||||
New-HTMLText -Text "Following command when executed fixes inconsistent permissions."
|
||||
New-HTMLText -Text "Make sure when running it for the first time to run it with ", "WhatIf", " parameter as shown below to prevent accidental removal." -FontWeight normal, bold, normal -Color Black, Red, Black
|
||||
New-HTMLText -Text "Make sure to fill in TargetDomain to match your Domain Admin permission account"
|
||||
|
||||
New-HTMLCodeBlock -Code {
|
||||
Repair-GPOZaurrPermissionConsistency -IncludeDomains "TargetDomain" -Verbose -WhatIf
|
||||
}
|
||||
New-HTMLText -TextBlock {
|
||||
"After execution please make sure there are no errors, make sure to review provided output, and confirm that what is about to be deleted matches expected data. Once happy with results please follow with command: "
|
||||
}
|
||||
New-HTMLCodeBlock -Code {
|
||||
Repair-GPOZaurrPermissionConsistency -LimitProcessing 2 -IncludeDomains "TargetDomain"
|
||||
}
|
||||
New-HTMLText -TextBlock {
|
||||
"This command when executed repairs only first X inconsistent permissions. Use LimitProcessing parameter to prevent mass fixing and increase the counter when no errors occur."
|
||||
"Repeat step above as much as needed increasing LimitProcessing count till there's nothing left. In case of any issues please review and action accordingly."
|
||||
}
|
||||
New-HTMLText -Text "If there's nothing else to be fixed, we can skip to next step step"
|
||||
}
|
||||
New-HTMLWizardStep -Name 'Fix inconsistent downlevel permissions' {
|
||||
New-HTMLText -Text "Unfortunetly this step is manual until automation is developed. "
|
||||
New-HTMLText -Text "If there are inconsistent permissions found inside GPO one has to fix them manually by going into SYSVOL and making sure inheritance is enabled, and that permissions are consistent across all files."
|
||||
}
|
||||
New-HTMLWizardStep -Name 'Verification report' {
|
||||
New-HTMLText -TextBlock {
|
||||
"Once cleanup task was executed properly, we need to verify that report now shows no problems."
|
||||
}
|
||||
New-HTMLCodeBlock -Code {
|
||||
Show-GPOZaurr -FilePath $Env:UserProfile\Desktop\GPOZaurrPermissionsInconsistentAfter.html -Verbose -Type GPOConsistency
|
||||
}
|
||||
New-HTMLText -Text "If everything is health in the report you're done! Enjoy rest of the day!" -Color BlueDiamond
|
||||
}
|
||||
} -RemoveDoneStepOnNavigateBack -Theme arrows -ToolbarButtonPosition center
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} -Online -ShowHTML -FilePath $FilePath
|
||||
}
|
||||
@@ -49,6 +49,23 @@ 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
|
||||
- Renamed `Remove-GPOZaurrOrphaned` to `Remove-GPOZaurrBroken` keeping it as an alias
|
||||
- Renamed `Get-GPOZaurrSysvol` to `Get-GPOZaurrBroken` keeping it as an alias
|
||||
- Improved `Show-GPOZaurr` (WIP)
|
||||
- 0.0.63 - 19.10.2020
|
||||
- Renamed `Invoke-GPOZaurrContent` back to `Invoke-GPOZaurr`
|
||||
- Added `Show-GPOZaurr` (WIP)
|
||||
- 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
|
||||
|
||||
Reference in New Issue
Block a user