mirror of
https://github.com/EvotecIT/GPOZaurr.git
synced 2026-07-26 11:49:17 +00:00
Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f990cdfa03 | |||
| 34282f79bc | |||
| eda72cb1d3 | |||
| 8ab9c0ee21 | |||
| 8646b07e41 | |||
| 1fe0b6b37e | |||
| 553de6dc2b | |||
| 24fd00e110 | |||
| 6e5ae262d4 | |||
| 74192f5d48 | |||
| d0dc7a7052 |
@@ -0,0 +1,4 @@
|
||||
Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
|
||||
|
||||
$Issues = Get-GPOZaurrPermissionIssue
|
||||
$Issues | Format-Table
|
||||
+2
-2
@@ -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-GPOZaurrBroken', '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-GPOZaurrPermissionConsistency', '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-GPOZaurrNetLogonOwner', '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-GPOZaurrDuplicateObject', '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-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-GPOZaurrNetLogonOwner', 'Repair-GPOZaurrPermissionConsistency', 'Restore-GPOZaurr', 'Save-GPOZaurrFiles', 'Set-GPOOwner', 'Set-GPOZaurrOwner')
|
||||
GUID = 'f7d4c9e4-0298-4f51-ad77-e8e3febebbde'
|
||||
ModuleVersion = '0.0.81'
|
||||
ModuleVersion = '0.0.83'
|
||||
PowerShellVersion = '5.1'
|
||||
PrivateData = @{
|
||||
PSData = @{
|
||||
|
||||
@@ -166,7 +166,7 @@
|
||||
#>
|
||||
|
||||
# I don't trust the returned data, some stuff like 'alias' shows up for groups. To unify it with everything else... using my own function
|
||||
$PermissionAccount = Get-WinADObject -Identity $GPOPermission.Trustee.Sid.Value -AddType -Cache
|
||||
$PermissionAccount = Get-WinADObject -Identity $GPOPermission.Trustee.Sid.Value -AddType -Cache -Verbose:$false
|
||||
if ($PermissionAccount) {
|
||||
$UserNameDomain = $PermissionAccount.DomainName
|
||||
$UserName = $PermissionAccount.Name
|
||||
@@ -214,7 +214,7 @@
|
||||
if ($IncludeOwner) {
|
||||
if ($GPO.Owner) {
|
||||
# I don't trust the returned data, some stuff like 'alias' shows up for groups. To unify it with everything else... using my own function
|
||||
$OwnerAccount = Get-WinADObject -Identity $GPO.Owner -AddType -Cache
|
||||
$OwnerAccount = Get-WinADObject -Identity $GPO.Owner -AddType -Cache -Verbose:$false
|
||||
if ($OwnerAccount) {
|
||||
$UserNameDomain = $OwnerAccount.DomainName
|
||||
$UserName = $OwnerAccount.Name
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
$Script:Reporting['GPOConsistency']['Variables']['InconsistentInside']++
|
||||
}
|
||||
}
|
||||
if ($Script:Reporting['GPOConsistency']['Variables']['Inconsistent'].Count -gt 0 -or $Script:Reporting['GPOConsistency']['Variables']['InconsistentInside'].Count -gt 0 ) {
|
||||
if ($Script:Reporting['GPOConsistency']['Variables']['Inconsistent'] -gt 0 -or $Script:Reporting['GPOConsistency']['Variables']['InconsistentInside'] -gt 0 ) {
|
||||
$Script:Reporting['GPOConsistency']['ActionRequired'] = $true
|
||||
} else {
|
||||
$Script:Reporting['GPOConsistency']['ActionRequired'] = $false
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
}
|
||||
}
|
||||
$Script:Reporting['GPOList']['Variables']['GPOTotal'] = $Script:Reporting['GPOList']['Data'].Count
|
||||
if ($Script:Reporting['GPOList']['Variables']['GPOEmptyOrUnlinked'].Count -gt 0) {
|
||||
if ($Script:Reporting['GPOList']['Variables']['GPOEmptyOrUnlinked'] -gt 0) {
|
||||
$Script:Reporting['GPOList']['ActionRequired'] = $true
|
||||
} else {
|
||||
$Script:Reporting['GPOList']['ActionRequired'] = $false
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
$Script:Reporting['NetLogonPermissions']['Variables']['NonOwner'].Add($File)
|
||||
}
|
||||
}
|
||||
if ($Script:Reporting['NetLogonPermissions']['Variables']['NetLogonOwnersToFix'].Count -gt 0) {
|
||||
if ($Script:Reporting['NetLogonPermissions']['Variables']['NetLogonOwnersToFix'] -gt 0) {
|
||||
$Script:Reporting['NetLogonPermissions']['ActionRequired'] = $true
|
||||
} else {
|
||||
$Script:Reporting['NetLogonPermissions']['ActionRequired'] = $false
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
$Script:Reporting['GPOOrphans']['Variables']['NotAvailablePermissionIssuePerDomain'][$GPO.DomainName]++
|
||||
}
|
||||
}
|
||||
if ($Script:Reporting['GPOOrphans']['Variables']['ToBeDeleted'].Count -gt 0) {
|
||||
if ($Script:Reporting['GPOOrphans']['Variables']['ToBeDeleted'] -gt 0) {
|
||||
$Script:Reporting['GPOOrphans']['ActionRequired'] = $true
|
||||
} else {
|
||||
$Script:Reporting['GPOOrphans']['ActionRequired'] = $false
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
$Script:Reporting['GPOOwners']['Variables']['WillNotTouch']++
|
||||
}
|
||||
}
|
||||
if ($Script:Reporting['GPOOwners']['Variables']['WillFix'].Count -gt 0) {
|
||||
if ($Script:Reporting['GPOOwners']['Variables']['WillFix'] -gt 0) {
|
||||
$Script:Reporting['GPOOwners']['ActionRequired'] = $true
|
||||
} else {
|
||||
$Script:Reporting['GPOOwners']['ActionRequired'] = $false
|
||||
|
||||
@@ -4,13 +4,37 @@
|
||||
Action = $null
|
||||
Data = $null
|
||||
Execute = {
|
||||
Get-GPOZaurrPermission -Type AuthenticatedUsers -ReturnSecurityWhenNoData
|
||||
[ordered] @{
|
||||
Permissions = Get-GPOZaurrPermission -Type AuthenticatedUsers -ReturnSecurityWhenNoData
|
||||
Issues = Get-GPOZaurrPermissionIssue
|
||||
}
|
||||
}
|
||||
Processing = {
|
||||
# This is a workaround - we need to use it since we have 0 permissions
|
||||
|
||||
# Create Per Domain Variables
|
||||
$Script:Reporting['GPOPermissionsRead']['Variables']['WillFixPerDomain'] = @{}
|
||||
$Script:Reporting['GPOPermissionsRead']['Variables']['WillNotTouchPerDomain'] = @{}
|
||||
foreach ($GPO in $Script:Reporting['GPOPermissionsRead']['Data']) {
|
||||
$Script:Reporting['GPOPermissionsRead']['Variables']['ReadPerDomain'] = @{}
|
||||
$Script:Reporting['GPOPermissionsRead']['Variables']['CouldNotReadPerDomain'] = @{}
|
||||
|
||||
foreach ($GPO in $Script:Reporting['GPOPermissionsRead']['Data'].Issues) {
|
||||
# Create Per Domain Variables
|
||||
if (-not $Script:Reporting['GPOPermissionsRead']['Variables']['CouldNotReadPerDomain'][$GPO.DomainName]) {
|
||||
$Script:Reporting['GPOPermissionsRead']['Variables']['CouldNotReadPerDomain'][$GPO.DomainName] = 0
|
||||
}
|
||||
if (-not $Script:Reporting['GPOPermissionsRead']['Variables']['ReadPerDomain'][$GPO.DomainName]) {
|
||||
$Script:Reporting['GPOPermissionsRead']['Variables']['ReadPerDomain'][$GPO.DomainName] = 0
|
||||
}
|
||||
if ($GPO.PermissionIssue) {
|
||||
$Script:Reporting['GPOPermissionsRead']['Variables']['CouldNotRead']++
|
||||
$Script:Reporting['GPOPermissionsRead']['Variables']['CouldNotReadPerDomain'][$GPO.DomainName]++
|
||||
} else {
|
||||
$Script:Reporting['GPOPermissionsRead']['Variables']['Read']++
|
||||
$Script:Reporting['GPOPermissionsRead']['Variables']['ReadPerDomain'][$GPO.DomainName]++
|
||||
}
|
||||
}
|
||||
foreach ($GPO in $Script:Reporting['GPOPermissionsRead']['Data'].Permissions) {
|
||||
# Create Per Domain Variables
|
||||
if (-not $Script:Reporting['GPOPermissionsRead']['Variables']['WillFixPerDomain'][$GPO.DomainName]) {
|
||||
$Script:Reporting['GPOPermissionsRead']['Variables']['WillFixPerDomain'][$GPO.DomainName] = 0
|
||||
@@ -27,17 +51,24 @@
|
||||
$Script:Reporting['GPOPermissionsRead']['Variables']['WillFixPerDomain'][$GPO.DomainName]++
|
||||
}
|
||||
}
|
||||
if ($Script:Reporting['GPOPermissionsRead']['Variables']['WillFix'].Count -gt 0) {
|
||||
if ($Script:Reporting['GPOPermissionsRead']['Variables']['WillFix'] -gt 0 -or $Script:Reporting['GPOPermissionsRead']['Variables']['CouldNotRead'] -gt 0) {
|
||||
$Script:Reporting['GPOPermissionsRead']['ActionRequired'] = $true
|
||||
} else {
|
||||
$Script:Reporting['GPOPermissionsRead']['ActionRequired'] = $false
|
||||
}
|
||||
# Summary from 2 reports
|
||||
$Script:Reporting['GPOPermissionsRead']['Variables']['TotalToFix'] = $Script:Reporting['GPOPermissionsRead']['Variables']['WillFix'] + $Script:Reporting['GPOPermissionsRead']['Variables']['CouldNotRead']
|
||||
}
|
||||
Variables = @{
|
||||
WillFix = 0
|
||||
WillNotTouch = 0
|
||||
WillFixPerDomain = $null
|
||||
WillNotTouchPerDomain = $ull
|
||||
WillNotTouchPerDomain = $null
|
||||
CouldNotRead = 0
|
||||
CouldNotReadPerDomain = $null
|
||||
Read = 0
|
||||
ReadPerDomain = $null
|
||||
TotalToFix = 0
|
||||
}
|
||||
Overview = {
|
||||
|
||||
@@ -46,12 +77,22 @@
|
||||
New-HTMLText -FontSize 10pt -TextBlock {
|
||||
"When GPO is created one of the permissions that are required for proper functioning of Group Policies is NT AUTHORITY\Authenticated Users. "
|
||||
"Some Administrators don't follow best practices and trying to remove GpoApply permission, remove also GpoRead permission from a GPO which can have consequences. "
|
||||
}
|
||||
New-HTMLText -Text "On June 14th, 2016 Microsoft released [HotFix](https://support.microsoft.com/en-gb/help/3159398/ms16-072-description-of-the-security-update-for-group-policy-june-14-2) that requires Authenticated Users to be present on all Group Policies to function properly" -FontSize 10pt
|
||||
} -LineBreak
|
||||
New-HTMLText -Text "On June 14th, 2016 Microsoft released [HotFix](https://support.microsoft.com/en-gb/help/3159398/ms16-072-description-of-the-security-update-for-group-policy-june-14-2) that requires Authenticated Users to be present on all Group Policies to function properly: " -FontSize 10pt
|
||||
New-HTMLText -TextBlock {
|
||||
"MS16-072 changes the security context with which user group policies are retrieved. This by-design behavior change protects customers’ computers from a security vulnerability. Before MS16-072 is installed, user group policies were retrieved by using the user’s security context. After MS16-072 is installed, user group policies are retrieved by using the computer's security context."
|
||||
} -FontStyle italic -FontSize 10pt
|
||||
New-HTMLText -FontSize 10pt -Text "Following will need to happen: " -FontWeight bold
|
||||
"MS16-072 changes the security context with which user group policies are retrieved. "
|
||||
"This by-design behavior change protects customers’ computers from a security vulnerability. "
|
||||
"Before MS16-072 is installed, user group policies were retrieved by using the user’s security context. "
|
||||
"After MS16-072 is installed, user group policies are retrieved by using the computer's security context."
|
||||
} -FontStyle italic -FontSize 10pt -FontWeight bold -LineBreak
|
||||
New-HTMLText -FontSize 10pt -Text @(
|
||||
"There are two parts to this assesment. Reading all Group Policies Permissions that account ",
|
||||
$($Env:USERNAME.ToUpper()),
|
||||
" has permissions to read and provide detailed assesment about permissions. ",
|
||||
"Second assesment checks for permissions that this account is not able to read at all, and therefore it has no visibility about permissions set on it. "
|
||||
"We just were able to detect the problem, but hopefully higher level account (Domain Admin) should be able to provide full assesment. "
|
||||
) -FontWeight normal, bold, normal
|
||||
New-HTMLText -FontSize 10pt -Text "First assesment results: " -FontWeight bold
|
||||
New-HTMLList -Type Unordered {
|
||||
New-HTMLListItem -Text 'Group Policies requiring Authenticated Users with GpoRead permission: ', $Script:Reporting['GPOPermissionsRead']['Variables']['WillFix'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text "Group Policies which don't require changes: ", $Script:Reporting['GPOPermissionsRead']['Variables']['WillNotTouch'] -FontWeight normal, bold
|
||||
@@ -62,6 +103,18 @@
|
||||
New-HTMLListItem -Text "$Domain requires ", $Script:Reporting['GPOPermissionsRead']['Variables']['WillFixPerDomain'][$Domain], " changes." -FontWeight normal, bold, normal
|
||||
}
|
||||
} -FontSize 10pt
|
||||
New-HTMLText -FontSize 10pt -Text "Secondary assesment results: " -FontWeight bold
|
||||
New-HTMLList -Type Unordered {
|
||||
New-HTMLListItem -Text "Group Policies couldn't read at all: ", $Script:Reporting['GPOPermissionsRead']['Variables']['CouldNotRead'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text "Group Policies with permissions allowing read: ", $Script:Reporting['GPOPermissionsRead']['Variables']['Read'] -FontWeight normal, bold
|
||||
} -FontSize 10pt
|
||||
New-HTMLText -Text @(
|
||||
"That means we need to fix permissions on: "
|
||||
$($Script:Reporting['GPOPermissionsRead']['Variables']['TotalToFix'])
|
||||
" out of "
|
||||
$($Script:Reporting['GPOPermissionsRead']['Data'].Issues).Count
|
||||
" Group Policies. "
|
||||
) -FontSize 10pt -FontWeight bold, bold, normal, bold, normal -Color Black, FreeSpeechRed, Black, Black -LineBreak -TextDecoration none, underline, underline, underline, none
|
||||
}
|
||||
Solution = {
|
||||
New-HTMLSection -Invisible {
|
||||
@@ -72,14 +125,20 @@
|
||||
New-HTMLChart {
|
||||
New-ChartBarOptions -Type barStacked
|
||||
New-ChartLegend -Name 'Yes', 'No' -Color LightGreen, Salmon
|
||||
New-ChartBar -Name 'Authenticated Users' -Value $Script:Reporting['GPOPermissionsRead']['Variables']['WillNotTouch'], $Script:Reporting['GPOPermissionsRead']['Variables']['WillFix']
|
||||
New-ChartBar -Name 'Authenticated Users Available' -Value $Script:Reporting['GPOPermissionsRead']['Variables']['WillNotTouch'], $Script:Reporting['GPOPermissionsRead']['Variables']['WillFix']
|
||||
New-ChartBar -Name 'Accessible Group Policies' -Value $Script:Reporting['GPOPermissionsRead']['Variables']['Read'], $Script:Reporting['GPOPermissionsRead']['Variables']['CouldNotRead']
|
||||
} -Title 'Group Policy Permissions' -TitleAlignment center
|
||||
}
|
||||
}
|
||||
New-HTMLSection -Name 'Group Policy Authenticated Users' {
|
||||
New-HTMLTable -DataTable $Script:Reporting['GPOPermissionsRead']['Data'] -Filtering {
|
||||
New-HTMLSection -Name 'Group Policy Authenticated Users Analysis' {
|
||||
New-HTMLTable -DataTable $Script:Reporting['GPOPermissionsRead']['Data'].Permissions -Filtering {
|
||||
New-HTMLTableCondition -Name 'Permission' -Value '' -BackgroundColor Salmon -ComparisonType string -Row
|
||||
} -PagingOptions 10, 20, 30, 40, 50
|
||||
} -PagingOptions 7, 15, 30, 45, 60
|
||||
}
|
||||
New-HTMLSection -Name 'Group Policy Issues Assesment' {
|
||||
New-HTMLTable -DataTable $Script:Reporting['GPOPermissionsRead']['Data'].Issues -Filtering {
|
||||
New-HTMLTableCondition -Name 'PermissionIssue' -Value $true -BackgroundColor Salmon -ComparisonType string -Row
|
||||
} -PagingOptions 7, 15, 30, 45, 60 -DefaultSortColumn PermissionIssue -DefaultSortOrder Descending
|
||||
}
|
||||
New-HTMLSection -Name 'Steps to fix Group Policy Authenticated Users' {
|
||||
New-HTMLContainer {
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
Doesn't display GPOs that have no SYSVOL content (orphaned GPOs)
|
||||
|
||||
.PARAMETER Forest
|
||||
Target different Forest
|
||||
Target different Forest, by default current forest is used
|
||||
|
||||
.PARAMETER ExcludeDomains
|
||||
Exclude domain from search, by default whole forest is scanned
|
||||
|
||||
@@ -7,16 +7,16 @@
|
||||
Tries to find CPassword in Group Policies or given path and translate it to readable value
|
||||
|
||||
.PARAMETER Forest
|
||||
Specify forest name. By default current forest is used
|
||||
Target different Forest, by default current forest is used
|
||||
|
||||
.PARAMETER ExcludeDomains
|
||||
Exclude Domain or Domains
|
||||
Exclude domain from search, by default whole forest is scanned
|
||||
|
||||
.PARAMETER IncludeDomains
|
||||
Include only certain Domain or Domains
|
||||
Include only specific domains, by default whole forest is scanned
|
||||
|
||||
.PARAMETER ExtendedForestInformation
|
||||
Ability to provide extended forest information in advanced scenarios
|
||||
Ability to provide Forest Information from another command to speed up processing
|
||||
|
||||
.PARAMETER GPOPath
|
||||
Path where Group Policy content is located or where backup is located
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
function Get-GPOZaurrPermissionIssue {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Detects Group Policy missing Authenticated Users permission while not having higher permissions.
|
||||
|
||||
.DESCRIPTION
|
||||
Detects Group Policy missing Authenticated Users permission while not having higher permissions.
|
||||
|
||||
.PARAMETER Forest
|
||||
Target different Forest, by default current forest is used
|
||||
|
||||
.PARAMETER ExcludeDomains
|
||||
Exclude domain from search, by default whole forest is scanned
|
||||
|
||||
.PARAMETER IncludeDomains
|
||||
Include only specific domains, by default whole forest is scanned
|
||||
|
||||
.PARAMETER ExtendedForestInformation
|
||||
Ability to provide Forest Information from another command to speed up processing
|
||||
|
||||
.EXAMPLE
|
||||
$Issues = Get-GPOZaurrPermissionIssue
|
||||
$Issues | Format-Table
|
||||
|
||||
.NOTES
|
||||
General notes
|
||||
#>
|
||||
[cmdletBinding()]
|
||||
param(
|
||||
[alias('ForestName')][string] $Forest,
|
||||
[string[]] $ExcludeDomains,
|
||||
[alias('Domain', 'Domains')][string[]] $IncludeDomains,
|
||||
[System.Collections.IDictionary] $ExtendedForestInformation
|
||||
)
|
||||
$ForestInformation = Get-WinADForestDetails -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExcludeDomainControllers $ExcludeDomainControllers -IncludeDomainControllers $IncludeDomainControllers -SkipRODC:$SkipRODC -ExtendedForestInformation $ExtendedForestInformation -Extended
|
||||
foreach ($Domain in $ForestInformation.Domains) {
|
||||
$TimeLog = Start-TimeLog
|
||||
Write-Verbose "Get-GPOZaurrPermissionIssue - Starting process for $Domain"
|
||||
$QueryServer = $ForestInformation['QueryServers']["$Domain"].HostName[0]
|
||||
$SystemsContainer = $ForestInformation['DomainsExtended'][$Domain].SystemsContainer
|
||||
if ($SystemsContainer) {
|
||||
$PoliciesSearchBase = -join ("CN=Policies,", $SystemsContainer)
|
||||
$Properties = 'DisplayName', 'Name', 'DistinguishedName', 'ObjectClass', 'WhenCreated', 'WhenChanged'
|
||||
$PoliciesInAD = Get-ADObject -SearchBase $PoliciesSearchBase -SearchScope OneLevel -Filter * -Server $QueryServer -Properties $Properties
|
||||
foreach ($Policy in $PoliciesInAD) {
|
||||
$GUIDFromDN = ConvertFrom-DistinguishedName -DistinguishedName $Policy.DistinguishedName
|
||||
$GUIDFromDN = $GUIDFromDN -replace '{' -replace '}'
|
||||
$GUID = $Policy.Name -replace '{' -replace '}'
|
||||
[PSCustomObject] @{
|
||||
DisplayName = $Policy.DisplayName
|
||||
DomainName = $Domain
|
||||
PermissionIssue = -not ($GUID -and $GUIDFromDN)
|
||||
ObjectClass = $Policy.ObjectClass
|
||||
Name = $Policy.Name
|
||||
DistinguishedName = $Policy.DistinguishedName
|
||||
GUID = $GUIDFromDN
|
||||
WhenCreated = $Policy.WhenCreated
|
||||
WhenChanged = $Policy.WhenChanged
|
||||
}
|
||||
}
|
||||
}
|
||||
$TimeEnd = Stop-TimeLog -Time $TimeLog -Option OneLiner
|
||||
Write-Verbose "Get-GPOZaurrPermissionIssue - Finishing process for $Domain (Time to process: $TimeEnd)"
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,7 @@
|
||||
GUID of GPO. By default all GPOs are targetted
|
||||
|
||||
.PARAMETER Forest
|
||||
Target different Forest
|
||||
Target different Forest, by default current forest is used
|
||||
|
||||
.PARAMETER ExcludeDomains
|
||||
Exclude domain from search, by default whole forest is scanned
|
||||
|
||||
@@ -57,6 +57,13 @@ That's it. Whenever there's a new version, you run the command, and you can enjo
|
||||
|
||||
## Changelog
|
||||
|
||||
- 0.0.83 - 14.11.2020
|
||||
- [x] Improves `Invoke-GPOZaurr` (WIP)
|
||||
- [x] Fix for wrong ActionRequired count
|
||||
- 0.0.82 - 14.11.2020
|
||||
- [x] Added `Get-GPOZaurrPermissionIssue` to detect permission issue with no rights
|
||||
- [x] Improves `Invoke-GPOZaurr` (WIP)
|
||||
- [x] Type `GPOPermissionsRead` improved detection of problems with low permissions
|
||||
- 0.0.81 - 12.11.2020
|
||||
- [x] Fix for `Set-GPOZaurrOwner` in case of missing permissions to not throw errors
|
||||
- [x] Improves `Invoke-GPOZaurr` (WIP)
|
||||
|
||||
Reference in New Issue
Block a user