mirror of
https://github.com/EvotecIT/GPOZaurr.git
synced 2026-07-26 20:00:09 +00:00
Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0383d249e9 | |||
| 8070179d27 | |||
| db67e6191e | |||
| db9b6d60c6 | |||
| 2c965d81d5 | |||
| bff372affe | |||
| 138a0f411e | |||
| 1c37a9d1df | |||
| 30535c1baf | |||
| 56c722edd0 |
+1
-1
@@ -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-GPOZaurrBrokenLink', 'Get-GPOZaurrDictionary', 'Get-GPOZaurrDuplicateObject', 'Get-GPOZaurrFiles', 'Get-GPOZaurrFilesPolicyDefinition', 'Get-GPOZaurrFolders', 'Get-GPOZaurrInheritance', 'Get-GPOZaurrLegacyFiles', 'Get-GPOZaurrLink', 'Get-GPOZaurrLinkSummary', 'Get-GPOZaurrNetLogon', 'Get-GPOZaurrOwner', 'Get-GPOZaurrPassword', 'Get-GPOZaurrPermission', 'Get-GPOZaurrPermissionAnalysis', 'Get-GPOZaurrPermissionConsistency', 'Get-GPOZaurrPermissionIssue', 'Get-GPOZaurrPermissionRoot', 'Get-GPOZaurrPermissionSummary', 'Get-GPOZaurrSysvolDFSR', 'Get-GPOZaurrWMI', 'Invoke-GPOZaurr', 'Invoke-GPOZaurrContent', 'Invoke-GPOZaurrPermission', 'Invoke-GPOZaurrSupport', 'New-GPOZaurrWMI', 'Optimize-GPOZaurr', 'Remove-GPOPermission', 'Remove-GPOZaurr', 'Remove-GPOZaurrBroken', 'Remove-GPOZaurrDuplicateObject', 'Remove-GPOZaurrFolders', 'Remove-GPOZaurrLegacyFiles', 'Remove-GPOZaurrPermission', 'Remove-GPOZaurrWMI', 'Repair-GPOZaurrBrokenLink', 'Repair-GPOZaurrNetLogonOwner', 'Repair-GPOZaurrPermission', 'Repair-GPOZaurrPermissionConsistency', 'Restore-GPOZaurr', 'Save-GPOZaurrFiles', 'Set-GPOOwner', 'Set-GPOZaurrOwner', 'Set-GPOZaurrStatus', 'Skip-GroupPolicy')
|
||||
GUID = 'f7d4c9e4-0298-4f51-ad77-e8e3febebbde'
|
||||
ModuleVersion = '0.0.116'
|
||||
ModuleVersion = '0.0.119'
|
||||
PowerShellVersion = '5.1'
|
||||
PrivateData = @{
|
||||
PSData = @{
|
||||
|
||||
+57
-30
@@ -12,6 +12,10 @@
|
||||
[string[]] $Type,
|
||||
[System.Collections.IDictionary] $LinksSummaryCache
|
||||
)
|
||||
|
||||
$DisplayName = $XMLContent.GPO.Name
|
||||
$DomainName = $XMLContent.GPO.Identifier.Domain.'#text'
|
||||
|
||||
if ($LinksSummaryCache) {
|
||||
$SearchGUID = -join ($XMLContent.GPO.Identifier.Domain.'#text', $XMLContent.GPO.Identifier.Identifier.InnerText -replace '{' -replace '}')
|
||||
if ($LinksSummaryCache[$SearchGUID]) {
|
||||
@@ -73,7 +77,7 @@
|
||||
} elseif ($XMLContent.GPO.Computer.Enabled -eq 'True') {
|
||||
$ComputerEnabled = $true
|
||||
} else {
|
||||
Write-Warning "Get-XMLGPO - Computer enabled not set to true or false. Weird."
|
||||
Write-Warning "Get-XMLGPO - Computer enabled not set to true or false [$DisplayName/$DomainName]. Weird."
|
||||
$ComputerEnabled = $null
|
||||
}
|
||||
if ($XMLContent.GPO.User.Enabled -eq 'False') {
|
||||
@@ -81,7 +85,7 @@
|
||||
} elseif ($XMLContent.GPO.User.Enabled -eq 'True') {
|
||||
$UserEnabled = $true
|
||||
} else {
|
||||
Write-Warning "Get-XMLGPO - User enabled not set to true or false. Weird."
|
||||
Write-Warning "Get-XMLGPO - User enabled not set to true or false [$DisplayName/$DomainName] . Weird."
|
||||
$UserEnabled = $null
|
||||
}
|
||||
# Translate Enabled to same as GPO GUI
|
||||
@@ -100,8 +104,8 @@
|
||||
}
|
||||
|
||||
# This is kind of old way of doing things, but it's superseded by other way below
|
||||
$ComputerSettingsAvailable = if ($null -eq $XMLContent.GPO.Computer.ExtensionData) { $false } else { $true }
|
||||
$UserSettingsAvailable = if ($null -eq $XMLContent.GPO.User.ExtensionData) { $false } else { $true }
|
||||
[bool] $ComputerSettingsAvailable = if ($null -eq $XMLContent.GPO.Computer.ExtensionData) { $false } else { $true }
|
||||
[bool] $UserSettingsAvailable = if ($null -eq $XMLContent.GPO.User.ExtensionData) { $false } else { $true }
|
||||
|
||||
if ($ComputerSettingsAvailable -eq $false -and $UserSettingsAvailable -eq $false) {
|
||||
$NoSettings = $true
|
||||
@@ -112,35 +116,58 @@
|
||||
# $OutputUser = $XMLContent.GPO.User.ExtensionData.Extension | Where-Object { $_.PSObject.Properties.TypeNameOfValue -in 'System.Xml.XmlElement', 'System.Object[]' }
|
||||
# $OutputComputer = $XMLContent.GPO.Computer.ExtensionData.Extension | Where-Object { $_.PSObject.Properties.TypeNameOfValue -in 'System.Xml.XmlElement', 'System.Object[]' }
|
||||
|
||||
$OutputUser = foreach ($ExtensionType in $XMLContent.GPO.User.ExtensionData.Extension) {
|
||||
if ($ExtensionType) {
|
||||
$GPOSettingTypeSplit = ($ExtensionType.type -split ':')
|
||||
try {
|
||||
$KeysToLoop = $ExtensionType | Get-Member -MemberType Properties -ErrorAction Stop | Where-Object { $_.Name -notin 'type', $GPOSettingTypeSplit[0] -and $_.Name -notin @('Blocked') }
|
||||
} catch {
|
||||
Write-Warning "Get-XMLGPO - things went sideways $($_.Exception.Message)"
|
||||
continue
|
||||
}
|
||||
|
||||
# This is additional check we do for error check to prevent false-positives for EMPTY on non-english language
|
||||
$PreCheckOutputUser = $false
|
||||
$PreCheckOutputComputer = $false
|
||||
foreach ($Extension in $XMLContent.GPO.User.ExtensionData) {
|
||||
if ($ExtensionType.Error) {
|
||||
$PreCheckOutputUser = $true
|
||||
}
|
||||
$KeysToLoop
|
||||
}
|
||||
$OutputComputer = foreach ($ExtensionType in $XMLContent.GPO.Computer.ExtensionData.Extension) {
|
||||
if ($ExtensionType) {
|
||||
$GPOSettingTypeSplit = ($ExtensionType.type -split ':')
|
||||
try {
|
||||
$KeysToLoop = $ExtensionType | Get-Member -MemberType Properties -ErrorAction Stop | Where-Object { $_.Name -notin 'type', $GPOSettingTypeSplit[0] -and $_.Name -notin @('Blocked') }
|
||||
} catch {
|
||||
Write-Warning "Get-XMLGPO - things went sideways $($_.Exception.Message)"
|
||||
continue
|
||||
}
|
||||
foreach ($Extension in $XMLContent.GPO.Computer.ExtensionData) {
|
||||
if ($Extension.Error) {
|
||||
$PreCheckOutputComputer = $true
|
||||
}
|
||||
$KeysToLoop
|
||||
}
|
||||
if ($PreCheckOutputComputer -eq $true -or $PreCheckOutputUser -eq $true) {
|
||||
# in some cases GPResult seems to return an error - this was first noticed by user when using Dutch based system
|
||||
# I am not sure if it's possible to fix this error for users, but once that happens checking if GPO is empty fails using the method below
|
||||
# therefore we will use the old method of assuming something is empty or not empty in such case
|
||||
Write-Warning "Get-XMLGPO - Reading GPO content [$DisplayName/$DomainName] returned an error. This may be because of non-english language. Assesing EMPTY using old method which can report false positives. Be careful please."
|
||||
$OutputUser = @()
|
||||
$OutputComputer = @()
|
||||
} else {
|
||||
[Array] $OutputUser = foreach ($ExtensionType in $XMLContent.GPO.User.ExtensionData.Extension) {
|
||||
if ($ExtensionType) {
|
||||
$GPOSettingTypeSplit = ($ExtensionType.type -split ':')
|
||||
try {
|
||||
$KeysToLoop = $ExtensionType | Get-Member -MemberType Properties -ErrorAction Stop | Where-Object { $_.Name -notin 'type', $GPOSettingTypeSplit[0] -and $_.Name -notin @('Blocked') }
|
||||
} catch {
|
||||
Write-Warning "Get-XMLGPO - things went sideways [$DisplayName/$DomainName]. Error $($_.Exception.Message)"
|
||||
continue
|
||||
}
|
||||
}
|
||||
$KeysToLoop
|
||||
}
|
||||
[Array] $OutputComputer = foreach ($ExtensionType in $XMLContent.GPO.Computer.ExtensionData.Extension) {
|
||||
if ($ExtensionType) {
|
||||
$GPOSettingTypeSplit = ($ExtensionType.type -split ':')
|
||||
try {
|
||||
$KeysToLoop = $ExtensionType | Get-Member -MemberType Properties -ErrorAction Stop | Where-Object { $_.Name -notin 'type', $GPOSettingTypeSplit[0] -and $_.Name -notin @('Blocked') }
|
||||
} catch {
|
||||
Write-Warning "Get-XMLGPO - things went sideways [$DisplayName/$DomainName]. Error $($_.Exception.Message)"
|
||||
continue
|
||||
}
|
||||
}
|
||||
$KeysToLoop
|
||||
}
|
||||
|
||||
[bool] $ComputerSettingsAvailable = if ($OutputComputer.Count -gt 0) { $true } else { $false }
|
||||
[bool] $UserSettingsAvailable = if ($OutputUser.Count -gt 0) { $true } else { $false }
|
||||
}
|
||||
|
||||
$ComputerSettingsAvailable = if ($OutputComputer) { $true } else { $false }
|
||||
$UserSettingsAvailable = if ($OutputUser) { $true } else { $false }
|
||||
|
||||
if (-not $ComputerSettingsAvailable -and -not $UserSettingsAvailable) {
|
||||
if ($ComputerSettingsAvailable -eq $false -and $UserSettingsAvailable -eq $false) {
|
||||
$Empty = $true
|
||||
} else {
|
||||
$Empty = $false
|
||||
@@ -277,8 +304,8 @@
|
||||
'UserSettingsAvailable' = $UserSettingsAvailable
|
||||
#'ComputerSettingsAvailableReal' = $ComputerSettingsAvailableReal
|
||||
#'UserSettingsAvailableReal' = $UserSettingsAvailableReal
|
||||
'ComputerSettingsTypes' = $OutputComputer.Name
|
||||
'UserSettingsTypes' = $OutputUser.Name
|
||||
'ComputerSettingsTypes' = $OutputComputer.Name -join ", "
|
||||
'UserSettingsTypes' = $OutputUser.Name -join ", "
|
||||
'ComputerEnabled' = $ComputerEnabled
|
||||
'UserEnabled' = $UserEnabled
|
||||
'ComputerSettingsStatus' = if ($XMLContent.GPO.Computer.VersionDirectory -eq 0 -and $XMLContent.GPO.Computer.VersionSysvol -eq 0) { "NeverModified" } else { "Modified" }
|
||||
|
||||
@@ -100,9 +100,11 @@
|
||||
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 -ExcludeGroupPolicies $ExcludeGPO -Type $Type
|
||||
if ($_.Name -ne 'GPOList.xml') {
|
||||
$XMLContent = [XML]::new()
|
||||
$XMLContent.Load($_.FullName)
|
||||
Get-XMLGPO -OwnerOnly:$OwnerOnly.IsPresent -XMLContent $XMLContent -PermissionsOnly:$PermissionsOnly.IsPresent -ExcludeGroupPolicies $ExcludeGPO -Type $Type
|
||||
}
|
||||
}
|
||||
Write-Verbose "Get-GPOZaurr - Finished GPO content from XML files"
|
||||
}
|
||||
|
||||
@@ -144,7 +144,10 @@
|
||||
|
||||
# Generate pretty HTML
|
||||
$TimeLogHTML = Start-TimeLog
|
||||
Write-Color -Text '[i]', '[HTML ] ', 'Generating HTML report' -Color Yellow, DarkGray, Yellow
|
||||
if (-not $FilePath) {
|
||||
$FilePath = Get-FileName -Extension 'html' -Temporary
|
||||
}
|
||||
Write-Color -Text '[i]', '[HTML ] ', "Generating HTML report ($FilePath)" -Color Yellow, DarkGray, Yellow
|
||||
New-HTML -Author 'Przemysław Kłys' -TitleText 'GPOZaurr Report' {
|
||||
New-HTMLTabStyle -BorderRadius 0px -TextTransform capitalize -BackgroundColorActive SlateGrey
|
||||
New-HTMLSectionStyle -BorderRadius 0px -HeaderBackGroundColor Grey -RemoveShadow
|
||||
|
||||
@@ -64,6 +64,14 @@ To understand the usage I've created blog post you may find useful
|
||||
|
||||
## Changelog
|
||||
|
||||
- 0.0.119 - 2021.02.10
|
||||
- [x] Improvement to `Get-GPOZaurr` to warn if there is potential issue with EMPTY (which can happen on non-english system)
|
||||
- [x] In such case GPOZaurr will asses EMPTY or not using old method which doesn't detect all EMPTY cases but shouldn't provide false positives
|
||||
- 0.0.118 - 2021.02.09
|
||||
- [x] Added information where the report is saved
|
||||
- [x] Small improvement to `Get-GPOZaurr` to exlicitly define variable types
|
||||
- 0.0.117 - 2021.02.09
|
||||
- [x] Small fix to `Get-GPOZaurr` to exclude GPOList.xml which is used in offline mode by `Save-GPOZaurrFiles`
|
||||
- 0.0.116 - 2021.02.08
|
||||
- [x] Improved `Remove-GPOZaurrBroken` to handle ObjectClass problem, and removed reduntant check
|
||||
- 0.0.115 - 2021.02.07
|
||||
|
||||
Reference in New Issue
Block a user