Files
GPOZaurr/Public/Remove-GPOZaurrBroken.ps1
Przemyslaw Klys 43b304d252 Removed redundant code
Handles ObjectClass problem properly now
2021-02-08 17:43:07 +01:00

131 lines
5.7 KiB
PowerShell

function Remove-GPOZaurrBroken {
<#
.SYNOPSIS
Finds and removes broken Group Policies from SYSVOL or AD or both.
.DESCRIPTION
Finds and removes broken Group Policies from SYSVOL or AD or both. Assesment is based on Get-GPOZaurrBroken and there are 3 supported types:
- AD - meaning GPOs which have no SYSVOL content will be deleted from AD
- SYSVOL - meaning GPOs which have no AD content will be deleted from SYSVOL
- ObjectClass - meaning GPOs which have ObjectClass category of Container rather than groupPolicyContainer will be deleted from AD & SYSVOL
.PARAMETER Type
Choose one or more types to delete. Options are AD, ObjectClass, SYSVOL
.PARAMETER BackupPath
Path to optional backup of SYSVOL content before deletion
.PARAMETER BackupDated
Forces backup to be created within folder that has date in it
.PARAMETER LimitProcessing
Allows to specify maximum number of items that will be fixed in a single run. It doesn't affect amount of GPOs processed
.PARAMETER Forest
Target different Forest, by default current forest is used
.PARAMETER ExcludeDomains
Exclude domain from search, by default whole forest is scanned
.PARAMETER IncludeDomains
Include only specific domains, by default whole forest is scanned
.PARAMETER ExtendedForestInformation
Ability to provide Forest Information from another command to speed up processing
.EXAMPLE
Remove-GPOZaurrBroken -Verbose -WhatIf -Type AD, SYSVOL
.EXAMPLE
Remove-GPOZaurrBroken -Verbose -WhatIf -Type AD, SYSVOL -IncludeDomains 'ad.evotec.pl' -LimitProcessing 2
.EXAMPLE
Remove-GPOZaurrBroken -Verbose -IncludeDomains 'ad.evotec.xyz' -BackupPath $Env:UserProfile\Desktop\MyBackup1 -WhatIf -Type AD, SYSVOL
.NOTES
General notes
#>
[alias('Remove-GPOZaurrOrphaned')]
[cmdletBinding(SupportsShouldProcess)]
param(
[parameter(Mandatory, Position = 0)][ValidateSet('SYSVOL', 'AD', 'ObjectClass')][string[]] $Type,
[string] $BackupPath,
[switch] $BackupDated,
[int] $LimitProcessing = [int32]::MaxValue,
[alias('ForestName')][string] $Forest,
[string[]] $ExcludeDomains,
[alias('Domain', 'Domains')][string[]] $IncludeDomains,
[System.Collections.IDictionary] $ExtendedForestInformation
)
if ($BackupPath) {
if ($BackupDated) {
$BackupFinalPath = "$BackupPath\$((Get-Date).ToString('yyyy-MM-dd_HH_mm_ss'))"
} else {
$BackupFinalPath = $BackupPath
}
} else {
$BackupFinalPath = ''
}
Get-GPOZaurrBroken -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExtendedForestInformation $ExtendedForestInformation | Where-Object {
if ($Type -contains 'SYSVOL') {
if ($_.Status -eq 'Not available in AD') {
$_
}
}
if ($Type -contains 'AD') {
if ($_.Status -eq 'Not available on SYSVOL') {
$_
}
}
if ($Type -contains 'ObjectClass') {
if ($_.Status -eq 'ObjectClass issue') {
$_
}
}
} | Select-Object | Select-Object -First $LimitProcessing | ForEach-Object {
$GPO = $_
if ($GPO.Status -in 'Not available in AD', 'ObjectClass issue') {
Write-Verbose "Remove-GPOZaurrBroken - Removing from SYSVOL [$($GPO.Status)] $($GPO.Path)"
if ($BackupFinalPath) {
Try {
Write-Verbose "Remove-GPOZaurrBroken - Backing up $($GPO.Path)"
Copy-Item -LiteralPath $GPO.Path -Recurse -Destination $BackupFinalPath -ErrorAction Stop
$BackupWorked = $true
} catch {
Write-Warning "Remove-GPOZaurrBroken - Error backing up $($GPO.Path) error: $($_.Exception.Message)"
$BackupWorked = $false
}
}
if ($BackupWorked -or $BackupFinalPath -eq '') {
Write-Verbose "Remove-GPOZaurrBroken - Removing $($GPO.Path)"
try {
Remove-Item -Recurse -Force -LiteralPath $GPO.Path -ErrorAction Stop
} catch {
Write-Warning "Remove-GPOZaurrBroken - Failed to remove file $($GPO.Path): $($_.Exception.Message)."
}
}
}
if ($GPO.Status -in 'Not available on SYSVOL', 'ObjectClass issue') {
Write-Verbose "Remove-GPOZaurrBroken - Removing from AD [$($GPO.Status)] $($GPO.DistinguishedName)"
<#
try {
$ExistingObject = Get-ADObject -Identity $GPO.DistinguishedName -Server $GPO.DomainName -ErrorAction Stop
} catch {
Write-Warning "Remove-GPOZaurrBroken - Error getting $($GPO.DistinguishedName) from AD error: $($_.Exception.Message)"
$ExistingObject = $null
}
#>
if ($GPO -and $GPO.ObjectClass -in 'groupPolicyContainer', 'Container') {
Write-Verbose "Remove-GPOZaurrBroken - Removing DN: $($GPO.DistinguishedName) / ObjectClass: $($GPO.ObjectClass)"
try {
Remove-ADObject -Server $GPO.DomainName -Identity $GPO.DistinguishedName -Recursive -Confirm:$false -ErrorAction Stop
} catch {
Write-Warning "Remove-GPOZaurrBroken - Failed to remove $($GPO.DistinguishedName) from AD error: $($_.Exception.Message)"
}
} else {
Write-Warning "Remove-GPOZaurrBroken - DistinguishedName $($GPO.DistinguishedName) not found or ObjectClass is not groupPolicyContainer/Container ($($GPO.ObjectClass))"
}
}
}
}