mirror of
https://github.com/EvotecIT/GPOZaurr.git
synced 2026-07-26 20:00:09 +00:00
Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0a863de36b | |||
| 31dd7e31a6 | |||
| 46a927b92d | |||
| 3e5c5fd6fb | |||
| 2a92c90b0c | |||
| 0f8fbb1220 | |||
| c37dd91403 | |||
| bc55cd09c5 | |||
| 2331e449b1 | |||
| d27760931e |
@@ -1,19 +0,0 @@
|
||||
#Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
|
||||
|
||||
Invoke-GPOZaurr -FilePath $PSScriptRoot\Reports\GPOZaurr.html -Verbose -Type NetLogon, GPOOrphans, GPOList, GPOConsistency
|
||||
|
||||
# Working conditions
|
||||
#Invoke-GPOZaurr -FilePath $PSScriptRoot\Reports\GPOZaurrOrphans.html -Verbose -Type GPOOrphans
|
||||
#Invoke-GPOZaurr -FilePath $PSScriptRoot\Reports\GPOZaurrEmptyUnlinked.html -Verbose -Type GPOList
|
||||
#Invoke-GPOZaurr -FilePath $PSScriptRoot\Reports\GPOZaurrEmptyUnlinked.html -Verbose -Type GPOConsistency
|
||||
#Invoke-GPOZaurr -FilePath $PSScriptRoot\Reports\GPOZaurr.html -Verbose -Type NetLogon
|
||||
|
||||
#Invoke-GPOZaurr -FilePath $PSScriptRoot\Reports\GPOZaurr.html -Verbose -Type GPOOwners
|
||||
|
||||
#Invoke-GPOZaurr -FilePath $PSScriptRoot\Reports\GPOZaurr.html -Verbose -Type GPOPermissionsRoot
|
||||
|
||||
#Invoke-GPOZaurr -FilePath $PSScriptRoot\Reports\GPOZaurr.html -Verbose -Type GPOOrphans, GPOConsistency, GPOList, GPOPermissionsRoot, NetLogon, GPOFiles
|
||||
#Invoke-GPOZaurr -FilePath $PSScriptRoot\Reports\GPOZaurr.html -Verbose -Type GPOConsistency
|
||||
#Invoke-GPOZaurr -FilePath $PSScriptRoot\Reports\GPOZaurr.html -Verbose -Type GPOOrphans, GPOConsistency
|
||||
#Invoke-GPOZaurr -FilePath $PSScriptRoot\Reports\GPOZaurr.html -Verbose -Type GPOList
|
||||
#Optimize-HTML -File 'C:\Support\GitHub\GpoZaurr\Examples\Reports\GPOZaurr.html' -OutputFile 'C:\Support\GitHub\GpoZaurr\Examples\Reports\GPOZaurr-Minified.html'
|
||||
@@ -0,0 +1,7 @@
|
||||
Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
|
||||
|
||||
$Output = Invoke-GPOZaurr -FilePath $PSScriptRoot\Reports\GPOZaurr.html -Type GPOPassword -PassThru
|
||||
$Output
|
||||
|
||||
Write-Color -Text 'Output of nested report' -Color DarkYellow -LinesBefore 1 -LinesAfter 1
|
||||
$Output.GPOPassword
|
||||
@@ -0,0 +1,3 @@
|
||||
Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
|
||||
|
||||
Invoke-GPOZaurr -FilePath $PSScriptRoot\Reports\GPOZaurr.html -Verbose -Type NetLogonPermissions, GPOOrphans, GPOList, GPOConsistency,GPOOwners
|
||||
@@ -1 +0,0 @@
|
||||
Invoke-GPOZaurr -FilePath $PSScriptRoot\Reports\GPOZaurr.html -Verbose -Type NetLogon, GPOOrphans, GPOList, GPOConsistency,GPOOwners
|
||||
@@ -0,0 +1,3 @@
|
||||
Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force
|
||||
|
||||
Get-GPOZaurrPassword -GPOPath 'C:\Users\przemyslaw.klys\Desktop\GPOExport_2020.10.12'
|
||||
+2
-2
@@ -8,7 +8,7 @@
|
||||
Description = 'Group Policy Eater is a PowerShell module that aims to gather information about Group Policies but also allows fixing issues that you may find in them.'
|
||||
FunctionsToExport = @('Add-GPOPermission', 'Add-GPOZaurrPermission', 'Backup-GPOZaurr', 'Clear-GPOZaurrSysvolDFSR', 'ConvertFrom-CSExtension', 'Find-CSExtension', 'Get-GPOZaurr', 'Get-GPOZaurrAD', 'Get-GPOZaurrBackupInformation', 'Get-GPOZaurrBroken', 'Get-GPOZaurrDictionary', 'Get-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', '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.72'
|
||||
ModuleVersion = '0.0.73'
|
||||
PowerShellVersion = '5.1'
|
||||
PrivateData = @{
|
||||
PSData = @{
|
||||
@@ -26,7 +26,7 @@
|
||||
ModuleName = 'ADEssentials'
|
||||
Guid = '9fc9fd61-7f11-4f4b-a527-084086f1905f'
|
||||
}, @{
|
||||
ModuleVersion = '0.0.119'
|
||||
ModuleVersion = '0.0.120'
|
||||
ModuleName = 'PSWriteHTML'
|
||||
Guid = 'a7bdf640-f5cb-4acf-9de0-365b322d245c'
|
||||
}, 'CimCmdlets', 'Microsoft.PowerShell.Management', 'Microsoft.PowerShell.Utility', 'Microsoft.PowerShell.Security')
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
function Export-GPOZaurr {
|
||||
[cmdletBinding()]
|
||||
param(
|
||||
|
||||
)
|
||||
$Output = [ordered] @{}
|
||||
foreach ($T in $Script:GPOConfiguration.Keys) {
|
||||
if ($Script:GPOConfiguration[$T].Enabled -eq $true) {
|
||||
$Output[$T] = [ordered]@{
|
||||
Action = $Script:GPOConfiguration[$T].Action
|
||||
Data = $Script:GPOConfiguration[$T].Data
|
||||
Name = $Script:GPOConfiguration[$T].Name
|
||||
Summary = $Script:GPOConfiguration[$T].Summary
|
||||
Variables = $Script:GPOConfiguration[$T].Variables
|
||||
}
|
||||
}
|
||||
}
|
||||
$Output
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
function Find-GPOPassword {
|
||||
[cmdletBinding()]
|
||||
param(
|
||||
[string] $Path
|
||||
)
|
||||
#Convert XML in a String file
|
||||
[string]$XMLString = Get-Content -LiteralPath $Path
|
||||
#Check if Cpassword Exist in the file
|
||||
if ($XMLString.Contains("cpassword")) {
|
||||
#Take the Cpassword Value from XML String file
|
||||
[string]$Cpassword = [regex]::matches($XMLString, '(cpassword=).+?(?=\")')
|
||||
$Cpassword = $Cpassword.split('(\")')[1]
|
||||
#Check if Cpassword has a value
|
||||
if ($Cpassword.Length -gt 20 -and $Cpassword -notlike '*cpassword*') {
|
||||
$Mod = ($Cpassword.length % 4)
|
||||
switch ($Mod) {
|
||||
'1' { $Cpassword = $Cpassword.Substring(0, $Cpassword.Length - 1) }
|
||||
'2' { $Cpassword += ('=' * (4 - $Mod)) }
|
||||
'3' { $Cpassword += ('=' * (4 - $Mod)) }
|
||||
}
|
||||
$Base64Decoded = [Convert]::FromBase64String($Cpassword)
|
||||
$AesObject = [System.Security.Cryptography.AesCryptoServiceProvider]::new()
|
||||
#Use th AES Key
|
||||
[Byte[]] $AesKey = @(0x4e, 0x99, 0x06, 0xe8, 0xfc, 0xb6, 0x6c, 0xc9, 0xfa, 0xf4, 0x93, 0x10, 0x62, 0x0f, 0xfe, 0xe8, 0xf4, 0x96, 0xe8, 0x06, 0xcc, 0x05, 0x79, 0x90, 0x20, 0x9b, 0x09, 0xa4, 0x33, 0xb6, 0x6c, 0x1b)
|
||||
$AesIV = New-Object Byte[]($AesObject.IV.Length)
|
||||
$AesObject.IV = $AesIV
|
||||
$AesObject.Key = $AesKey
|
||||
$DecryptorObject = $AesObject.CreateDecryptor()
|
||||
[Byte[]] $OutBlock = $DecryptorObject.TransformFinalBlock($Base64Decoded, 0, $Base64Decoded.length)
|
||||
#Convert Hash variable in a String valute
|
||||
$Password = [System.Text.UnicodeEncoding]::Unicode.GetString($OutBlock)
|
||||
} else {
|
||||
$Password = ''
|
||||
}
|
||||
}
|
||||
$Password
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
function Get-GitHubVersion {
|
||||
[cmdletBinding()]
|
||||
param(
|
||||
[Parameter(Mandatory)][string] $Cmdlet,
|
||||
[Parameter(Mandatory)][string] $RepositoryOwner,
|
||||
[Parameter(Mandatory)][string] $RepositoryName
|
||||
)
|
||||
$App = Get-Command -Name $Cmdlet -ErrorAction SilentlyContinue
|
||||
if ($App) {
|
||||
[Array] $GitHubReleases = (Get-GitHubLatestRelease -Url "https://api.github.com/repos/$RepositoryOwner/$RepositoryName/releases" -Verbose:$false)
|
||||
$LatestVersion = $GitHubReleases[0]
|
||||
if (-not $LatestVersion.Errors) {
|
||||
if ($App.Version -eq $LatestVersion.Version) {
|
||||
"Current/Latest: $($LatestVersion.Version) at $($LatestVersion.PublishDate)"
|
||||
} elseif ($App.Version -lt $LatestVersion.Version) {
|
||||
"Current: $($App.Version), Published: $($LatestVersion.Version) at $($LatestVersion.PublishDate). Update?"
|
||||
} elseif ($App.Version -gt $LatestVersion.Version) {
|
||||
"Current: $($App.Version), Published: $($LatestVersion.Version) at $($LatestVersion.PublishDate). Lucky you!"
|
||||
}
|
||||
} else {
|
||||
"Current: $($App.Version)"
|
||||
}
|
||||
}
|
||||
}
|
||||
+36
-2
@@ -54,6 +54,36 @@
|
||||
} elseif ($UserEnabled -eq $false -and $ComputerEnabled -eq $true) {
|
||||
$Enabled = 'User configuration settings disabled'
|
||||
}
|
||||
|
||||
$ComputerSettingsAvailable = if ($null -eq $XMLContent.GPO.Computer.ExtensionData) { $false } else { $true }
|
||||
$UserSettingsAvailable = if ($null -eq $XMLContent.GPO.User.ExtensionData) { $false } else { $true }
|
||||
|
||||
$ComputerProblem = $false
|
||||
if ($ComputerEnabled -eq $true -and $ComputerSettingsAvailable -eq $true) {
|
||||
$ComputerOptimized = $true
|
||||
} elseif ($ComputerEnabled -eq $true -and $ComputerSettingsAvailable -eq $false) {
|
||||
$ComputerOptimized = $false
|
||||
} elseif ($ComputerEnabled -eq $false -and $ComputerSettingsAvailable -eq $false) {
|
||||
$ComputerOptimized = $true
|
||||
} else {
|
||||
# Enabled $false, but ComputerData is there.
|
||||
$ComputerOptimized = $false
|
||||
$ComputerProblem = $true
|
||||
}
|
||||
|
||||
$UserProblem = $false
|
||||
if ($UserEnabled -eq $true -and $UserSettingsAvailable -eq $true) {
|
||||
$UserOptimized = $true
|
||||
} elseif ($UserEnabled -eq $true -and $UserSettingsAvailable -eq $false) {
|
||||
$UserOptimized = $false
|
||||
} elseif ($UserEnabled -eq $false -and $UserSettingsAvailable -eq $false) {
|
||||
$UserOptimized = $true
|
||||
} else {
|
||||
# Enabled $false, but UserData is there.
|
||||
$UserOptimized = $false
|
||||
$UserProblem = $true
|
||||
}
|
||||
|
||||
if (-not $PermissionsOnly) {
|
||||
if ($XMLContent.GPO.SecurityDescriptor.Owner.Name.'#text') {
|
||||
$AdministrativeGroup = $ADAdministrativeGroups['ByNetBIOS']["$($XMLContent.GPO.SecurityDescriptor.Owner.Name.'#text')"]
|
||||
@@ -123,9 +153,13 @@
|
||||
'LinksDisabledCount' = $LinksDisabledCount
|
||||
'Enabled' = $Enabled
|
||||
'ComputerEnabled' = $ComputerEnabled
|
||||
'ComputerOptimized' = $ComputerOptimized
|
||||
'ComputerProblem' = $ComputerProblem
|
||||
'UserEnabled' = $UserEnabled
|
||||
'ComputerSettingsAvailable' = if ($null -eq $XMLContent.GPO.Computer.ExtensionData) { $false } else { $true }
|
||||
'UserSettingsAvailable' = if ($null -eq $XMLContent.GPO.User.ExtensionData) { $false } else { $true }
|
||||
'UserOptimized' = $UserOptimized
|
||||
'UserProblem' = $UserProblem
|
||||
'ComputerSettingsAvailable' = $ComputerSettingsAvailable
|
||||
'UserSettingsAvailable' = $UserSettingsAvailable
|
||||
'ComputerSettingsStatus' = if ($XMLContent.GPO.Computer.VersionDirectory -eq 0 -and $XMLContent.GPO.Computer.VersionSysvol -eq 0) { "NeverModified" } else { "Modified" }
|
||||
'ComputerSetttingsVersionIdentical' = if ($XMLContent.GPO.Computer.VersionDirectory -eq $XMLContent.GPO.Computer.VersionSysvol) { $true } else { $false }
|
||||
'ComputerSettings' = $XMLContent.GPO.Computer.ExtensionData.Extension
|
||||
|
||||
@@ -1,24 +1,32 @@
|
||||
$GPOZaurrAnalysis = [ordered] @{
|
||||
Name = 'Group Policy Content'
|
||||
Enabled = $true
|
||||
Action = $null
|
||||
Data = $null
|
||||
Execute = {
|
||||
Name = 'Group Policy Content'
|
||||
Enabled = $true
|
||||
ActionRequired = $null
|
||||
Data = $null
|
||||
Execute = {
|
||||
Invoke-GPOZaurrContent
|
||||
}
|
||||
Processing = {
|
||||
Processing = {
|
||||
|
||||
}
|
||||
Variables = @{
|
||||
Variables = @{
|
||||
|
||||
}
|
||||
Overview = {
|
||||
Overview = {
|
||||
|
||||
}
|
||||
Solution = {
|
||||
foreach ($Key in $GPOZaurrAnalysis['Data'].Keys) {
|
||||
Solution = {
|
||||
foreach ($Key in $Script:Reporting['GPOAnalysis']['Data'].Keys) {
|
||||
New-HTMLTab -Name $Key {
|
||||
New-HTMLTable -DataTable $GPOZaurrAnalysis['Data'][$Key] -Filtering -Title $Key
|
||||
New-HTMLTable -DataTable $Script:Reporting['GPOAnalysis']['Data'][$Key] -Filtering -Title $Key
|
||||
}
|
||||
}
|
||||
if ($Script:Reporting['GPOAnalysis']['WarningsAndErrors']) {
|
||||
New-HTMLSection -Name 'Warnings & Errors to Review' {
|
||||
New-HTMLTable -DataTable $Script:Reporting['GPOAnalysis']['WarningsAndErrors'] -Filtering {
|
||||
New-HTMLTableCondition -Name 'Type' -Value 'Warning' -BackgroundColor SandyBrown -ComparisonType string -Row
|
||||
New-HTMLTableCondition -Name 'Type' -Value 'Error' -BackgroundColor Salmon -ComparisonType string -Row
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
$GPOZaurrBlockedInheritance = [ordered] @{
|
||||
Name = 'Group Policy Blocked Inhertiance'
|
||||
Enabled = $true
|
||||
ActionRequired = $null
|
||||
Data = $null
|
||||
Execute = {
|
||||
Get-GPOZaurrInheritance -IncludeBlockedObjects -OnlyBlockedInheritance
|
||||
}
|
||||
Processing = {
|
||||
|
||||
}
|
||||
Variables = @{
|
||||
|
||||
}
|
||||
Overview = {
|
||||
|
||||
}
|
||||
Solution = {
|
||||
New-HTMLTable -DataTable $Script:Reporting['GPOBlockedInheritance']['Data'] -Filtering
|
||||
if ($Script:Reporting['GPOBlockedInheritance']['WarningsAndErrors']) {
|
||||
New-HTMLSection -Name 'Warnings & Errors to Review' {
|
||||
New-HTMLTable -DataTable $Script:Reporting['GPOBlockedInheritance']['WarningsAndErrors'] -Filtering {
|
||||
New-HTMLTableCondition -Name 'Type' -Value 'Warning' -BackgroundColor SandyBrown -ComparisonType string -Row
|
||||
New-HTMLTableCondition -Name 'Type' -Value 'Error' -BackgroundColor Salmon -ComparisonType string -Row
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,54 +1,54 @@
|
||||
$GPOZaurrConsistency = [ordered] @{
|
||||
Name = 'GPO Permissions Consistency'
|
||||
Enabled = $true
|
||||
Action = $null
|
||||
Data = $null
|
||||
Execute = { Get-GPOZaurrPermissionConsistency -Type All -VerifyInheritance }
|
||||
Processing = {
|
||||
foreach ($GPO in $GPOZaurrConsistency['Data']) {
|
||||
Name = 'GPO Permissions Consistency'
|
||||
Enabled = $true
|
||||
ActionRequired = $null
|
||||
Data = $null
|
||||
Execute = { Get-GPOZaurrPermissionConsistency -Type All -VerifyInheritance }
|
||||
Processing = {
|
||||
foreach ($GPO in $Script:Reporting['GPOConsistency']['Data']) {
|
||||
if ($GPO.ACLConsistent -eq $true) {
|
||||
$GPOZaurrConsistency['Variables']['Consistent']++
|
||||
$Script:Reporting['GPOConsistency']['Variables']['Consistent']++
|
||||
} else {
|
||||
$GPOZaurrConsistency['Variables']['Inconsistent']++
|
||||
$Script:Reporting['GPOConsistency']['Variables']['Inconsistent']++
|
||||
}
|
||||
if ($GPO.ACLConsistentInside -eq $true) {
|
||||
$GPOZaurrConsistency['Variables']['ConsistentInside']++
|
||||
$Script:Reporting['GPOConsistency']['Variables']['ConsistentInside']++
|
||||
} else {
|
||||
$GPOZaurrConsistency['Variables']['InconsistentInside']++
|
||||
$Script:Reporting['GPOConsistency']['Variables']['InconsistentInside']++
|
||||
}
|
||||
}
|
||||
if ($GPOZaurrConsistency['Variables']['Inconsistent'].Count -gt 0 -or $GPOZaurrConsistency['Variables']['InconsistentInside'].Count -gt 0 ) {
|
||||
$GPOZaurrConsistency['Action'] = $true
|
||||
if ($Script:Reporting['GPOConsistency']['Variables']['Inconsistent'].Count -gt 0 -or $Script:Reporting['GPOConsistency']['Variables']['InconsistentInside'].Count -gt 0 ) {
|
||||
$Script:Reporting['GPOConsistency']['ActionRequired'] = $true
|
||||
} else {
|
||||
$GPOZaurrConsistency['Action'] = $false
|
||||
$Script:Reporting['GPOConsistency']['ActionRequired'] = $false
|
||||
}
|
||||
}
|
||||
Variables = @{
|
||||
Variables = @{
|
||||
Consistent = 0
|
||||
Inconsistent = 0
|
||||
ConsistentInside = 0
|
||||
InconsistentInside = 0
|
||||
}
|
||||
Overview = {
|
||||
Overview = {
|
||||
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: ', $GPOZaurrConsistency['Variables']['Consistent'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text 'Inherited permissions consistency: ', $GPOZaurrConsistency['Variables']['ConsistentInside'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text 'Inconsistent top level permissions: ', $GPOZaurrConsistency['Variables']['Inconsistent'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text "Inconsistent inherited permissions: ", $GPOZaurrConsistency['Variables']['InconsistentInside'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text 'Top level permissions consistency: ', $Script:Reporting['GPOConsistency']['Variables']['Consistent'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text 'Inherited permissions consistency: ', $Script:Reporting['GPOConsistency']['Variables']['ConsistentInside'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text 'Inconsistent top level permissions: ', $Script:Reporting['GPOConsistency']['Variables']['Inconsistent'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text "Inconsistent inherited permissions: ", $Script:Reporting['GPOConsistency']['Variables']['InconsistentInside'] -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 $GPOZaurrConsistency['Variables']['Consistent'], $GPOZaurrConsistency['Variables']['Inconsistent']
|
||||
New-ChartBar -Name 'Inherited' -Value $GPOZaurrConsistency['Variables']['ConsistentInside'], $GPOZaurrConsistency['Variables']['InconsistentInside']
|
||||
New-ChartBar -Name 'TopLevel' -Value $Script:Reporting['GPOConsistency']['Variables']['Consistent'], $Script:Reporting['GPOConsistency']['Variables']['Inconsistent']
|
||||
New-ChartBar -Name 'Inherited' -Value $Script:Reporting['GPOConsistency']['Variables']['ConsistentInside'], $Script:Reporting['GPOConsistency']['Variables']['InconsistentInside']
|
||||
} -Title 'Permissions Consistency' -TitleAlignment center
|
||||
}
|
||||
}
|
||||
Summary = {
|
||||
Summary = {
|
||||
New-HTMLText -FontSize 10pt -TextBlock {
|
||||
"When GPO is created it creates an entry in Active Directory (metadata) and SYSVOL (content). "
|
||||
"Two different places meens two different sets of permissions. Group Policy module is making sure the data in both places is correct. "
|
||||
@@ -58,31 +58,31 @@
|
||||
}
|
||||
New-HTMLText -Text 'Following list 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: ', $GPOZaurrConsistency['Variables']['Consistent'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text 'Inherited permissions consistency: ', $GPOZaurrConsistency['Variables']['ConsistentInside'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text 'Inconsistent top level permissions: ', $GPOZaurrConsistency['Variables']['Inconsistent'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text "Inconsistent inherited permissions: ", $GPOZaurrConsistency['Variables']['InconsistentInside'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text 'Top level permissions consistency: ', $Script:Reporting['GPOConsistency']['Variables']['Consistent'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text 'Inherited permissions consistency: ', $Script:Reporting['GPOConsistency']['Variables']['ConsistentInside'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text 'Inconsistent top level permissions: ', $Script:Reporting['GPOConsistency']['Variables']['Inconsistent'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text "Inconsistent inherited permissions: ", $Script:Reporting['GPOConsistency']['Variables']['InconsistentInside'] -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
|
||||
}
|
||||
Solution = {
|
||||
Solution = {
|
||||
New-HTMLSection -Invisible {
|
||||
New-HTMLPanel {
|
||||
& $GPOZaurrConsistency['Summary']
|
||||
& $Script:GPOConfiguration['GPOConsistency']['Summary']
|
||||
}
|
||||
New-HTMLPanel {
|
||||
New-HTMLChart {
|
||||
New-ChartLegend -Names 'Bad', 'Good' -Color PaleGreen, Salmon
|
||||
# New-ChartLegend -Names 'Bad', 'Good' -Color PaleGreen, Salmon
|
||||
New-ChartBarOptions -Type barStacked
|
||||
New-ChartLegend -Name 'Consistent', 'Inconsistent'
|
||||
New-ChartBar -Name 'TopLevel' -Value $GPOZaurrConsistency['Variables']['Consistent'], $GPOZaurrConsistency['Variables']['Inconsistent']
|
||||
New-ChartBar -Name 'Inherited' -Value $GPOZaurrConsistency['Variables']['ConsistentInside'], $GPOZaurrConsistency['Variables']['InconsistentInside']
|
||||
New-ChartBar -Name 'TopLevel' -Value $Script:Reporting['GPOConsistency']['Variables']['Consistent'], $Script:Reporting['GPOConsistency']['Variables']['Inconsistent']
|
||||
New-ChartBar -Name 'Inherited' -Value $Script:Reporting['GPOConsistency']['Variables']['ConsistentInside'], $Script:Reporting['GPOConsistency']['Variables']['InconsistentInside']
|
||||
} -Title 'Permissions Consistency' -TitleAlignment center
|
||||
}
|
||||
}
|
||||
New-HTMLSection -Name 'Group Policy Permissions Consistency' {
|
||||
New-HTMLTable -DataTable $GPOZaurrConsistency['Data'] -Filtering {
|
||||
New-HTMLTable -DataTable $Script:Reporting['GPOConsistency']['Data'] -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
|
||||
@@ -91,6 +91,14 @@
|
||||
New-HTMLTableCondition -Name 'ACLConsistentInside' -Value 'Not available' -BackgroundColor Crimson -ComparisonType string
|
||||
} -PagingOptions 10, 20, 30, 40, 50
|
||||
}
|
||||
if ($Script:Reporting['GPOConsistency']['WarningsAndErrors']) {
|
||||
New-HTMLSection -Name 'Warnings & Errors to Review' {
|
||||
New-HTMLTable -DataTable $Script:Reporting['GPOConsistency']['WarningsAndErrors'] -Filtering {
|
||||
New-HTMLTableCondition -Name 'Type' -Value 'Warning' -BackgroundColor SandyBrown -ComparisonType string -Row
|
||||
New-HTMLTableCondition -Name 'Type' -Value 'Error' -BackgroundColor Salmon -ComparisonType string -Row
|
||||
}
|
||||
}
|
||||
}
|
||||
New-HTMLSection -Name 'Steps to fix - Permissions Consistency' {
|
||||
New-HTMLContainer {
|
||||
New-HTMLSpanStyle -FontSize 10pt {
|
||||
@@ -151,7 +159,7 @@
|
||||
New-HTMLCodeBlock -Code {
|
||||
Invoke-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
|
||||
New-HTMLText -Text "If everything is healthy in the report you're done! Enjoy rest of the day!" -Color BlueDiamond
|
||||
}
|
||||
} -RemoveDoneStepOnNavigateBack -Theme arrows -ToolbarButtonPosition center
|
||||
}
|
||||
|
||||
@@ -7,15 +7,116 @@
|
||||
Get-GPOZaurrDuplicateObject
|
||||
}
|
||||
Processing = {
|
||||
|
||||
$Script:Reporting['GPODuplicates']['Variables']['RequireDeletion'] = $Script:Reporting['GPODuplicates']['Data'].Count
|
||||
if ($Script:Reporting['GPODuplicates']['Data'].Count -gt 0) {
|
||||
$Script:Reporting['GPODuplicates']['ActionRequired'] = $true
|
||||
} else {
|
||||
$Script:Reporting['GPODuplicates']['ActionRequired'] = $false
|
||||
}
|
||||
}
|
||||
Variables = @{
|
||||
|
||||
RequireDeletion = 0
|
||||
}
|
||||
Overview = {
|
||||
|
||||
}
|
||||
Resources = @(
|
||||
'https://social.technet.microsoft.com/wiki/contents/articles/15435.active-directory-duplicate-object-name-resolution.aspx'
|
||||
'https://kickthatcomputer.wordpress.com/2014/11/22/seek-and-destroy-duplicate-ad-objects-with-cnf-in-the-name/'
|
||||
)
|
||||
Summary = {
|
||||
New-HTMLText -FontSize 10pt -TextBlock {
|
||||
"CNF objects, Conflict objects or Duplicate Objects are created in Active Directory when there is simultaneous creation of an AD object under the same container "
|
||||
"on two separate Domain Controllers near about the same time or before the replication occurs. "
|
||||
"This results in a conflict and the same is exhibited by a CNF (Duplicate) object. "
|
||||
"While it doesn't nessecary has a huge impact on Active Directory it's important to keep Active Directory in proper, healthy state. "
|
||||
}
|
||||
New-HTMLText -Text 'As it stands currently there are ', $Script:Reporting['GPODuplicates']['Data'].Count, ' CNF (Duplicate) Group Policy objects to be deleted.' -FontSize 10pt -FontWeight normal, bold, normal
|
||||
}
|
||||
Solution = {
|
||||
New-HTMLTable -DataTable $GPOZaurrDuplicates['Data'] -Filtering
|
||||
New-HTMLSection -Invisible {
|
||||
New-HTMLPanel {
|
||||
& $Script:GPOConfiguration['GPODuplicates']['Summary']
|
||||
}
|
||||
New-HTMLPanel {
|
||||
New-HTMLChart {
|
||||
New-ChartLegend -Names 'Bad' -Color PaleGreen, Salmon
|
||||
New-ChartBar -Name 'Duplicate (CNF) object' -Value $Script:Reporting['GPODuplicates']['Data'].Count
|
||||
} -Title 'Duplicate (CNF) Objects' -TitleAlignment center
|
||||
}
|
||||
}
|
||||
New-HTMLSection -Name 'Group Policy CNF (Duplicate) Objects' {
|
||||
New-HTMLTable -DataTable $Script:Reporting['GPODuplicates']['Data'] -Filtering {
|
||||
|
||||
} -PagingOptions 10, 20, 30, 40, 50
|
||||
}
|
||||
if ($Script:Reporting['GPODuplicates']['WarningsAndErrors']) {
|
||||
New-HTMLSection -Name 'Warnings & Errors to Review' {
|
||||
New-HTMLTable -DataTable $Script:Reporting['GPODuplicates']['WarningsAndErrors'] -Filtering {
|
||||
New-HTMLTableCondition -Name 'Type' -Value 'Warning' -BackgroundColor SandyBrown -ComparisonType string -Row
|
||||
New-HTMLTableCondition -Name 'Type' -Value 'Error' -BackgroundColor Salmon -ComparisonType string -Row
|
||||
}
|
||||
}
|
||||
}
|
||||
New-HTMLSection -Name 'Steps to fix - Remove duplicate (CNF) objects' {
|
||||
New-HTMLContainer {
|
||||
New-HTMLSpanStyle -FontSize 10pt {
|
||||
New-HTMLText -Text 'Following steps will guide you how to remove duplicate objects'
|
||||
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 duplicate GPO objects. To generate new report please use:"
|
||||
New-HTMLCodeBlock -Code {
|
||||
Invoke-GPOZaurr -FilePath $Env:UserProfile\Desktop\GPOZaurrDuplicateObjectsBefore.html -Verbose -Type GPODuplicates
|
||||
}
|
||||
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-GPOZaurrDuplicateObject
|
||||
$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 'Remove CNF objects' {
|
||||
New-HTMLText -Text "Following command when executed, runs internally command that lists all duplicate objects."
|
||||
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-GPOZaurrDuplicateObject -WhatIf -Verbose
|
||||
}
|
||||
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 changed matches expected data. Once happy with results please follow with command: "
|
||||
}
|
||||
New-HTMLCodeBlock -Code {
|
||||
Remove-GPOZaurrDuplicateObject -Verbose -LimitProcessing 2
|
||||
}
|
||||
New-HTMLText -TextBlock {
|
||||
"This command when executed removes only first X duplicate objects. 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-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 {
|
||||
Invoke-GPOZaurr -FilePath $Env:UserProfile\Desktop\GPOZaurrDuplicateObjectsAfter.html -Verbose -Type GPODuplicates
|
||||
}
|
||||
New-HTMLText -Text "If everything is healthy in the report you're done! Enjoy rest of the day!" -Color BlueDiamond
|
||||
}
|
||||
} -RemoveDoneStepOnNavigateBack -Theme arrows -ToolbarButtonPosition center
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,21 +1,29 @@
|
||||
$GPOZaurrFiles = [ordered] @{
|
||||
Name = 'SYSVOL (NetLogon) Files List'
|
||||
Enabled = $true
|
||||
Action = $null
|
||||
Data = $null
|
||||
Execute = {
|
||||
Name = 'SYSVOL (NetLogon) Files List'
|
||||
Enabled = $true
|
||||
ActionRequired = $null
|
||||
Data = $null
|
||||
Execute = {
|
||||
Get-GPOZaurrFiles
|
||||
}
|
||||
Processing = {
|
||||
Processing = {
|
||||
|
||||
}
|
||||
Variables = @{
|
||||
Variables = @{
|
||||
|
||||
}
|
||||
Overview = {
|
||||
Overview = {
|
||||
|
||||
}
|
||||
Solution = {
|
||||
New-HTMLTable -DataTable $GPOZaurrFiles['Data'] -Filtering
|
||||
Solution = {
|
||||
New-HTMLTable -DataTable $Script:Reporting['GPOFiles']['Data'] -Filtering
|
||||
if ($Script:Reporting['GPOFiles']['WarningsAndErrors']) {
|
||||
New-HTMLSection -Name 'Warnings & Errors to Review' {
|
||||
New-HTMLTable -DataTable $Script:Reporting['GPOFiles']['WarningsAndErrors'] -Filtering {
|
||||
New-HTMLTableCondition -Name 'Type' -Value 'Warning' -BackgroundColor SandyBrown -ComparisonType string -Row
|
||||
New-HTMLTableCondition -Name 'Type' -Value 'Error' -BackgroundColor Salmon -ComparisonType string -Row
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+152
-65
@@ -1,5 +1,5 @@
|
||||
$GPOZaurrList = [ordered] @{
|
||||
Name = 'Group Policy Empty & Unlinked'
|
||||
Name = 'Group Policy Summary'
|
||||
Enabled = $true
|
||||
Action = $null
|
||||
Data = $null
|
||||
@@ -7,42 +7,80 @@
|
||||
Get-GPOZaurr
|
||||
}
|
||||
Processing = {
|
||||
foreach ($GPO in $GPOZaurrList['Data']) {
|
||||
foreach ($GPO in $Script:Reporting['GPOList']['Data']) {
|
||||
if ($GPO.Linked -eq $false -and $GPO.Empty -eq $true) {
|
||||
# Not linked, Empty
|
||||
$GPOZaurrList['Variables']['GPOEmptyAndUnlinked']++
|
||||
$GPOZaurrList['Variables']['GPOEmptyOrUnlinked']++
|
||||
$GPOZaurrList['Variables']['GPONotLinked']++
|
||||
$GPOZaurrList['Variables']['GPOEmpty']++
|
||||
$Script:Reporting['GPOList']['Variables']['GPOEmptyAndUnlinked']++
|
||||
$Script:Reporting['GPOList']['Variables']['GPOEmptyOrUnlinked']++
|
||||
$Script:Reporting['GPOList']['Variables']['GPONotLinked']++
|
||||
$Script:Reporting['GPOList']['Variables']['GPOEmpty']++
|
||||
} elseif ($GPO.Linked -eq $true -and $GPO.Empty -eq $true) {
|
||||
# Linked, But EMPTY
|
||||
$GPOZaurrList['Variables']['GPOLinkedButEmpty']++
|
||||
$GPOZaurrList['Variables']['GPOEmptyOrUnlinked']++
|
||||
$GPOZaurrList['Variables']['GPOEmpty']++
|
||||
$GPOZaurrList['Variables']['GPOLinked']++
|
||||
$Script:Reporting['GPOList']['Variables']['GPOLinkedButEmpty']++
|
||||
$Script:Reporting['GPOList']['Variables']['GPOEmptyOrUnlinked']++
|
||||
$Script:Reporting['GPOList']['Variables']['GPOEmpty']++
|
||||
$Script:Reporting['GPOList']['Variables']['GPOLinked']++
|
||||
} elseif ($GPO.Linked -eq $false) {
|
||||
# Not linked, but not EMPTY
|
||||
$GPOZaurrList['Variables']['GPONotLinked']++
|
||||
$GPOZaurrList['Variables']['GPOEmptyOrUnlinked']++
|
||||
$GPOZaurrList['Variables']['GPONotEmpty']++
|
||||
$Script:Reporting['GPOList']['Variables']['GPONotLinked']++
|
||||
$Script:Reporting['GPOList']['Variables']['GPOEmptyOrUnlinked']++
|
||||
$Script:Reporting['GPOList']['Variables']['GPONotEmpty']++
|
||||
} elseif ($GPO.Empty -eq $true) {
|
||||
# Linked, But EMPTY
|
||||
$GPOZaurrList['Variables']['GPOEmpty']++
|
||||
$GPOZaurrList['Variables']['GPOEmptyOrUnlinked']++
|
||||
$GPOZaurrList['Variables']['GPOLinked']++
|
||||
$Script:Reporting['GPOList']['Variables']['GPOEmpty']++
|
||||
$Script:Reporting['GPOList']['Variables']['GPOEmptyOrUnlinked']++
|
||||
$Script:Reporting['GPOList']['Variables']['GPOLinked']++
|
||||
} else {
|
||||
# Linked, not EMPTY
|
||||
$GPOZaurrList['Variables']['GPOValid']++
|
||||
$GPOZaurrList['Variables']['GPOLinked']++
|
||||
$GPOZaurrList['Variables']['GPONotEmpty']++
|
||||
$Script:Reporting['GPOList']['Variables']['GPOValid']++
|
||||
$Script:Reporting['GPOList']['Variables']['GPOLinked']++
|
||||
$Script:Reporting['GPOList']['Variables']['GPONotEmpty']++
|
||||
}
|
||||
if ($GPO.LinksDisabledCount -eq $GPO.LinksCount -and $GPO.LinksCount -gt 0) {
|
||||
$GPOZaurrList['Variables']['GPOLinkedButLinkDisabled']++
|
||||
$Script:Reporting['GPOList']['Variables']['GPOLinkedButLinkDisabled']++
|
||||
}
|
||||
|
||||
if ($GPO.ComputerOptimized -eq $true) {
|
||||
$Script:Reporting['GPOList']['Variables']['ComputerOptimizedYes']++
|
||||
} else {
|
||||
$Script:Reporting['GPOList']['Variables']['ComputerOptimizedNo']++
|
||||
}
|
||||
if ($GPO.ComputerProblem -eq $true) {
|
||||
$Script:Reporting['GPOList']['Variables']['ComputerProblemYes']++
|
||||
} else {
|
||||
$Script:Reporting['GPOList']['Variables']['ComputerProblemNo']++
|
||||
}
|
||||
if ($GPO.UserOptimized -eq $true) {
|
||||
$Script:Reporting['GPOList']['Variables']['UserOptimizedYes']++
|
||||
} else {
|
||||
$Script:Reporting['GPOList']['Variables']['UserOptimizedNo']++
|
||||
}
|
||||
if ($GPO.UserProblem -eq $true) {
|
||||
$Script:Reporting['GPOList']['Variables']['UserProblemYes']++
|
||||
} else {
|
||||
$Script:Reporting['GPOList']['Variables']['UserProblemNo']++
|
||||
}
|
||||
if ($GPO.UserProblem -or $GPO.ComputerProblem) {
|
||||
$Script:Reporting['GPOList']['Variables']['GPOWithProblems']++
|
||||
}
|
||||
}
|
||||
$GPOZaurrList['Variables']['GPOTotal'] = $GPOZaurrList['Data'].Count
|
||||
$Script:Reporting['GPOList']['Variables']['GPOTotal'] = $Script:Reporting['GPOList']['Data'].Count
|
||||
if ($Script:Reporting['GPOList']['Variables']['GPOEmptyOrUnlinked'].Count -gt 0) {
|
||||
$Script:Reporting['GPOList']['ActionRequired'] = $true
|
||||
} else {
|
||||
$Script:Reporting['GPOList']['ActionRequired'] = $false
|
||||
}
|
||||
}
|
||||
Variables = [ordered] @{
|
||||
Variables = @{
|
||||
GPOWithProblems = 0
|
||||
ComputerOptimizedYes = 0
|
||||
ComputerOptimizedNo = 0
|
||||
ComputerProblemYes = 0
|
||||
ComputerProblemNo = 0
|
||||
UserOptimizedYes = 0
|
||||
UserOptimizedNo = 0
|
||||
UserProblemYes = 0
|
||||
UserProblemNo = 0
|
||||
GPONotLinked = 0
|
||||
GPOLinked = 0
|
||||
GPOEmpty = 0
|
||||
@@ -58,73 +96,122 @@
|
||||
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: ', $GPOZaurrList['Variables']['GPOTotal'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text "Group Policies valid: ", $GPOZaurrList['Variables']['GPOValid'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text "Group Policies to delete: ", $GPOZaurrList['Variables']['GPOEmptyOrUnlinked'] -FontWeight normal, bold {
|
||||
New-HTMLListItem -Text 'Group Policies total: ', $Script:Reporting['GPOList']['Variables']['GPOTotal'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text "Group Policies valid: ", $Script:Reporting['GPOList']['Variables']['GPOValid'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text "Group Policies to delete: ", $Script:Reporting['GPOList']['Variables']['GPOEmptyOrUnlinked'] -FontWeight normal, bold {
|
||||
New-HTMLList -Type Unordered {
|
||||
New-HTMLListItem -Text 'Group Policies that are unlinked (are not doing anything currently): ', $GPOZaurrList['Variables']['GPONotLinked'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text "Group Policies that are empty (have no settings): ", $GPOZaurrList['Variables']['GPOEmpty'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text "Group Policies that are linked, but empty: ", $GPOZaurrList['Variables']['GPOLinkedButEmpty'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text "Group Policies that are linked, but link disabled: ", $GPOZaurrList['Variables']['GPOLinkedButLinkDisabled'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text 'Group Policies that are unlinked (are not doing anything currently): ', $Script:Reporting['GPOList']['Variables']['GPONotLinked'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text "Group Policies that are empty (have no settings): ", $Script:Reporting['GPOList']['Variables']['GPOEmpty'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text "Group Policies that are linked, but empty: ", $Script:Reporting['GPOList']['Variables']['GPOLinkedButEmpty'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text "Group Policies that are linked, but link disabled: ", $Script:Reporting['GPOList']['Variables']['GPOLinkedButLinkDisabled'] -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 $GPOZaurrList['Variables']['GPONotLinked'], $GPOZaurrList['Variables']['GPOLinked'], $GPOZaurrList['Variables']['GPOEmpty'], $GPOZaurrList['Variables']['GPOTotal']
|
||||
New-ChartBar -Name 'Linked' -Value $GPOZaurrList['Variables']['GPOLinked'], $GPOZaurrList['Variables']['GPONotLinked']
|
||||
New-ChartBar -Name 'Empty' -Value $GPOZaurrList['Variables']['GPONotEmpty'], $GPOZaurrList['Variables']['GPOEmpty']
|
||||
New-ChartBar -Name 'Valid' -Value $GPOZaurrList['Variables']['GPOValid'], $GPOZaurrList['Variables']['GPOEmptyOrUnlinked']
|
||||
#New-ChartBar -Name 'Group Policies' -Value $Script:Reporting['GPOList']['Variables']['GPONotLinked'], $Script:Reporting['GPOList']['Variables']['GPOLinked'], $Script:Reporting['GPOList']['Variables']['GPOEmpty'], $Script:Reporting['GPOList']['Variables']['GPOTotal']
|
||||
New-ChartBar -Name 'Linked' -Value $Script:Reporting['GPOList']['Variables']['GPOLinked'], $Script:Reporting['GPOList']['Variables']['GPONotLinked']
|
||||
New-ChartBar -Name 'Empty' -Value $Script:Reporting['GPOList']['Variables']['GPONotEmpty'], $Script:Reporting['GPOList']['Variables']['GPOEmpty']
|
||||
New-ChartBar -Name 'Valid' -Value $Script:Reporting['GPOList']['Variables']['GPOValid'], $Script:Reporting['GPOList']['Variables']['GPOEmptyOrUnlinked']
|
||||
} -TitleAlignment center
|
||||
}
|
||||
}
|
||||
Summary = {
|
||||
New-HTMLText -TextBlock {
|
||||
"Over time Administrators add more and more group policies, as business requirements change. "
|
||||
"Due to neglection or thinking it may serve it's purpose later on a lot of Group Policies often have no value at all. "
|
||||
"Either the Group Policy is not linked to anything and just stays unlinked forever, or GPO is linked, but the link (links) are disabled. "
|
||||
"Additionally sometimes new GPO is created without any settings or the settings are removed over time, but GPO stays in place. "
|
||||
} -FontSize 10pt
|
||||
New-HTMLList -Type Unordered {
|
||||
New-HTMLListItem -Text 'Group Policies total: ', $Script:Reporting['GPOList']['Variables']['GPOTotal'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text "Group Policies valid: ", $Script:Reporting['GPOList']['Variables']['GPOValid'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text "Group Policies to delete: ", $Script:Reporting['GPOList']['Variables']['GPOEmptyOrUnlinked'] -FontWeight normal, bold {
|
||||
New-HTMLList -Type Unordered {
|
||||
New-HTMLListItem -Text 'Group Policies that are unlinked (are not doing anything currently): ', $Script:Reporting['GPOList']['Variables']['GPONotLinked'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text "Group Policies that are empty (have no settings): ", $Script:Reporting['GPOList']['Variables']['GPOEmpty'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text "Group Policies that are linked, but empty: ", $Script:Reporting['GPOList']['Variables']['GPOLinkedButEmpty'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text "Group Policies that are linked, but link disabled: ", $Script:Reporting['GPOList']['Variables']['GPOLinkedButLinkDisabled'] -FontWeight normal, bold
|
||||
}
|
||||
}
|
||||
} -FontSize 10pt
|
||||
New-HTMLText -Text "Additionally, we're reviewing Group Policies that have their section disabled, but contain data. Please review them and make sure this configuration is as expected!" -FontSize 10pt
|
||||
New-HTMLList -Type Unordered {
|
||||
New-HTMLListItem -Text 'Group Policies with problems: ', $Script:Reporting['GPOList']['Variables']['GPOWithProblems'] -FontWeight normal, bold {
|
||||
New-HTMLList -Type Unordered {
|
||||
New-HTMLListItem -Text 'Group Policies that have content (computer), but are disabled: ', $Script:Reporting['GPOList']['Variables']['ComputerProblemYes'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text "Group Policies that have content (user), but are disabled: ", $Script:Reporting['GPOList']['Variables']['UserProblemYes'] -FontWeight normal, bold
|
||||
}
|
||||
}
|
||||
} -FontSize 10pt
|
||||
New-HTMLText -Text "For best performance it's recommended that if there are no settings of certain kind (Computer or User settings) it's best to disable them. " -FontSize 10pt
|
||||
New-HTMLList -Type Unordered {
|
||||
New-HTMLListItem -Text 'Group Policies with optimization: ' -FontWeight normal, bold {
|
||||
New-HTMLList -Type Unordered {
|
||||
New-HTMLListItem -Text 'Group Policies that are optimized (computer) ', $Script:Reporting['GPOList']['Variables']['ComputerOptimizedYes'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text "Group Policies that are optimized (user): ", $Script:Reporting['GPOList']['Variables']['UserOptimizedYes'] -FontWeight normal, bold
|
||||
}
|
||||
}
|
||||
New-HTMLListItem -Text 'Group Policies without optimization: ' -FontWeight normal, bold {
|
||||
New-HTMLList -Type Unordered {
|
||||
New-HTMLListItem -Text 'Group Policies that are not optimized (computer): ', $Script:Reporting['GPOList']['Variables']['ComputerOptimizedNo'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text "Group Policies that are not optimized (user): ", $Script:Reporting['GPOList']['Variables']['UserOptimizedNo'] -FontWeight normal, bold
|
||||
}
|
||||
}
|
||||
} -FontSize 10pt
|
||||
New-HTMLText -TextBlock {
|
||||
'All empty or unlinked Group Policies can be automatically deleted. Please review output in the table and follow steps below table to cleanup Group Policies. '
|
||||
'GPOs that have content, but are disabled require manual intervention. '
|
||||
"If performance is an issue you should consider disabling user or computer sections of GPO when those are not used. "
|
||||
} -FontSize 10pt
|
||||
}
|
||||
Solution = {
|
||||
New-HTMLSection -Invisible {
|
||||
New-HTMLPanel {
|
||||
$newHTMLTextSplat = @{
|
||||
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 or linked, but link disabled.'
|
||||
)
|
||||
FontSize = '10pt'
|
||||
FontWeight = 'normal', 'bold'
|
||||
}
|
||||
New-HTMLText @newHTMLTextSplat
|
||||
New-HTMLList -Type Unordered {
|
||||
New-HTMLListItem -Text 'Group Policies total: ', $GPOZaurrList['Variables']['GPOTotal'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text "Group Policies valid: ", $GPOZaurrList['Variables']['GPOValid'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text "Group Policies to delete: ", $GPOZaurrList['Variables']['GPOEmptyOrUnlinked'] -FontWeight normal, bold {
|
||||
New-HTMLList -Type Unordered {
|
||||
New-HTMLListItem -Text 'Group Policies that are unlinked (are not doing anything currently): ', $GPOZaurrList['Variables']['GPONotLinked'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text "Group Policies that are empty (have no settings): ", $GPOZaurrList['Variables']['GPOEmpty'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text "Group Policies that are linked, but empty: ", $GPOZaurrList['Variables']['GPOLinkedButEmpty'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text "Group Policies that are linked, but link disabled: ", $GPOZaurrList['Variables']['GPOLinkedButLinkDisabled'] -FontWeight normal, bold
|
||||
}
|
||||
}
|
||||
} -FontSize 10pt
|
||||
New-HTMLText -Text 'All those mentioned Group Policies can be automatically deleted following the steps below the table.' -FontSize 10pt
|
||||
& $Script:GPOConfiguration['GPOList']['Summary']
|
||||
}
|
||||
New-HTMLPanel {
|
||||
New-HTMLChart -Title 'Group Policies Empty & Unlinked' {
|
||||
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 $GPOZaurrList['Variables']['GPONotLinked'], $GPOZaurrList['Variables']['GPOLinked'], $GPOZaurrList['Variables']['GPOEmpty'], $GPOZaurrList['Variables']['GPOTotal']
|
||||
New-ChartBar -Name 'Linked' -Value $GPOZaurrList['Variables']['GPOLinked'], $GPOZaurrList['Variables']['GPONotLinked']
|
||||
New-ChartBar -Name 'Empty' -Value $GPOZaurrList['Variables']['GPONotEmpty'], $GPOZaurrList['Variables']['GPOEmpty']
|
||||
New-ChartBar -Name 'Valid' -Value $GPOZaurrList['Variables']['GPOValid'], $GPOZaurrList['Variables']['GPOEmptyOrUnlinked']
|
||||
New-ChartLegend -Names 'Yes', 'No' -Color SpringGreen, Salmon
|
||||
New-ChartBar -Name 'Linked' -Value $Script:Reporting['GPOList']['Variables']['GPOLinked'], $Script:Reporting['GPOList']['Variables']['GPONotLinked']
|
||||
New-ChartBar -Name 'Empty' -Value $Script:Reporting['GPOList']['Variables']['GPONotEmpty'], $Script:Reporting['GPOList']['Variables']['GPOEmpty']
|
||||
New-ChartBar -Name 'Valid' -Value $Script:Reporting['GPOList']['Variables']['GPOValid'], $Script:Reporting['GPOList']['Variables']['GPOEmptyOrUnlinked']
|
||||
New-ChartBar -Name 'With problem (computers)' -Value $Script:Reporting['GPOList']['Variables']['ComputerProblemNo'], $Script:Reporting['GPOList']['Variables']['ComputerProblemYes']
|
||||
New-ChartBar -Name 'With problem (users)' -Value $Script:Reporting['GPOList']['Variables']['UserProblemNo'], $Script:Reporting['GPOList']['Variables']['UserProblemYes']
|
||||
New-ChartBar -Name 'Optimized Computers' -Value $Script:Reporting['GPOList']['Variables']['ComputerOptimizedYes'], $Script:Reporting['GPOList']['Variables']['ComputerOptimizedNo']
|
||||
New-ChartBar -Name 'Optimized Users' -Value $Script:Reporting['GPOList']['Variables']['UserOptimizedYes'], $Script:Reporting['GPOList']['Variables']['UserOptimizedNo']
|
||||
} -TitleAlignment center
|
||||
}
|
||||
}
|
||||
New-HTMLSection -Name 'Group Policies List' {
|
||||
New-HTMLTable -DataTable $GPOZaurrList['Data'] -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
|
||||
New-HTMLTable -DataTable $Script:Reporting['GPOList']['Data'] -Filtering {
|
||||
New-HTMLTableCondition -Name 'Empty' -Value $true -BackgroundColor Salmon -ComparisonType string
|
||||
New-HTMLTableCondition -Name 'Linked' -Value $false -BackgroundColor Salmon -ComparisonType string
|
||||
New-HTMLTableCondition -Name 'ComputerProblem' -Value $true -BackgroundColor Salmon -ComparisonType string
|
||||
New-HTMLTableCondition -Name 'UserProblem' -Value $true -BackgroundColor Salmon -ComparisonType string
|
||||
New-HTMLTableCondition -Name 'ComputerOptimized' -Value $false -BackgroundColor Salmon -ComparisonType string
|
||||
New-HTMLTableCondition -Name 'UserOptimized' -Value $false -BackgroundColor Salmon -TextTransform capitalize -ComparisonType string
|
||||
# reverse
|
||||
New-HTMLTableCondition -Name 'Empty' -Value $false -BackgroundColor SpringGreen -ComparisonType string
|
||||
New-HTMLTableCondition -Name 'Linked' -Value $true -BackgroundColor SpringGreen -ComparisonType string
|
||||
New-HTMLTableCondition -Name 'ComputerProblem' -Value $false -BackgroundColor SpringGreen -ComparisonType string
|
||||
New-HTMLTableCondition -Name 'UserProblem' -Value $false -BackgroundColor SpringGreen -ComparisonType string
|
||||
New-HTMLTableCondition -Name 'ComputerOptimized' -Value $true -BackgroundColor SpringGreen -ComparisonType string
|
||||
New-HTMLTableCondition -Name 'UserOptimized' -Value $true -BackgroundColor SpringGreen -TextTransform capitalize -ComparisonType string
|
||||
} -PagingOptions 10, 20, 30, 40, 50
|
||||
}
|
||||
if ($Script:Reporting['GPOList']['WarningsAndErrors']) {
|
||||
New-HTMLSection -Name 'Warnings & Errors to Review' {
|
||||
New-HTMLTable -DataTable $Script:Reporting['GPOList']['WarningsAndErrors'] -Filtering {
|
||||
New-HTMLTableCondition -Name 'Type' -Value 'Warning' -BackgroundColor SandyBrown -ComparisonType string -Row
|
||||
New-HTMLTableCondition -Name 'Type' -Value 'Error' -BackgroundColor Salmon -ComparisonType string -Row
|
||||
}
|
||||
}
|
||||
}
|
||||
New-HTMLSection -Name 'Steps to fix - Empty & Unlinked Group Policies' {
|
||||
New-HTMLContainer {
|
||||
New-HTMLSpanStyle -FontSize 10pt {
|
||||
|
||||
@@ -1,42 +1,42 @@
|
||||
$GPOZaurrNetLogonPermissions = [ordered] @{
|
||||
Name = 'NetLogon Permissions'
|
||||
Enabled = $true
|
||||
Action = $null
|
||||
Data = $null
|
||||
Execute = {
|
||||
Name = 'NetLogon Permissions'
|
||||
Enabled = $true
|
||||
ActionRequired = $null
|
||||
Data = $null
|
||||
Execute = {
|
||||
Get-GPOZaurrNetLogon
|
||||
}
|
||||
Processing = {
|
||||
foreach ($File in $GPOZaurrNetLogonPermissions['Data']) {
|
||||
Processing = {
|
||||
foreach ($File in $Script:Reporting['NetLogonPermissions']['Data']) {
|
||||
if ($File.FileSystemRights -eq 'Owner') {
|
||||
$GPOZaurrNetLogonPermissions['Variables']['NetLogonOwners']++
|
||||
$Script:Reporting['NetLogonPermissions']['Variables']['NetLogonOwners']++
|
||||
if ($File.PrincipalType -eq 'WellKnownAdministrative') {
|
||||
$GPOZaurrNetLogonPermissions['Variables']['NetLogonOwnersAdministrative']++
|
||||
$Script:Reporting['NetLogonPermissions']['Variables']['NetLogonOwnersAdministrative']++
|
||||
} elseif ($File.PrincipalType -eq 'Administrative') {
|
||||
$GPOZaurrNetLogonPermissions['Variables']['NetLogonOwnersAdministrative']++
|
||||
$Script:Reporting['NetLogonPermissions']['Variables']['NetLogonOwnersAdministrative']++
|
||||
} else {
|
||||
$GPOZaurrNetLogonPermissions['Variables']['NetLogonOwnersNotAdministrative']++
|
||||
$Script:Reporting['NetLogonPermissions']['Variables']['NetLogonOwnersNotAdministrative']++
|
||||
}
|
||||
if ($File.PrincipalSid -eq 'S-1-5-32-544') {
|
||||
$GPOZaurrNetLogonPermissions['Variables']['NetLogonOwnersAdministrators']++
|
||||
$Script:Reporting['NetLogonPermissions']['Variables']['NetLogonOwnersAdministrators']++
|
||||
} elseif ($File.PrincipalType -in 'WellKnownAdministrative', 'Administrative') {
|
||||
$GPOZaurrNetLogonPermissions['Variables']['NetLogonOwnersAdministrativeNotAdministrators']++
|
||||
$GPOZaurrNetLogonPermissions['Variables']['NetLogonOwnersToFix']++
|
||||
$Script:Reporting['NetLogonPermissions']['Variables']['NetLogonOwnersAdministrativeNotAdministrators']++
|
||||
$Script:Reporting['NetLogonPermissions']['Variables']['NetLogonOwnersToFix']++
|
||||
} else {
|
||||
$GPOZaurrNetLogonPermissions['Variables']['NetLogonOwnersToFix']++
|
||||
$Script:Reporting['NetLogonPermissions']['Variables']['NetLogonOwnersToFix']++
|
||||
}
|
||||
$GPOZaurrNetLogonPermissions['Variables']['Owner'].Add($File)
|
||||
$Script:Reporting['NetLogonPermissions']['Variables']['Owner'].Add($File)
|
||||
} else {
|
||||
$GPOZaurrNetLogonPermissions['Variables']['NonOwner'].Add($File)
|
||||
$Script:Reporting['NetLogonPermissions']['Variables']['NonOwner'].Add($File)
|
||||
}
|
||||
}
|
||||
if ($GPOZaurrNetLogonPermissions['Variables']['NetLogonOwnersToFix'].Count -gt 0) {
|
||||
$GPOZaurrNetLogonPermissions['Action'] = $true
|
||||
if ($Script:Reporting['NetLogonPermissions']['Variables']['NetLogonOwnersToFix'].Count -gt 0) {
|
||||
$Script:Reporting['NetLogonPermissions']['ActionRequired'] = $true
|
||||
} else {
|
||||
$GPOZaurrNetLogonPermissions['Action'] = $false
|
||||
$Script:Reporting['NetLogonPermissions']['ActionRequired'] = $false
|
||||
}
|
||||
}
|
||||
Variables = @{
|
||||
Variables = @{
|
||||
NetLogonOwners = 0
|
||||
NetLogonOwnersAdministrators = 0
|
||||
NetLogonOwnersNotAdministrative = 0
|
||||
@@ -46,30 +46,30 @@
|
||||
Owner = [System.Collections.Generic.List[PSCustomObject]]::new()
|
||||
NonOwner = [System.Collections.Generic.List[PSCustomObject]]::new()
|
||||
}
|
||||
Overview = {
|
||||
Overview = {
|
||||
New-HTMLPanel {
|
||||
New-HTMLText -Text 'Following chart presents ', 'NetLogon Summary' -FontSize 10pt -FontWeight normal, bold
|
||||
New-HTMLList -Type Unordered {
|
||||
New-HTMLListItem -Text 'NetLogon Files in Total: ', $GPOZaurrNetLogonPermissions['Variables']['NetLogonOwners'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text 'NetLogon BUILTIN\Administrators as Owner: ', $GPOZaurrNetLogonPermissions['Variables']['NetLogonOwnersAdministrators'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text "NetLogon Owners requiring change: ", $GPOZaurrNetLogonPermissions['Variables']['NetLogonOwnersToFix'] -FontWeight normal, bold {
|
||||
New-HTMLListItem -Text 'NetLogon Files in Total: ', $Script:Reporting['NetLogonPermissions']['Variables']['NetLogonOwners'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text 'NetLogon BUILTIN\Administrators as Owner: ', $Script:Reporting['NetLogonPermissions']['Variables']['NetLogonOwnersAdministrators'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text "NetLogon Owners requiring change: ", $Script:Reporting['NetLogonPermissions']['Variables']['NetLogonOwnersToFix'] -FontWeight normal, bold {
|
||||
New-HTMLList -Type Unordered {
|
||||
New-HTMLListItem -Text 'Not Administrative: ', $GPOZaurrNetLogonPermissions['Variables']['NetLogonOwnersNotAdministrative'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text 'Administrative, but not BUILTIN\Administrators: ', $GPOZaurrNetLogonPermissions['Variables']['NetLogonOwnersAdministrativeNotAdministrators'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text 'Not Administrative: ', $Script:Reporting['NetLogonPermissions']['Variables']['NetLogonOwnersNotAdministrative'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text 'Administrative, but not BUILTIN\Administrators: ', $Script:Reporting['NetLogonPermissions']['Variables']['NetLogonOwnersAdministrativeNotAdministrators'] -FontWeight normal, bold
|
||||
}
|
||||
}
|
||||
} -FontSize 10pt
|
||||
#New-HTMLText -FontSize 10pt -Text 'Those problems must be resolved before doing other clenaup activities.'
|
||||
New-HTMLChart {
|
||||
New-ChartPie -Name 'Correct Owners' -Value $GPOZaurrNetLogonPermissions['Variables']['NetLogonOwnersAdministrators'] -Color LightGreen
|
||||
New-ChartPie -Name 'Incorrect Owners' -Value $GPOZaurrNetLogonPermissions['Variables']['NetLogonOwnersToFix'] -Color Crimson
|
||||
New-ChartPie -Name 'Correct Owners' -Value $Script:Reporting['NetLogonPermissions']['Variables']['NetLogonOwnersAdministrators'] -Color LightGreen
|
||||
New-ChartPie -Name 'Incorrect Owners' -Value $Script:Reporting['NetLogonPermissions']['Variables']['NetLogonOwnersToFix'] -Color Crimson
|
||||
} -Title 'NetLogon Owners' -TitleAlignment center
|
||||
}
|
||||
New-HTMLPanel {
|
||||
|
||||
}
|
||||
}
|
||||
Solution = {
|
||||
Solution = {
|
||||
New-HTMLTab -Name 'NetLogon Owners' {
|
||||
New-HTMLSection -Invisible {
|
||||
New-HTMLPanel {
|
||||
@@ -79,12 +79,12 @@
|
||||
"That's why as a best-practice it's recommended to change any non-administrative owners to BUILTIN\Administrators, and even Administrative accounts should be replaced with it. "
|
||||
} -FontSize 10pt
|
||||
New-HTMLList -Type Unordered {
|
||||
New-HTMLListItem -Text 'NetLogon Files in Total: ', $GPOZaurrNetLogonPermissions['Variables']['NetLogonOwners'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text 'NetLogon BUILTIN\Administrators as Owner: ', $GPOZaurrNetLogonPermissions['Variables']['NetLogonOwnersAdministrators'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text "NetLogon Owners requiring change: ", $GPOZaurrNetLogonPermissions['Variables']['NetLogonOwnersToFix'] -FontWeight normal, bold {
|
||||
New-HTMLListItem -Text 'NetLogon Files in Total: ', $Script:Reporting['NetLogonPermissions']['Variables']['NetLogonOwners'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text 'NetLogon BUILTIN\Administrators as Owner: ', $Script:Reporting['NetLogonPermissions']['Variables']['NetLogonOwnersAdministrators'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text "NetLogon Owners requiring change: ", $Script:Reporting['NetLogonPermissions']['Variables']['NetLogonOwnersToFix'] -FontWeight normal, bold {
|
||||
New-HTMLList -Type Unordered {
|
||||
New-HTMLListItem -Text 'Not Administrative: ', $GPOZaurrNetLogonPermissions['Variables']['NetLogonOwnersNotAdministrative'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text 'Administrative, but not BUILTIN\Administrators: ', $GPOZaurrNetLogonPermissions['Variables']['NetLogonOwnersAdministrativeNotAdministrators'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text 'Not Administrative: ', $Script:Reporting['NetLogonPermissions']['Variables']['NetLogonOwnersNotAdministrative'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text 'Administrative, but not BUILTIN\Administrators: ', $Script:Reporting['NetLogonPermissions']['Variables']['NetLogonOwnersAdministrativeNotAdministrators'] -FontWeight normal, bold
|
||||
}
|
||||
}
|
||||
} -FontSize 10pt
|
||||
@@ -92,18 +92,26 @@
|
||||
}
|
||||
New-HTMLPanel {
|
||||
New-HTMLChart {
|
||||
New-ChartPie -Name 'Correct Owners' -Value $GPOZaurrNetLogonPermissions['Variables']['NetLogonOwnersAdministrators'] -Color LightGreen
|
||||
New-ChartPie -Name 'Incorrect Owners' -Value $GPOZaurrNetLogonPermissions['Variables']['NetLogonOwnersToFix'] -Color Crimson
|
||||
New-ChartPie -Name 'Correct Owners' -Value $Script:Reporting['NetLogonPermissions']['Variables']['NetLogonOwnersAdministrators'] -Color LightGreen
|
||||
New-ChartPie -Name 'Incorrect Owners' -Value $Script:Reporting['NetLogonPermissions']['Variables']['NetLogonOwnersToFix'] -Color Crimson
|
||||
} -Title 'NetLogon Owners' -TitleAlignment center
|
||||
}
|
||||
}
|
||||
New-HTMLSection -Name 'NetLogon Files List' {
|
||||
New-HTMLTable -DataTable $GPOZaurrNetLogonPermissions['Variables']['Owner'] -Filtering {
|
||||
New-HTMLTable -DataTable $Script:Reporting['NetLogonPermissions']['Variables']['Owner'] -Filtering {
|
||||
New-HTMLTableCondition -Name 'PrincipalSid' -Value "S-1-5-32-544" -BackgroundColor LightGreen -ComparisonType string
|
||||
New-HTMLTableCondition -Name 'PrincipalSid' -Value "S-1-5-32-544" -BackgroundColor Salmon -ComparisonType string -Operator ne
|
||||
New-HTMLTableCondition -Name 'PrincipalType' -Value "WellKnownAdministrative" -BackgroundColor LightGreen -ComparisonType string -Operator eq
|
||||
}
|
||||
}
|
||||
if ($Script:Reporting['NetLogonPermissions']['WarningsAndErrors']) {
|
||||
New-HTMLSection -Name 'Warnings & Errors to Review' {
|
||||
New-HTMLTable -DataTable $Script:Reporting['NetLogonPermissions']['WarningsAndErrors'] -Filtering {
|
||||
New-HTMLTableCondition -Name 'Type' -Value 'Warning' -BackgroundColor SandyBrown -ComparisonType string -Row
|
||||
New-HTMLTableCondition -Name 'Type' -Value 'Error' -BackgroundColor Salmon -ComparisonType string -Row
|
||||
}
|
||||
}
|
||||
}
|
||||
New-HTMLSection -Name 'Steps to fix NetLogon Owners ' {
|
||||
New-HTMLContainer {
|
||||
New-HTMLSpanStyle -FontSize 10pt {
|
||||
@@ -167,7 +175,7 @@
|
||||
}
|
||||
New-HTMLTab -Name 'NetLogon Permissions' {
|
||||
New-HTMLSection -Name 'NetLogon Files List' {
|
||||
New-HTMLTable -DataTable $GPOZaurrNetLogonPermissions['Variables']['NonOwner'] -Filtering
|
||||
New-HTMLTable -DataTable $Script:Reporting['NetLogonPermissions']['Variables']['NonOwner'] -Filtering
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,34 +1,36 @@
|
||||
$GPOZaurrOrphans = [ordered] @{
|
||||
Name = 'Orphaned Group Policies'
|
||||
Enabled = $true
|
||||
Action = $null
|
||||
Data = $null
|
||||
Execute = {
|
||||
Name = 'Orphaned Group Policies'
|
||||
Enabled = $true
|
||||
ActionRequired = $null
|
||||
Data = $null
|
||||
Execute = {
|
||||
Get-GPOZaurrBroken
|
||||
}
|
||||
Processing = {
|
||||
#$NotAvailableInAD = [System.Collections.Generic.List[PSCustomObject]]::new()
|
||||
#$NotAvailableOnSysvol = [System.Collections.Generic.List[PSCustomObject]]::new()
|
||||
#$NotAvailablePermissionIssue = [System.Collections.Generic.List[PSCustomObject]]::new()
|
||||
foreach ($GPO in $GPOZaurrOrphans['Data']) {
|
||||
Processing = {
|
||||
foreach ($GPO in $Script:Reporting['GPOOrphans']['Data']) {
|
||||
if ($GPO.Status -eq 'Not available in AD') {
|
||||
#$NotAvailableInAD.Add($NotAvailableInAD)
|
||||
$GPOZaurrOrphans['Variables']['NotAvailableInAD']++
|
||||
$Script:Reporting['GPOOrphans']['Variables']['NotAvailableInAD']++
|
||||
$Script:Reporting['GPOOrphans']['Variables']['ToBeDeleted']++
|
||||
} elseif ($GPO.Status -eq 'Not available on SYSVOL') {
|
||||
#$NotAvailableOnSysvol.Add($NotAvailableInAD)
|
||||
$GPOZaurrOrphans['Variables']['NotAvailableOnSysvol']++
|
||||
$Script:Reporting['GPOOrphans']['Variables']['NotAvailableOnSysvol']++
|
||||
$Script:Reporting['GPOOrphans']['Variables']['ToBeDeleted']++
|
||||
} elseif ($GPO.Status -eq 'Permissions issue') {
|
||||
#$NotAvailablePermissionIssue.Add($NotAvailableInAD)
|
||||
$GPOZaurrOrphans['Variables']['NotAvailablePermissionIssue']++
|
||||
$Script:Reporting['GPOOrphans']['Variables']['NotAvailablePermissionIssue']++
|
||||
}
|
||||
}
|
||||
if ($Script:Reporting['GPOOrphans']['Variables']['ToBeDeleted'].Count -gt 0) {
|
||||
$Script:Reporting['GPOOrphans']['ActionRequired'] = $true
|
||||
} else {
|
||||
$Script:Reporting['GPOOrphans']['ActionRequired'] = $false
|
||||
}
|
||||
}
|
||||
Variables = @{
|
||||
Variables = @{
|
||||
NotAvailableInAD = 0
|
||||
NotAvailableOnSysvol = 0
|
||||
NotAvailablePermissionIssue = 0
|
||||
ToBeDeleted = 0
|
||||
}
|
||||
Overview = {
|
||||
Overview = {
|
||||
New-HTMLPanel {
|
||||
New-HTMLText -TextBlock {
|
||||
"Group Policies are stored in two places - Active Directory (metadata) and SYSVOL (content)."
|
||||
@@ -42,58 +44,66 @@
|
||||
}
|
||||
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: ', $GPOZaurrOrphans['Variables']['NotAvailableInAD'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text 'Group Policies in AD, but no content on SYSVOL: ', $GPOZaurrOrphans['Variables']['NotAvailableOnSysvol'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text "Group Policies which couldn't be assed due to permissions issue: ", $GPOZaurrOrphans['Variables']['NotAvailablePermissionIssue'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text 'Group Policies on SYSVOL, but no details in AD: ', $Script:Reporting['GPOOrphans']['Variables']['NotAvailableInAD'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text 'Group Policies in AD, but no content on SYSVOL: ', $Script:Reporting['GPOOrphans']['Variables']['NotAvailableOnSysvol'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text "Group Policies which couldn't be assed due to permissions issue: ", $Script:Reporting['GPOOrphans']['Variables']['NotAvailablePermissionIssue'] -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 $GPOZaurrOrphans['Variables']['NotAvailableInAD'], $GPOZaurrOrphans['Variables']['NotAvailableOnSysvol'], $GPOZaurrOrphans['Variables']['NotAvailablePermissionIssue']
|
||||
New-ChartBar -Name 'Orphans' -Value $Script:Reporting['GPOOrphans']['Variables']['NotAvailableInAD'], $Script:Reporting['GPOOrphans']['Variables']['NotAvailableOnSysvol'], $Script:Reporting['GPOOrphans']['Variables']['NotAvailablePermissionIssue']
|
||||
} -Title 'Broken / Orphaned Group Policies' -TitleAlignment center
|
||||
}
|
||||
}
|
||||
Summary = {
|
||||
New-HTMLPanel {
|
||||
New-HTMLText -TextBlock {
|
||||
"Group Policies are stored in two places - Active Directory (metadata) and SYSVOL (content)."
|
||||
"Since those are managed in different ways, replicated in different ways it's possible because of different issues they get out of sync."
|
||||
} -FontSize 10pt
|
||||
New-HTMLText -Text "For example:" -FontSize 10pt -FontWeight bold
|
||||
New-HTMLList -Type Unordered {
|
||||
New-HTMLListItem -Text 'USN Rollback in AD could cause already deleted Group Policies to reapper in Active Directory, yet SYSVOL data would be unavailable'
|
||||
New-HTMLListItem -Text 'Group Policy deletion failing to delete GPO content'
|
||||
New-HTMLListItem -Text 'Permission issue preventing deletion of GPO content'
|
||||
New-HTMLListItem -Text 'Failing DFSR replication between DCs'
|
||||
} -FontSize 10pt
|
||||
New-HTMLText -Text 'Following problems were detected:' -FontSize 10pt -FontWeight bold
|
||||
New-HTMLList -Type Unordered {
|
||||
New-HTMLListItem -Text 'Group Policies on SYSVOL, but no details in AD: ', $GPOZaurrOrphans['Variables']['NotAvailableInAD'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text 'Group Policies in AD, but no content on SYSVOL: ', $GPOZaurrOrphans['Variables']['NotAvailableOnSysvol'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text "Group Policies which couldn't be assed due to permissions issue: ", $GPOZaurrOrphans['Variables']['NotAvailablePermissionIssue'] -FontWeight normal, bold
|
||||
} -FontSize 10pt
|
||||
New-HTMLText -Text "Please review output in table and follow the steps below table to get Active Directory Group Policies in healthy state." -FontSize 10pt
|
||||
}
|
||||
Summary = {
|
||||
New-HTMLText -TextBlock {
|
||||
"Group Policies are stored in two places - Active Directory (metadata) and SYSVOL (content)."
|
||||
"Since those are managed in different ways, replicated in different ways it's possible because of different issues they get out of sync."
|
||||
} -FontSize 10pt
|
||||
New-HTMLText -Text "For example:" -FontSize 10pt -FontWeight bold
|
||||
New-HTMLList -Type Unordered {
|
||||
New-HTMLListItem -Text 'USN Rollback in AD could cause already deleted Group Policies to reapper in Active Directory, yet SYSVOL data would be unavailable'
|
||||
New-HTMLListItem -Text 'Group Policy deletion failing to delete GPO content'
|
||||
New-HTMLListItem -Text 'Permission issue preventing deletion of GPO content'
|
||||
New-HTMLListItem -Text 'Failing DFSR replication between DCs'
|
||||
} -FontSize 10pt
|
||||
New-HTMLText -Text 'Following problems were detected:' -FontSize 10pt -FontWeight bold
|
||||
New-HTMLList -Type Unordered {
|
||||
New-HTMLListItem -Text 'Group Policies on SYSVOL, but no details in AD: ', $Script:Reporting['GPOOrphans']['Variables']['NotAvailableInAD'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text 'Group Policies in AD, but no content on SYSVOL: ', $Script:Reporting['GPOOrphans']['Variables']['NotAvailableOnSysvol'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text "Group Policies which couldn't be assed due to permissions issue: ", $Script:Reporting['GPOOrphans']['Variables']['NotAvailablePermissionIssue'] -FontWeight normal, bold
|
||||
} -FontSize 10pt
|
||||
New-HTMLText -Text "Please review output in table and follow the steps below table to get Active Directory Group Policies in healthy state." -FontSize 10pt
|
||||
}
|
||||
Solution = {
|
||||
Solution = {
|
||||
New-HTMLSection -Invisible {
|
||||
& $GPOZaurrOrphans['Summary']
|
||||
New-HTMLPanel {
|
||||
& $Script:GPOConfiguration['GPOOrphans']['Summary']
|
||||
}
|
||||
New-HTMLPanel {
|
||||
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 $GPOZaurrOrphans['Variables']['NotAvailableInAD'], $GPOZaurrOrphans['Variables']['NotAvailableOnSysvol'], $GPOZaurrOrphans['Variables']['NotAvailablePermissionIssue']
|
||||
New-ChartBar -Name 'Orphans' -Value $Script:Reporting['GPOOrphans']['Variables']['NotAvailableInAD'], $Script:Reporting['GPOOrphans']['Variables']['NotAvailableOnSysvol'], $Script:Reporting['GPOOrphans']['Variables']['NotAvailablePermissionIssue']
|
||||
} -Title 'Broken / Orphaned Group Policies' -TitleAlignment center
|
||||
}
|
||||
}
|
||||
New-HTMLSection -Name 'Health State of Group Policies' {
|
||||
New-HTMLTable -DataTable $GPOZaurrOrphans['Data'] -Filtering {
|
||||
New-HTMLTable -DataTable $Script:Reporting['GPOOrphans']['Data'] -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
|
||||
}
|
||||
if ($Script:Reporting['GPOOrphans']['WarningsAndErrors']) {
|
||||
New-HTMLSection -Name 'Warnings & Errors to Review' {
|
||||
New-HTMLTable -DataTable $Script:Reporting['GPOOrphans']['WarningsAndErrors'] -Filtering {
|
||||
New-HTMLTableCondition -Name 'Type' -Value 'Warning' -BackgroundColor SandyBrown -ComparisonType string -Row
|
||||
New-HTMLTableCondition -Name 'Type' -Value 'Error' -BackgroundColor Salmon -ComparisonType string -Row
|
||||
}
|
||||
}
|
||||
}
|
||||
New-HTMLSection -Name 'Steps to fix - Not available on SYSVOL / Active Directory' {
|
||||
New-HTMLContainer {
|
||||
New-HTMLSpanStyle -FontSize 10pt {
|
||||
|
||||
@@ -1,31 +1,36 @@
|
||||
$GPOZaurrOwners = [ordered] @{
|
||||
Name = 'Group Policy Owners'
|
||||
Enabled = $true
|
||||
Action = $null
|
||||
Data = $null
|
||||
Execute = { Get-GPOZaurrOwner -IncludeSysvol }
|
||||
Processing = {
|
||||
foreach ($GPO in $GpoZaurrOwners['Data']) {
|
||||
Name = 'Group Policy Owners'
|
||||
Enabled = $true
|
||||
ActionRequired = $null
|
||||
Data = $null
|
||||
Execute = { Get-GPOZaurrOwner -IncludeSysvol }
|
||||
Processing = {
|
||||
foreach ($GPO in $Script:Reporting['GPOOwners']['Data']) {
|
||||
if ($GPO.IsOwnerConsistent) {
|
||||
$GpoZaurrOwners['Variables']['IsConsistent']++
|
||||
$Script:Reporting['GPOOwners']['Variables']['IsConsistent']++
|
||||
} else {
|
||||
$GpoZaurrOwners['Variables']['IsNotConsistent']++
|
||||
$Script:Reporting['GPOOwners']['Variables']['IsNotConsistent']++
|
||||
}
|
||||
if ($GPO.IsOwnerAdministrative) {
|
||||
$GpoZaurrOwners['Variables']['IsAdministrative']++
|
||||
$Script:Reporting['GPOOwners']['Variables']['IsAdministrative']++
|
||||
} else {
|
||||
$GpoZaurrOwners['Variables']['IsNotAdministrative']++
|
||||
$Script:Reporting['GPOOwners']['Variables']['IsNotAdministrative']++
|
||||
}
|
||||
if (($GPO.IsOwnerAdministrative -eq $false -or $GPO.IsOwnerConsistent -eq $false) -and $GPO.SysvolExists -eq $true) {
|
||||
$GpoZaurrOwners['Variables']['WillFix']++
|
||||
$Script:Reporting['GPOOwners']['Variables']['WillFix']++
|
||||
} elseif ($GPO.SysvolExists -eq $false) {
|
||||
$GpoZaurrOwners['Variables']['RequiresDiffFix']++
|
||||
$Script:Reporting['GPOOwners']['Variables']['RequiresDiffFix']++
|
||||
} else {
|
||||
$GpoZaurrOwners['Variables']['WillNotTouch']++
|
||||
$Script:Reporting['GPOOwners']['Variables']['WillNotTouch']++
|
||||
}
|
||||
}
|
||||
if ($Script:Reporting['GPOOwners']['Variables']['WillFix'].Count -gt 0) {
|
||||
$Script:Reporting['GPOOwners']['ActionRequired'] = $true
|
||||
} else {
|
||||
$Script:Reporting['GPOOwners']['ActionRequired'] = $false
|
||||
}
|
||||
}
|
||||
Variables = [ordered] @{
|
||||
Variables = @{
|
||||
IsAdministrative = 0
|
||||
IsNotAdministrative = 0
|
||||
IsConsistent = 0
|
||||
@@ -34,25 +39,25 @@
|
||||
RequiresDiffFix = 0
|
||||
WillNotTouch = 0
|
||||
}
|
||||
Overview = {
|
||||
Overview = {
|
||||
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)." -FontSize 10pt
|
||||
New-HTMLList -Type Unordered {
|
||||
New-HTMLListItem -Text 'Administrative Owners: ', $GpoZaurrOwners['Variables']['IsAdministrative'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text 'Non-Administrative Owners: ', $GpoZaurrOwners['Variables']['IsNotAdministrative'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text "Owners consistent in AD and SYSVOL: ", $GpoZaurrOwners['Variables']['IsConsistent'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text "Owners not-consistent in AD and SYSVOL: ", $GpoZaurrOwners['Variables']['IsNotConsistent'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text 'Administrative Owners: ', $Script:Reporting['GPOOwners']['Variables']['IsAdministrative'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text 'Non-Administrative Owners: ', $Script:Reporting['GPOOwners']['Variables']['IsNotAdministrative'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text "Owners consistent in AD and SYSVOL: ", $Script:Reporting['GPOOwners']['Variables']['IsConsistent'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text "Owners not-consistent in AD and SYSVOL: ", $Script:Reporting['GPOOwners']['Variables']['IsNotConsistent'] -FontWeight normal, bold
|
||||
} -FontSize 10pt
|
||||
New-HTMLChart {
|
||||
New-ChartBarOptions -Type barStacked
|
||||
New-ChartLegend -Name 'Yes', 'No' -Color PaleGreen, Orchid
|
||||
New-ChartBar -Name 'Is administrative' -Value $GpoZaurrOwners['Variables']['IsAdministrative'], $GpoZaurrOwners['Variables']['IsNotAdministrative']
|
||||
New-ChartBar -Name 'Is consistent' -Value $GpoZaurrOwners['Variables']['IsConsistent'], $GpoZaurrOwners['Variables']['IsNotConsistent']
|
||||
New-ChartBar -Name 'Is administrative' -Value $Script:Reporting['GPOOwners']['Variables']['IsAdministrative'], $Script:Reporting['GPOOwners']['Variables']['IsNotAdministrative']
|
||||
New-ChartBar -Name 'Is consistent' -Value $Script:Reporting['GPOOwners']['Variables']['IsConsistent'], $Script:Reporting['GPOOwners']['Variables']['IsNotConsistent']
|
||||
} -Title 'Group Policy Owners' -TitleAlignment center
|
||||
}
|
||||
}
|
||||
Summary = {
|
||||
Summary = {
|
||||
New-HTMLText -FontSize 10pt -TextBlock {
|
||||
"By default GPO creation is usually maintained by Domain Admins or Enterprise Admins. "
|
||||
"When GPO is created by member of Domain Admins or Enterprise Admins group the GPO Owner is set to Domain Admins. "
|
||||
@@ -67,38 +72,46 @@
|
||||
}
|
||||
New-HTMLText -Text "Here's a short summary of ", "Group Policy Owners", ": " -FontSize 10pt -FontWeight normal, bold, normal
|
||||
New-HTMLList -Type Unordered {
|
||||
New-HTMLListItem -Text 'Administrative Owners: ', $GpoZaurrOwners['Variables']['IsAdministrative'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text 'Non-Administrative Owners: ', $GpoZaurrOwners['Variables']['IsNotAdministrative'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text "Owners consistent in AD and SYSVOL: ", $GpoZaurrOwners['Variables']['IsConsistent'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text "Owners not-consistent in AD and SYSVOL: ", $GpoZaurrOwners['Variables']['IsNotConsistent'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text 'Administrative Owners: ', $Script:Reporting['GPOOwners']['Variables']['IsAdministrative'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text 'Non-Administrative Owners: ', $Script:Reporting['GPOOwners']['Variables']['IsNotAdministrative'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text "Owners consistent in AD and SYSVOL: ", $Script:Reporting['GPOOwners']['Variables']['IsConsistent'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text "Owners not-consistent in AD and SYSVOL: ", $Script:Reporting['GPOOwners']['Variables']['IsNotConsistent'] -FontWeight normal, bold
|
||||
} -FontSize 10pt
|
||||
New-HTMLText -FontSize 10pt -Text "This gives us: "
|
||||
New-HTMLList -Type Unordered {
|
||||
New-HTMLListItem -Text 'Group Policies requiring owner change: ', $GpoZaurrOwners['Variables']['WillFix'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text "Group Policies which can't be fixed (no SYSVOL?): ", $GpoZaurrOwners['Variables']['RequiresDiffFix'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text "Group Policies unaffected: ", $GpoZaurrOwners['Variables']['WillNotTouch'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text 'Group Policies requiring owner change: ', $Script:Reporting['GPOOwners']['Variables']['WillFix'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text "Group Policies which can't be fixed (no SYSVOL?): ", $Script:Reporting['GPOOwners']['Variables']['RequiresDiffFix'] -FontWeight normal, bold
|
||||
New-HTMLListItem -Text "Group Policies unaffected: ", $Script:Reporting['GPOOwners']['Variables']['WillNotTouch'] -FontWeight normal, bold
|
||||
} -FontSize 10pt
|
||||
}
|
||||
Solution = {
|
||||
Solution = {
|
||||
New-HTMLSection -Invisible {
|
||||
New-HTMLPanel {
|
||||
& $GpoZaurrOwners['Summary']
|
||||
& $Script:GPOConfiguration['GPOOwners']['Summary']
|
||||
}
|
||||
New-HTMLPanel {
|
||||
New-HTMLChart {
|
||||
New-ChartBarOptions -Type barStacked
|
||||
New-ChartLegend -Name 'Yes', 'No' -Color LightGreen, Salmon
|
||||
New-ChartBar -Name 'Is administrative' -Value $GpoZaurrOwners['Variables']['IsAdministrative'], $GpoZaurrOwners['Variables']['IsNotAdministrative']
|
||||
New-ChartBar -Name 'Is consistent' -Value $GpoZaurrOwners['Variables']['IsConsistent'], $GpoZaurrOwners['Variables']['IsNotConsistent']
|
||||
New-ChartBar -Name 'Is administrative' -Value $Script:Reporting['GPOOwners']['Variables']['IsAdministrative'], $Script:Reporting['GPOOwners']['Variables']['IsNotAdministrative']
|
||||
New-ChartBar -Name 'Is consistent' -Value $Script:Reporting['GPOOwners']['Variables']['IsConsistent'], $Script:Reporting['GPOOwners']['Variables']['IsNotConsistent']
|
||||
} -Title 'Group Policy Owners' -TitleAlignment center
|
||||
}
|
||||
}
|
||||
New-HTMLSection -Name 'Group Policy Owners' {
|
||||
New-HTMLTable -DataTable $GpoZaurrOwners['Data'] -Filtering {
|
||||
New-HTMLTable -DataTable $Script:Reporting['GPOOwners']['Data'] -Filtering {
|
||||
New-HTMLTableCondition -Name 'IsOwnerConsistent' -Value $false -BackgroundColor Salmon -ComparisonType string -Row
|
||||
New-HTMLTableCondition -Name 'IsOwnerAdministrative' -Value $false -BackgroundColor Salmon -ComparisonType string -Row
|
||||
} -PagingOptions 10, 20, 30, 40, 50
|
||||
}
|
||||
if ($Script:Reporting['GPOOwners']['WarningsAndErrors']) {
|
||||
New-HTMLSection -Name 'Warnings & Errors to Review' {
|
||||
New-HTMLTable -DataTable $Script:Reporting['GPOOwners']['WarningsAndErrors'] -Filtering {
|
||||
New-HTMLTableCondition -Name 'Type' -Value 'Warning' -BackgroundColor SandyBrown -ComparisonType string -Row
|
||||
New-HTMLTableCondition -Name 'Type' -Value 'Error' -BackgroundColor Salmon -ComparisonType string -Row
|
||||
}
|
||||
}
|
||||
}
|
||||
New-HTMLSection -Name 'Steps to fix Group Policy Owners' {
|
||||
New-HTMLContainer {
|
||||
New-HTMLSpanStyle -FontSize 10pt {
|
||||
|
||||
@@ -16,6 +16,15 @@
|
||||
|
||||
}
|
||||
Solution = {
|
||||
New-HTMLTable -DataTable $GPOZaurrPassword['Data'] -Filtering
|
||||
New-HTMLTable -DataTable $Script:Reporting['GPOPassword']['Data'] -Filtering
|
||||
|
||||
if ($Script:Reporting['GPOPassword']['WarningsAndErrors']) {
|
||||
New-HTMLSection -Name 'Warnings & Errors to Review' {
|
||||
New-HTMLTable -DataTable $Script:Reporting['GPOPassword']['WarningsAndErrors'] -Filtering {
|
||||
New-HTMLTableCondition -Name 'Type' -Value 'Warning' -BackgroundColor SandyBrown -ComparisonType string -Row
|
||||
New-HTMLTableCondition -Name 'Type' -Value 'Error' -BackgroundColor Salmon -ComparisonType string -Row
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,14 @@
|
||||
|
||||
}
|
||||
Solution = {
|
||||
New-HTMLTable -DataTable $GPOZaurrPermissions['Data'] -Filtering
|
||||
New-HTMLTable -DataTable $Script:Reporting['GPOPermissions']['Data'] -Filtering
|
||||
if ($Script:Reporting['GPOPermissions']['WarningsAndErrors']) {
|
||||
New-HTMLSection -Name 'Warnings & Errors to Review' {
|
||||
New-HTMLTable -DataTable $Script:Reporting['GPOPermissions']['WarningsAndErrors'] -Filtering {
|
||||
New-HTMLTableCondition -Name 'Type' -Value 'Warning' -BackgroundColor SandyBrown -ComparisonType string -Row
|
||||
New-HTMLTableCondition -Name 'Type' -Value 'Error' -BackgroundColor Salmon -ComparisonType string -Row
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,14 @@
|
||||
|
||||
}
|
||||
Solution = {
|
||||
New-HTMLTable -DataTable $GPOZaurrPermissionsRoot['Data'] -Filtering
|
||||
New-HTMLTable -DataTable $Script:Reporting['GPOPermissionsRoot']['Data'] -Filtering
|
||||
if ($Script:Reporting['GPOPermissionsRoot']['WarningsAndErrors']) {
|
||||
New-HTMLSection -Name 'Warnings & Errors to Review' {
|
||||
New-HTMLTable -DataTable $Script:Reporting['GPOPermissionsRoot']['WarningsAndErrors'] -Filtering {
|
||||
New-HTMLTableCondition -Name 'Type' -Value 'Warning' -BackgroundColor SandyBrown -ComparisonType string -Row
|
||||
New-HTMLTableCondition -Name 'Type' -Value 'Error' -BackgroundColor Salmon -ComparisonType string -Row
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,14 @@
|
||||
|
||||
}
|
||||
Solution = {
|
||||
New-HTMLTable -DataTable $GPOZaurrSysVolLegacyFiles['Data'] -Filtering
|
||||
New-HTMLTable -DataTable $Script:Reporting['SysVolLegacyFiles']['Data'] -Filtering
|
||||
if ($Script:Reporting['SysVolLegacyFiles']['WarningsAndErrors']) {
|
||||
New-HTMLSection -Name 'Warnings & Errors to Review' {
|
||||
New-HTMLTable -DataTable $Script:Reporting['SysVolLegacyFiles']['WarningsAndErrors'] -Filtering {
|
||||
New-HTMLTableCondition -Name 'Type' -Value 'Warning' -BackgroundColor SandyBrown -ComparisonType string -Row
|
||||
New-HTMLTableCondition -Name 'Type' -Value 'Error' -BackgroundColor Salmon -ComparisonType string -Row
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,11 @@
|
||||
param(
|
||||
|
||||
)
|
||||
#if (-not $Script:GPOConfigurationClean) {
|
||||
# $Script:GPOConfigurationClean = Copy-Dictionary -Dictionary $Script:GPOConfiguration
|
||||
#} else {
|
||||
# $Script:GPOConfiguration = Copy-Dictionary -Dictionary $Script:GPOConfigurationClean
|
||||
#}
|
||||
if (-not $Script:DefaultTypes) {
|
||||
$Script:DefaultTypes = foreach ($T in $Script:GPOConfiguration.Keys) {
|
||||
if ($Script:GPOConfiguration[$T].Enabled) {
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
$Script:GPOConfiguration = [ordered] @{
|
||||
GPOOrphans = $GPOZaurrOrphans
|
||||
GPOOwners = $GPOZaurrOwners
|
||||
GPOConsistency = $GPOZaurrConsistency
|
||||
GPODuplicates = $GPOZaurrDuplicates
|
||||
GPOList = $GPOZaurrList
|
||||
GPOPassword = $GPOZaurrPassword
|
||||
GPOPermissions = $GPOZaurrPermissions
|
||||
GPOPermissionsRoot = $GPOZaurrPermissionsRoot
|
||||
GPOFiles = $GPOZaurrFiles
|
||||
GPOAnalysis = $GPOZaurrAnalysis
|
||||
NetLogonPermissions = $GPOZaurrNetLogonPermissions
|
||||
SysVolLegacyFiles = $GPOZaurrSysVolLegacyFiles
|
||||
GPOOrphans = $GPOZaurrOrphans
|
||||
GPOOwners = $GPOZaurrOwners
|
||||
GPOConsistency = $GPOZaurrConsistency
|
||||
GPODuplicates = $GPOZaurrDuplicates
|
||||
GPOList = $GPOZaurrList
|
||||
GPOPassword = $GPOZaurrPassword
|
||||
GPOPermissions = $GPOZaurrPermissions
|
||||
GPOPermissionsRoot = $GPOZaurrPermissionsRoot
|
||||
GPOFiles = $GPOZaurrFiles
|
||||
GPOBlockedInheritance = $GPOZaurrBlockedInheritance
|
||||
GPOAnalysis = $GPOZaurrAnalysis
|
||||
NetLogonPermissions = $GPOZaurrNetLogonPermissions
|
||||
SysVolLegacyFiles = $GPOZaurrSysVolLegacyFiles
|
||||
}
|
||||
+84
-103
@@ -1,4 +1,35 @@
|
||||
function Get-GPOZaurrPassword {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Tries to find CPassword in Group Policies or given path and translate it to readable value
|
||||
|
||||
.DESCRIPTION
|
||||
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
|
||||
|
||||
.PARAMETER ExcludeDomains
|
||||
Exclude Domain or Domains
|
||||
|
||||
.PARAMETER IncludeDomains
|
||||
Include only certain Domain or Domains
|
||||
|
||||
.PARAMETER ExtendedForestInformation
|
||||
Ability to provide extended forest information in advanced scenarios
|
||||
|
||||
.PARAMETER GPOPath
|
||||
Path where Group Policy content is located or where backup is located
|
||||
|
||||
.EXAMPLE
|
||||
Get-GPOZaurrPassword -GPOPath 'C:\Users\przemyslaw.klys\Desktop\GPOExport_2020.10.12'
|
||||
|
||||
.EXAMPLE
|
||||
Get-GPOZaurrPassword
|
||||
|
||||
.NOTES
|
||||
General notes
|
||||
#>
|
||||
[cmdletBinding()]
|
||||
param(
|
||||
[alias('ForestName')][string] $Forest,
|
||||
@@ -7,115 +38,65 @@
|
||||
[System.Collections.IDictionary] $ExtendedForestInformation,
|
||||
[string[]] $GPOPath
|
||||
)
|
||||
if (-not $GPOPath) {
|
||||
if (-not $ExtendedForestInformation) {
|
||||
$ForestInformation = Get-WinADForestDetails -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains
|
||||
} else {
|
||||
$ForestInformation = $ExtendedForestInformation
|
||||
}
|
||||
|
||||
[Array] $GPOPath = foreach ($Domain in $ForestInformation.Domains) {
|
||||
-join ('\\', $Domain, '\SYSVOL\', $Domain, '\Policies')
|
||||
}
|
||||
}
|
||||
if (-not $GPOPath) {
|
||||
return
|
||||
}
|
||||
foreach ($Path in $GPOPath) {
|
||||
#Extract the all XML files in the Folders
|
||||
$Items = Get-ChildItem -LiteralPath $Path -Recurse -Filter *.xml
|
||||
$Output = foreach ($XMLFileName in $Items) {
|
||||
#Convert XML in a String file
|
||||
[string]$XMLString = Get-Content ($XMLFileName.FullName)
|
||||
#Check if Cpassword Exist in the file
|
||||
if ($XMLString.Contains("cpassword")) {
|
||||
#Take the Cpassword Value from XML String file
|
||||
[string]$Cpassword = [regex]::matches($XMLString, '(cpassword=).+?(?=\")')
|
||||
$Cpassword = $Cpassword.split('(\")')[1]
|
||||
#Check if Cpassword has a value
|
||||
if ($Cpassword.Length -gt 20 -and $Cpassword -notlike '*cpassword*') {
|
||||
$Mod = ($Cpassword.length % 4)
|
||||
switch ($Mod) {
|
||||
'1' { $Cpassword = $Cpassword.Substring(0, $Cpassword.Length - 1) }
|
||||
'2' { $Cpassword += ('=' * (4 - $Mod)) }
|
||||
'3' { $Cpassword += ('=' * (4 - $Mod)) }
|
||||
}
|
||||
$Base64Decoded = [Convert]::FromBase64String($Cpassword)
|
||||
$AesObject = [System.Security.Cryptography.AesCryptoServiceProvider]::new()
|
||||
#Use th AES Key
|
||||
[Byte[]] $AesKey = @(0x4e, 0x99, 0x06, 0xe8, 0xfc, 0xb6, 0x6c, 0xc9, 0xfa, 0xf4, 0x93, 0x10, 0x62, 0x0f, 0xfe, 0xe8, 0xf4, 0x96, 0xe8, 0x06, 0xcc, 0x05, 0x79, 0x90, 0x20, 0x9b, 0x09, 0xa4, 0x33, 0xb6, 0x6c, 0x1b)
|
||||
$AesIV = New-Object Byte[]($AesObject.IV.Length)
|
||||
$AesObject.IV = $AesIV
|
||||
$AesObject.Key = $AesKey
|
||||
$DecryptorObject = $AesObject.CreateDecryptor()
|
||||
[Byte[]] $OutBlock = $DecryptorObject.TransformFinalBlock($Base64Decoded, 0, $Base64Decoded.length)
|
||||
#Convert Hash variable in a String valute
|
||||
$Password = [System.Text.UnicodeEncoding]::Unicode.GetString($OutBlock)
|
||||
} else {
|
||||
$Password = ''
|
||||
}
|
||||
#[string]$GPOguid = [regex]::matches($XMLFileName.DirectoryName, '(?<=\{).+?(?=\})')
|
||||
#$GPODetail = Get-GPO -guid $GPOguid
|
||||
[xml] $XMLContent = $XMLString
|
||||
|
||||
#if (-not $XMLContent.gpo.Computer.ExtensionData.Extension.LocalUsersAndGroups.User.Properties.cpassword -and -not $XMLContent.gpo.User.ExtensionData.Extension.DriveMapSettings.Drive.Properties.cpassword) {
|
||||
#Write-Host ''
|
||||
#}
|
||||
if ($GPOPath) {
|
||||
foreach ($Path in $GPOPath) {
|
||||
$Items = Get-ChildItem -LiteralPath $Path -Recurse -Filter *.xml -ErrorAction SilentlyContinue -ErrorVariable err
|
||||
$Output = foreach ($XMLFileName in $Items) {
|
||||
$Password = Find-GPOPassword -Path $XMLFileName.FullName
|
||||
if ($Password) {
|
||||
$PasswordStatus = $true
|
||||
} else {
|
||||
$PasswordStatus = $false
|
||||
if ($XMLFileName.FullName -match '{\w{8}-\w{4}-\w{4}-\w{4}-\w{12}}') {
|
||||
$GPOGUID = $matches[0]
|
||||
}
|
||||
[PSCustomObject] @{
|
||||
RootPath = $Path
|
||||
PasswordFile = $XMLFileName.FullName
|
||||
GUID = $GPOGUID
|
||||
Password = $Password
|
||||
}
|
||||
}
|
||||
|
||||
[PsCustomObject] @{
|
||||
'Name' = $XMLContent.GPO.Name
|
||||
'Links' = $XMLContent.GPO.LinksTo #| Select-Object -ExpandProperty SOMPath
|
||||
'Enabled' = $XMLContent.GPO.GpoStatus
|
||||
'PasswordStatus' = $PasswordStatus
|
||||
#'GPO' = $XMLContent.gpo.Computer.ExtensionData.Extension.LocalUsersAndGroups
|
||||
'User' = $XMLContent.gpo.Computer.ExtensionData.Extension.LocalUsersAndGroups.User.name
|
||||
'Cpassword' = $XMLContent.gpo.Computer.ExtensionData.Extension.LocalUsersAndGroups.User.Properties.cpassword
|
||||
'CpasswordMap' = $XMLContent.gpo.User.ExtensionData.Extension.DriveMapSettings.Drive.Properties.cpassword
|
||||
'Password' = $Password
|
||||
'GUID' = $XMLContent.GPO.Identifier.Identifier.InnerText
|
||||
|
||||
'Domain' = $XMLContent.GPO.Identifier.Domain
|
||||
|
||||
'ComputerSettingsAvailable' = if ($null -eq $XMLContent.GPO.Computer.ExtensionData) { $false } else { $true }
|
||||
'ComputerSettingsStatus' = if ($XMLContent.GPO.Computer.VersionDirectory -eq 0 -and $XMLContent.GPO.Computer.VersionSysvol -eq 0) { "NeverModified" } else { "Modified" }
|
||||
'ComputerEnabled' = [bool] $XMLContent.GPO.Computer.Enabled
|
||||
'ComputerSetttingsVersionIdentical' = if ($XMLContent.GPO.Computer.VersionDirectory -eq $XMLContent.GPO.Computer.VersionSysvol) { $true } else { $false }
|
||||
'ComputerSettings' = $XMLContent.GPO.Computer.ExtensionData.Extension
|
||||
|
||||
'UserSettingsAvailable' = if ($null -eq $XMLContent.GPO.User.ExtensionData) { $false } else { $true }
|
||||
'UserEnabled' = [bool] $XMLContent.GPO.User.Enabled
|
||||
'UserSettingsStatus' = if ($XMLContent.GPO.User.VersionDirectory -eq 0 -and $XMLContent.GPO.User.VersionSysvol -eq 0) { "NeverModified" } else { "Modified" }
|
||||
'UserSettingsVersionIdentical' = if ($XMLContent.GPO.User.VersionDirectory -eq $XMLContent.GPO.User.VersionSysvol) { $true } else { $false }
|
||||
'UserSettings' = $XMLContent.GPO.User.ExtensionData.Extension
|
||||
|
||||
|
||||
'CreationTime' = [DateTime] $XMLContent.GPO.CreatedTime
|
||||
'ModificationTime' = [DateTime] $XMLContent.GPO.ModifiedTime
|
||||
'ReadTime' = [DateTime] $XMLContent.GPO.ReadTime
|
||||
|
||||
'WMIFilter' = $GPO.WmiFilter.name
|
||||
'WMIFilterDescription' = $GPO.WmiFilter.Description
|
||||
'Path' = $GPO.Path
|
||||
#'SDDL' = if ($Splitter -ne '') { $XMLContent.GPO.SecurityDescriptor.SDDL.'#text' -join $Splitter } else { $XMLContent.GPO.SecurityDescriptor.SDDL.'#text' }
|
||||
'ACL' = $XMLContent.GPO.SecurityDescriptor.Permissions.TrusteePermissions | ForEach-Object -Process {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$ForestInformation = Get-WinADForestDetails -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExtendedForestInformation $ExtendedForestInformation
|
||||
foreach ($Domain in $ForestInformation.Domains) {
|
||||
$Path = -join ('\\', $Domain, '\SYSVOL\', $Domain, '\Policies')
|
||||
#Extract the all XML files in the Folder
|
||||
$Items = Get-ChildItem -LiteralPath $Path -Recurse -Filter *.xml -ErrorAction SilentlyContinue -ErrorVariable err
|
||||
$Output = foreach ($XMLFileName in $Items) {
|
||||
$Password = Find-GPOPassword -Path $XMLFileName.FullName
|
||||
if ($Password) {
|
||||
# match regex
|
||||
if ($XMLFileName.FullName -match '{\w{8}-\w{4}-\w{4}-\w{4}-\w{12}}') {
|
||||
$GPOGUID = $matches[0]
|
||||
$GPO = Get-GPOZaurrAD -GPOGuid $GPOGUID -IncludeDomains $Domain
|
||||
[PSCustomObject] @{
|
||||
'User' = $_.trustee.name.'#Text'
|
||||
'Permission Type' = $_.type.PermissionType
|
||||
'Inherited' = $_.Inherited
|
||||
'Permissions' = $_.Standard.GPOGroupedAccessEnum
|
||||
DisplayName = $GPO.DisplayName
|
||||
DomainName = $GPO.DomainName
|
||||
GUID = $GPO.GUID
|
||||
PasswordFile = $XMLFileName.FullName
|
||||
Password = $Password
|
||||
Created = $GPO.Created
|
||||
Modified = $GPO.Modified
|
||||
Description = $GPO.Description
|
||||
}
|
||||
} else {
|
||||
[PSCustomObject] @{
|
||||
DisplayName = ''
|
||||
DomainName = ''
|
||||
GUID = ''
|
||||
PasswordFile = $XMLFileName.FullName
|
||||
Password = $Password
|
||||
Created = ''
|
||||
Modified = ''
|
||||
Description = ''
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
#Write-Host "I find a Password [ " $Password " ] The GPO named:" $GPODetail" and th file is:" $XMLFileName
|
||||
|
||||
} #if($XMLContent.Contains("cpassword")
|
||||
}
|
||||
foreach ($e in $err) {
|
||||
Write-Warning "Get-GPOZaurrPassword - $($e.Exception.Message) ($($e.CategoryInfo.Reason))"
|
||||
}
|
||||
$Output
|
||||
}
|
||||
$Output
|
||||
}
|
||||
}
|
||||
+39
-25
@@ -10,25 +10,10 @@
|
||||
Reset-GPOZaurrStatus # This makes sure types are at it's proper status
|
||||
|
||||
$Script:Reporting = [ordered] @{}
|
||||
# Provide version check for easy use
|
||||
$GPOZaurrVersion = Get-Command -Name 'Invoke-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'] = "Current/Latest: $($LatestVersion.Version) at $($LatestVersion.PublishDate)"
|
||||
} elseif ($GPOZaurrVersion.Version -lt $LatestVersion.Version) {
|
||||
$Script:Reporting['Version'] = "Current: $($GPOZaurrVersion.Version), Published: $($LatestVersion.Version) at $($LatestVersion.PublishDate). Update?"
|
||||
} elseif ($GPOZaurrVersion.Version -gt $LatestVersion.Version) {
|
||||
$Script:Reporting['Version'] = "Current: $($GPOZaurrVersion.Version), Published: $($LatestVersion.Version) at $($LatestVersion.PublishDate). Lucky you!"
|
||||
}
|
||||
} else {
|
||||
$Script:Reporting['Version'] = "GPOZaurr Current: $($GPOZaurrVersion.Version)"
|
||||
}
|
||||
$Script:Reporting['Version'] = Get-GitHubVersion -Cmdlet 'Invoke-GPOZaurr' -RepositoryOwner 'evotecit' -RepositoryName 'GPOZaurr'
|
||||
Write-Color '[i]', "[GPOZaurr] ", 'Version', ' [Informative] ', $Script:Reporting['Version'] -Color Yellow, DarkGray, Yellow, DarkGray, Magenta
|
||||
|
||||
# Verify requested types are supported
|
||||
$Supported = [System.Collections.Generic.List[string]]::new()
|
||||
[Array] $NotSupported = foreach ($T in $Type) {
|
||||
if ($T -notin $Script:GPOConfiguration.Keys ) {
|
||||
@@ -46,7 +31,7 @@
|
||||
return
|
||||
}
|
||||
|
||||
# Lets disable all current ones
|
||||
# Lets make sure we only enable those types which are requestd by user
|
||||
if ($Type) {
|
||||
foreach ($T in $Script:GPOConfiguration.Keys) {
|
||||
$Script:GPOConfiguration[$T].Enabled = $false
|
||||
@@ -57,20 +42,48 @@
|
||||
}
|
||||
}
|
||||
|
||||
# Build data
|
||||
foreach ($T in $Script:GPOConfiguration.Keys) {
|
||||
if ($Script:GPOConfiguration[$T].Enabled -eq $true) {
|
||||
$Script:Reporting[$T] = [ordered] @{
|
||||
Name = $Script:GPOConfiguration[$T].Name
|
||||
ActionRequired = $null
|
||||
Data = $null
|
||||
WarningsAndErrors = $null
|
||||
Time = $null
|
||||
Variables = Copy-Dictionary -Dictionary $Script:GPOConfiguration[$T]['Variables']
|
||||
}
|
||||
$TimeLogGPOList = Start-TimeLog
|
||||
Write-Color -Text '[i]', '[Start] ', $($Script:GPOConfiguration[$T]['Name']) -Color Yellow, DarkGray, Yellow
|
||||
$Script:GPOConfiguration[$T]['Data'] = & $Script:GPOConfiguration[$T]['Execute']
|
||||
& $Script:GPOConfiguration[$T]['Processing']
|
||||
|
||||
$Script:Reporting[$T]['Data'] = Invoke-Command -ScriptBlock $Script:GPOConfiguration[$T]['Execute'] -WarningVariable CommandWarnings -ErrorVariable CommandErrors
|
||||
Invoke-Command -ScriptBlock $Script:GPOConfiguration[$T]['Processing']
|
||||
$Script:Reporting[$T]['WarningsAndErrors'] = @(
|
||||
foreach ($War in $CommandWarnings) {
|
||||
[PSCustomObject] @{
|
||||
Type = 'Warning'
|
||||
Comment = $War
|
||||
Reason = ''
|
||||
TargetName = ''
|
||||
}
|
||||
}
|
||||
foreach ($Err in $CommandErrors) {
|
||||
[PSCustomObject] @{
|
||||
Type = 'Error'
|
||||
Comment = $Err
|
||||
Reason = $Err.CategoryInfo.Reason
|
||||
TargetName = $Err.CategoryInfo.TargetName
|
||||
}
|
||||
}
|
||||
)
|
||||
$TimeEndGPOList = Stop-TimeLog -Time $TimeLogGPOList -Option OneLiner
|
||||
$Script:Reporting[$T]['Time'] = $TimeEndGPOList
|
||||
Write-Color -Text '[i]', '[End ] ', $($Script:GPOConfiguration[$T]['Name']), " [Time to execute: $TimeEndGPOList]" -Color Yellow, DarkGray, Yellow, DarkGray
|
||||
}
|
||||
}
|
||||
|
||||
# Generate pretty HTML
|
||||
Write-Verbose "Invoke-GPOZaurr - Generating HTML"
|
||||
$TimeLogHTML = Start-TimeLog
|
||||
Write-Color -Text '[i]', '[HTML ] ', 'Generating HTML report' -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
|
||||
@@ -104,12 +117,13 @@
|
||||
}
|
||||
}
|
||||
} -Online -ShowHTML:(-not $HideHTML) -FilePath $FilePath
|
||||
|
||||
$TimeLogEndHTML = Stop-TimeLog -Time $TimeLogHTML -Option OneLiner
|
||||
Write-Color -Text '[i]', '[HTML ] ', 'Generating HTML report', " [Time to execute: $TimeLogEndHTML]" -Color Yellow, DarkGray, Yellow, DarkGray
|
||||
if ($PassThru) {
|
||||
$OutputData = Export-GPOZaurr
|
||||
$OutputData
|
||||
$Script:Reporting
|
||||
}
|
||||
Reset-GPOZaurrStatus # This makes sure types are at it's proper status
|
||||
|
||||
}
|
||||
|
||||
[scriptblock] $SourcesAutoCompleter = {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
function Remove-GPOZaurrDuplicateObject {
|
||||
[cmdletBinding(SupportsShouldProcess)]
|
||||
param(
|
||||
[int] $LimitProcessing = [int32]::MaxValue,
|
||||
[alias('ForestName')][string] $Forest,
|
||||
[string[]] $ExcludeDomains,
|
||||
[alias('Domain', 'Domains')][string[]] $IncludeDomains,
|
||||
@@ -15,9 +16,9 @@
|
||||
}
|
||||
|
||||
$DuplicateGpoObjects = Get-GPOZaurrDuplicateObject @getGPOZaurrDuplicateObjectSplat
|
||||
foreach ($Duplicate in $DuplicateGpoObjects) {
|
||||
foreach ($Duplicate in $DuplicateGpoObjects | Select-Object -First $LimitProcessing) {
|
||||
try {
|
||||
Remove-ADObject -Identity $_.ObjectGUID -Recursive -ErrorAction Stop -Server $Duplicate.DomainName
|
||||
Remove-ADObject -Identity $Duplicate.ObjectGUID -Recursive -ErrorAction Stop -Server $Duplicate.DomainName
|
||||
} catch {
|
||||
Write-Warning "Remove-GPOZaurrDuplicateObject - Deleting $($Duplicate.ConflictDN) / $($Duplicate.DomainName) via GUID: $($Duplicate.ObjectGUID) failed with error: $($_.Exception.Message)"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user