diff --git a/Private/Remove-PrivPermission.ps1 b/Private/Remove-PrivPermission.ps1 index bc4258f..770d9e0 100644 --- a/Private/Remove-PrivPermission.ps1 +++ b/Private/Remove-PrivPermission.ps1 @@ -5,41 +5,60 @@ [validateset('DistinguishedName', 'Name', 'Sid')][string] $PrincipalType = 'DistinguishedName', [PSCustomObject] $GPOPermission, [alias('PermissionType')][Microsoft.GroupPolicy.GPPermissionType[]] $IncludePermissionType - ) + if ($GPOPermission.Name) { + $Text = "Removing SID: $($GPOPermission.Sid), Name: $($GPOPermission.Name), SidType: $($GPOPermission.SidType) from domain $($GPOPermission.DomainName)" + } else { + $Text = "Removing SID: $($GPOPermission.Sid), Name: EMPTY, SidType: $($GPOPermission.SidType) from domain $($GPOPermission.DomainName)" + } if ($PrincipalType -eq 'DistinguishedName') { if ($GPOPermission.DistinguishedName -eq $Principal -and $GPOPermission.Permission -eq $IncludePermissionType) { - if ($PSCmdlet.ShouldProcess($GPOPermission.DisplayName, "Removing $($GPOPermission.Sid)/$($GPOPermission.Name) from domain $($GPOPermission.DomainName)")) { + if ($PSCmdlet.ShouldProcess($GPOPermission.DisplayName, $Text)) { try { - Write-Verbose "Remove-GPOZaurrPermission - Removing permission $IncludePermissionType for $($Principal) / $($GPOPermission.Name)" - $GPOPermission.GPOSecurity.Remove($GPOPermission.GPOSecurityPermissionIndex) + Write-Verbose "Remove-GPOZaurrPermission - Removing permission $IncludePermissionType for $($Principal) / $($GPOPermission.Name) / Type: $($GPOPermission.PermissionType)" + $GPOPermission.GPOSecurity.Remove($GPOPermission.GPOSecurityPermissionItem) $GPOPermission.GPOObject.SetSecurityInfo($GPOPermission.GPOSecurity) } catch { - Write-Warning "Remove-GPOZaurrPermission - Adding permission $IncludePermissionType failed for $($Principal) with error: $($_.Exception.Message)" + Write-Warning "Remove-GPOZaurrPermission - Removing permission $IncludePermissionType failed for $($Principal) with error: $($_.Exception.Message)" } } } } elseif ($PrincipalType -eq 'Sid') { if ($GPOPermission.Sid -eq $Principal -and $GPOPermission.Permission -eq $IncludePermissionType) { - if ($PSCmdlet.ShouldProcess($GPOPermission.DisplayName, "Removing $($GPOPermission.Sid)/$($GPOPermission.Name) from domain $($GPOPermission.DomainName)")) { + if ($PSCmdlet.ShouldProcess($GPOPermission.DisplayName, $Text)) { try { - Write-Verbose "Remove-GPOZaurrPermission - Removing permission $IncludePermissionType for $($Principal) / $($GPOPermission.Name)" - $GPOPermission.GPOSecurity.Remove($GPOPermission.GPOSecurityPermissionIndex) + Write-Verbose "Remove-GPOZaurrPermission - Removing permission $IncludePermissionType for $($Principal) / $($GPOPermission.Name) / Type: $($GPOPermission.PermissionType)" + $GPOPermission.GPOSecurity.Remove($GPOPermission.GPOSecurityPermissionItem) $GPOPermission.GPOObject.SetSecurityInfo($GPOPermission.GPOSecurity) } catch { - Write-Warning "Remove-GPOZaurrPermission - Adding permission $IncludePermissionType failed for $($Principal) with error: $($_.Exception.Message)" + if ($_.Exception.Message -like '*The request is not supported. (Exception from HRESULT: 0x80070032)*') { + Write-Warning "Remove-GPOZaurrPermission - Bummer! The request is not supported, but lets fix it differently." + # This is basically atomic approach. We will totally remove any permissions for that user on ACL level to get rid of this situation. + # This situation should only happen if DENY is on FULL Control + $ACL = Get-ADACL -ADObject $GPOPermission.GPOObject.Path -Bundle #-Verbose:$VerbosePreference + if ($ACL) { + Remove-ADACL -ACL $ACL -Principal $Principal -AccessControlType Deny -Verbose:$VerbosePreference + } + # I've noticed that in situation where Edit settings, delete, modify security is set and then set to Deny we need to fix it once more + $ACL = Get-ADACL -ADObject $GPOPermission.GPOObject.Path -Bundle + if ($ACL) { + Remove-ADACL -ACL $ACL -Principal $Principal -AccessControlType Allow -Verbose:$VerbosePreference + } + } else { + Write-Warning "Remove-GPOZaurrPermission - Removing permission $IncludePermissionType failed for $($Principal) with error: $($_.Exception.Message)" + } } } } } elseif ($PrincipalType -eq 'Name') { if ($GPOPermission.Name -eq $Principal -and $GPOPermission.Permission -eq $IncludePermissionType) { - if ($PSCmdlet.ShouldProcess($GPOPermission.DisplayName, "Removing $($GPOPermission.Sid)/$($GPOPermission.Name) from domain $($GPOPermission.DomainName)")) { + if ($PSCmdlet.ShouldProcess($GPOPermission.DisplayName, $Text)) { try { - Write-Verbose "Remove-GPOZaurrPermission - Removing permission $IncludePermissionType for $($Principal)" - $GPOPermission.GPOSecurity.Remove($GPOPermission.GPOSecurityPermissionIndex) + Write-Verbose "Remove-GPOZaurrPermission - Removing permission $IncludePermissionType for $($Principal) / $($GPOPermission.Name) / Type: $($GPOPermission.PermissionType)" + $GPOPermission.GPOSecurity.Remove($GPOPermission.GPOSecurityPermissionItem) $GPOPermission.GPOObject.SetSecurityInfo($GPOPermission.GPOSecurity) } catch { - Write-Warning "Remove-GPOZaurrPermission - Adding permission $IncludePermissionType failed for $($Principal) with error: $($_.Exception.Message)" + Write-Warning "Remove-GPOZaurrPermission - Removing permission $IncludePermissionType failed for $($Principal) with error: $($_.Exception.Message)" } } } diff --git a/Public/Remove-GPOZaurrPermission.ps1 b/Public/Remove-GPOZaurrPermission.ps1 index af2ed17..ff7e178 100644 --- a/Public/Remove-GPOZaurrPermission.ps1 +++ b/Public/Remove-GPOZaurrPermission.ps1 @@ -7,18 +7,16 @@ [Parameter(ParameterSetName = 'GPOGUID', Mandatory)] [alias('GUID', 'GPOID')][string] $GPOGuid, - [string] $Principal, - [validateset('DistinguishedName', 'Name', 'Sid')][string] $PrincipalType = 'DistinguishedName', + [string[]] $Principal, + [validateset('DistinguishedName', 'Name', 'Sid')][string] $PrincipalType = 'Sid', - [validateset('Unknown', 'Named', 'NotAdministrative', 'Default')][string[]] $Type = 'Default', + [validateset('Unknown', 'NotAdministrative', 'Default')][string[]] $Type = 'Default', [alias('PermissionType')][Microsoft.GroupPolicy.GPPermissionType[]] $IncludePermissionType, [Microsoft.GroupPolicy.GPPermissionType[]] $ExcludePermissionType, [switch] $SkipWellKnown, [switch] $SkipAdministrative, - [string[]]$NamedObjects, - [alias('ForestName')][string] $Forest, [string[]] $ExcludeDomains, [alias('Domain', 'Domains')][string[]] $IncludeDomains, @@ -28,37 +26,21 @@ ) Begin { $Count = 0 + $StopMe = $false + + $ForestInformation = Get-WinADForestDetails -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExtendedForestInformation $ExtendedForestInformation + $ADAdministrativeGroups = Get-ADADministrativeGroups -Type DomainAdmins, EnterpriseAdmins -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExtendedForestInformation $ExtendedForestInformation + if ($Type -eq 'Unknown') { + if ($SkipAdministrative -or $SkipWellKnown) { + Write-Warning "Remove-GPOZaurrPermission - Using SkipAdministrative or SkipWellKnown while looking for Unknown doesn't make sense as only Unknown will be displayed." + } + } } Process { - if ($Type -contains 'Named' -and $NamedObjects.Count -eq 0) { + if ($Type -contains 'Named' -and $Principal.Count -eq 0) { Write-Warning "Remove-GPOZaurrPermission - When using type Named you need to provide names to remove. Terminating." return } - if ($GPOName) { - $Splat = @{ - GPOName = $GPOName - } - } elseif ($GPOGUID) { - $Splat = @{ - GPOGUID = $GPOGUID - } - } else { - $Splat = @{ - - } - } - - $Splat['IncludeGPOObject'] = $true - $Splat['Forest'] = $Forest - $Splat['IncludeDomains'] = $IncludeDomains - $Splat['ExcludeDomains'] = $ExcludeDomains - $Splat['ExtendedForestInformation'] = $ExtendedForestInformation - $Splat['ExcludePermissionType'] = $ExcludePermissionType - $Splat['IncludePermissionType'] = $IncludePermissionType - $Splat['SkipWellKnown'] = $SkipWellKnown.IsPresent - $Splat['SkipAdministrative'] = $SkipAdministrative.IsPresent - - # $GPOPermission.GPOSecurity.RemoveTrustee($GPOPermission.Sid) #void RemoveTrustee(string trustee) #void RemoveTrustee(System.Security.Principal.IdentityReference identity) @@ -67,6 +49,57 @@ #void IList[GPPermission].RemoveAt(int index) #void IList.RemoveAt(int index) + foreach ($Domain in $ForestInformation.Domains) { + $QueryServer = $ForestInformation['QueryServers'][$Domain]['HostName'][0] + if ($GPOName) { + $getGPOSplat = @{ + Name = $GPOName + Domain = $Domain + Server = $QueryServer + ErrorAction = 'SilentlyContinue' + } + } elseif ($GPOGuid) { + $getGPOSplat = @{ + Guid = $GPOGuid + Domain = $Domain + Server = $QueryServer + ErrorAction = 'SilentlyContinue' + } + } else { + $getGPOSplat = @{ + All = $true + Domain = $Domain + Server = $QueryServer + ErrorAction = 'SilentlyContinue' + } + } + Get-GPO @getGPOSplat | ForEach-Object -Process { + $getPrivPermissionSplat = @{ + Principal = $Principal + PrincipalType = $PrincipalType + Accounts = $Accounts + Type = $Type + GPO = $_ + SkipWellKnown = $SkipWellKnown.IsPresent + SkipAdministrative = $SkipAdministrative.IsPresent + IncludeOwner = $false + IncludeGPOObject = $true + IncludePermissionType = $IncludePermissionType + ExcludePermissionType = $ExcludePermissionType + ADAdministrativeGroups = $ADAdministrativeGroups + } + [Array] $GPOPermissions = Get-PrivPermission @getPrivPermissionSplat + foreach ($Permission in $GPOPermissions) { + Remove-PrivPermission -Principal $Permission.Sid -PrincipalType Sid -GPOPermission $Permission -IncludePermissionType $Permission.Permission #-IncludeDomains $GPO.DomainName + $Count++ + if ($Count -eq $LimitProcessing) { + # skipping skips per removed permission not per gpo. + break + } + } + } + } + <# Get-GPOZaurrPermission @Splat | ForEach-Object -Process { $GPOPermission = $_ if ($Type -contains 'Unknown') { @@ -77,7 +110,7 @@ Write-Verbose "Remove-GPOZaurrPermission - Removing permission $($GPOPermission.Permission) for $($GPOPermission.Sid)" $GPOPermission.GPOSecurity.RemoveTrustee($GPOPermission.Sid) $GPOPermission.GPOObject.SetSecurityInfo($GPOPermission.GPOSecurity) - #$GPOPermission.GPOSecurity.RemoveAt($GPOPermission.GPOSecurityPermissionIndex) + #$GPOPermission.GPOSecurity.RemoveAt($GPOPermission.GPOSecurityPermissionItem) #$GPOPermission.GPOObject.SetSecurityInfo($GPOPermission.GPOSecurity) } catch { Write-Warning "Remove-GPOZaurrPermission - Removing permission $($GPOPermission.Permission) for $($GPOPermission.Sid) with error: $($_.Exception.Message)" @@ -92,79 +125,19 @@ } } if ($Type -contains 'Named') { - <# - if ($PrincipalType -eq 'DistinguishedName') { - } elseif ($PrincipalType -eq 'Sid') { - if ($GPOPermission.Sid -eq $Principal -and $GPOPermission.Permission -eq $IncludePermissionType) { - - } - } elseif ($PrincipalType -eq 'Name') { - if ($GPOPermission.Name -eq $Principal -and $GPOPermission.Permission -eq $IncludePermissionType) { - - } - } - if ($NamedObjects -contains $GPOPermission.Sid) { - #Write-Verbose "Remove-GPOZaurrPermission - Removing $($GPOPermission.Sid) from $($GPOPermission.DisplayName) at $($GPOPermission.DomainName)" - if ($PSCmdlet.ShouldProcess($GPOPermission.DisplayName, "Removing $($GPOPermission.Sid) from $($GPOPermission.DisplayName) at $($GPOPermission.DomainName)")) { - $GPOPermission.GPOSecurity.RemoveTrustee($GPOPermission.Sid) - $GPOPermission.GPOObject.SetSecurityInfo($GPOPermission.GPOSecurity) - # Set-GPPPermission doesn't work on Unknown Accounts - } - $Count++ - if ($Count -eq $LimitProcessing) { - # skipping skips per removed permission not per gpo. - break - } - } - #> } if ($Type -contains 'NotAdministrative') { } if ($Type -contains 'Default') { Remove-PrivPermission -Principal $Principal -PrincipalType $PrincipalType -GPOPermission $GPOPermission -IncludePermissionType $IncludePermissionType - <# - if ($PrincipalType -eq 'DistinguishedName') { - if ($GPOPermission.DistinguishedName -eq $Principal -and $GPOPermission.Permission -eq $IncludePermissionType) { - try { - Write-Verbose "Remove-GPOZaurrPermission - Removing permission $IncludePermissionType for $($Principal)" - $GPOPermission.GPOSecurity.RemoveAt($GPOPermission.GPOSecurityPermissionIndex) - $GPOPermission.GPOObject.SetSecurityInfo($GPOPermission.GPOSecurity) - } catch { - Write-Warning "Remove-GPOZaurrPermission - Adding permission $IncludePermissionType failed for $($Principal) with error: $($_.Exception.Message)" - } - } - } elseif ($PrincipalType -eq 'Sid') { - if ($GPOPermission.Sid -eq $Principal -and $GPOPermission.Permission -eq $IncludePermissionType) { - try { - Write-Verbose "Remove-GPOZaurrPermission - Removing permission $IncludePermissionType for $($Principal)" - $GPOPermission.GPOSecurity.RemoveAt($GPOPermission.GPOSecurityPermissionIndex) - $GPOPermission.GPOObject.SetSecurityInfo($GPOPermission.GPOSecurity) - } catch { - Write-Warning "Remove-GPOZaurrPermission - Adding permission $IncludePermissionType failed for $($Principal) with error: $($_.Exception.Message)" - } - } - } elseif ($PrincipalType -eq 'Name') { - if ($GPOPermission.Name -eq $Principal -and $GPOPermission.Permission -eq $IncludePermissionType) { - try { - Write-Verbose "Remove-GPOZaurrPermission - Removing permission $IncludePermissionType for $($Principal)" - $GPOPermission.GPOSecurity.RemoveAt($GPOPermission.GPOSecurityPermissionIndex) - $GPOPermission.GPOObject.SetSecurityInfo($GPOPermission.GPOSecurity) - } catch { - Write-Warning "Remove-GPOZaurrPermission - Adding permission $IncludePermissionType failed for $($Principal) with error: $($_.Exception.Message)" - } - } - } - #> - } #Set-GPPermission -PermissionLevel None -TargetName $GPOPermission.Sid -Verbose -DomainName $GPOPermission.DomainName -Guid $GPOPermission.GUID #-WhatIf #Set-GPPermission -PermissionLevel GpoRead -TargetName 'Authenticated Users' -TargetType Group -Verbose -DomainName $Domain -Guid $_.GUID -WhatIf } + #> } - End { - - } + End {} } \ No newline at end of file