diff --git a/Public/Remove-GPOZaurrBroken.ps1 b/Public/Remove-GPOZaurrBroken.ps1 index b541c89..d1a1ae8 100644 --- a/Public/Remove-GPOZaurrBroken.ps1 +++ b/Public/Remove-GPOZaurrBroken.ps1 @@ -1,8 +1,54 @@ 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( - [ValidateSet('SYSVOL', 'AD')][string[]] $Type = @('SYSVOL', 'AD'), + [parameter(Mandatory, Position = 0)][ValidateSet('SYSVOL', 'AD', 'ObjectClass')][string[]] $Type, [string] $BackupPath, [switch] $BackupDated, [int] $LimitProcessing = [int32]::MaxValue, @@ -32,10 +78,15 @@ $_ } } + if ($Type -contains 'ObjectClass') { + if ($_.Status -eq 'ObjectClass issue') { + $_ + } + } } | Select-Object | Select-Object -First $LimitProcessing | ForEach-Object { $GPO = $_ - if ($GPO.Status -eq 'Not available in AD') { - Write-Verbose "Remove-GPOZaurrBroken - Processing [AD] $($GPO.Path)" + 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)" @@ -47,15 +98,16 @@ } } if ($BackupWorked -or $BackupFinalPath -eq '') { - Write-Verbose "Remove-GPOZaurrBroken - Deleting $($GPO.Path)" + 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)." } } - } elseif ($GPO.Status -eq 'Not available on SYSVOL') { - Write-Verbose "Remove-GPOZaurrBroken - Processing [SYSVOL] $($GPO.DistinguishedName)" + } + 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 {