From 261f38177fe57a2e787dee94cea3065522fb2648 Mon Sep 17 00:00:00 2001 From: Przemyslaw Klys Date: Sun, 31 May 2020 16:03:35 +0200 Subject: [PATCH] Update --- .../Example-16-AddRemoveGPOPermission02.ps1 | 39 ++- Examples/Example-16-KeepPermissions.ps1 | 27 +- Private/Get-PrivPermission.ps1 | 33 ++- Public/Add-GPOPermission.ps1 | 21 +- Public/Add-GPOZaurrPermission.ps1 | 263 ++++++++++-------- Public/Get-GPOZaurrPermission.ps1 | 61 ++-- Public/Invoke-GPOZaurrPermission.ps1 | 198 +++++-------- 7 files changed, 353 insertions(+), 289 deletions(-) diff --git a/Examples/Example-16-AddRemoveGPOPermission02.ps1 b/Examples/Example-16-AddRemoveGPOPermission02.ps1 index 8fcf959..c3b74dc 100644 --- a/Examples/Example-16-AddRemoveGPOPermission02.ps1 +++ b/Examples/Example-16-AddRemoveGPOPermission02.ps1 @@ -2,18 +2,37 @@ Clear-Host -$T = Get-GPOZaurrPermission -GPOName 'ALL | Enable RDP' #-IncludeGPOObject #-ExcludePermissionType GpoApply,GpoRead -IncludeGPOObject -$T | Format-Table -AutoSize * +$GPOName = 'ALL | Enable RDP' -Add-GPOZaurrPermission -GPOName 'ALL | Enable RDP' -PermissionType GpoEditDeleteModifySecurity -Principal 'Domain Admins' -Verbose -Add-GPOZaurrPermission -GPOName 'ALL | Enable RDP' -PermissionType GpoApply -Principal 'przemyslaw.klys' -Verbose -Add-GPOZaurrPermission -GPOName 'ALL | Enable RDP' -PermissionType GpoEditDeleteModifySecurity -Principal 'przemyslaw.klys' -Verbose -Add-GPOZaurrPermission -GPOName 'ALL | Enable RDP' -PermissionType GpoEdit -Principal 'przemyslaw.klys' -Verbose +$T = Get-GPOZaurrPermission -GPOName $GPOName -IncludePermissionType GpoEditDeleteModifySecurity -PermitType Allow -Principal 'Domain Admins' -PrincipalType 'Name' +$T | Format-Table * -$T = Get-GPOZaurrPermission -GPOName 'ALL | Enable RDP' #-ExcludePermissionType GpoApply,GpoRead -IncludeGPOObject -$T | Format-Table -AutoSize * +<# +# this will go and check for both Domain Admins / Enterprise Admins - if found won't do anything +Add-GPOZaurrPermission -GPOName $GPOName -PermissionType GpoEditDeleteModifySecurity -Type Administrative -Verbose +# this will go thru, because PrincipalType is not set to look by Name. Be precise with what you ask for +Add-GPOZaurrPermission -GPOName $GPOName -PermissionType GpoEditDeleteModifySecurity -Principal 'Domain Admins' -Verbose +# this will be detected as already existing +Add-GPOZaurrPermission -GPOName $GPOName -PermissionType GpoEditDeleteModifySecurity -Principal 'Domain Admins' -PrincipalType Name -Verbose +# this will be added only if it doesn't exists - assuming that przemyslaw.klys is displayed in Get-GPOZaurrPermissions +Add-GPOZaurrPermission -GPOName $GPOName -PermissionType GpoApply -Principal 'przemyslaw.klys' -PrincipalType Name -Verbose +# this will be added only if it doesn't exists - assuming that przemyslaw.klys is displayed in Get-GPOZaurrPermissions +Add-GPOZaurrPermission -GPOName $GPOName -PermissionType GpoEditDeleteModifySecurity -Principal 'przemyslaw.klys' -PrincipalType Name -Verbose +# this will ADD system if it doesn't eists +Add-GPOZaurrPermission -GPOName $GPOName -PermissionType GpoEditDeleteModifySecurity -Type WellKnownAdministrative -Verbose -#Remove-GPOZaurrPermission -GPOName 'ALL | Enable RDP' -PermissionType GpoApply -Principal 'przemyslaw.klys' -PrincipalType Name -Verbose +Add-GPOZaurrPermission -GPOName $GPOName -PermissionType GpoApply -Principal 'przemyslaw.klys' -Verbose +Add-GPOZaurrPermission -GPOName $GPOName -PermissionType GpoEditDeleteModifySecurity -Principal 'przemyslaw.klys' -Verbose +# this will not work because we already have GPOEditDeleteModifySecurity which is higher than GpoEDIT +Add-GPOZaurrPermission -GPOName $GPOName -PermissionType GpoEdit -Principal 'przemyslaw.klys' -Verbose +#> +Add-GPOZaurrPermission -GPOName $GPOName -Type AuthenticatedUsers -PermissionType GpoRead -Verbose #-WhatIf -#$T = Get-GPOZaurrPermission -GPOName 'ALL | Enable RDP' #-ExcludePermissionType GpoApply,GpoRead -IncludeGPOObject +#$T = Get-GPOZaurrPermission -GPOName $GPOName #-ExcludePermissionType GpoApply,GpoRead -IncludeGPOObject +#$T | Format-Table -AutoSize * + +#Remove-GPOZaurrPermission -GPOName $GPOName -PermissionType GpoApply -Principal 'przemyslaw.klys' -PrincipalType Name -Verbose + +#$T = Get-GPOZaurrPermission -GPOName $GPOName #-ExcludePermissionType GpoApply,GpoRead -IncludeGPOObject +#$T = Get-GPOZaurrPermission -GPOName $GPOName #-ExcludePermissionType GpoApply,GpoRead -IncludeGPOObject #$T | Format-Table -AutoSize * \ No newline at end of file diff --git a/Examples/Example-16-KeepPermissions.ps1 b/Examples/Example-16-KeepPermissions.ps1 index 398ee70..9028f57 100644 --- a/Examples/Example-16-KeepPermissions.ps1 +++ b/Examples/Example-16-KeepPermissions.ps1 @@ -1,33 +1,46 @@ Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force Import-Module 'C:\Support\GitHub\PSSharedGoods\PSSharedGoods.psd1' -Force +<# # Apply permissions for ROOT Invoke-GPOZaurrPermission -Verbose -Linked Root -IncludeDomains 'ad.evotec.xyz' { Set-GPOOwner -Type Administrative Remove-GPOPermission -Type NotAdministrative, NotWellKnownAdministrative -IncludePermissionType GpoEdit, GpoEditDeleteModifySecurity -PermitType Allow -} #-WhatIf + Add-GPOPermission -Type Administrative -IncludePermissionType GpoEditDeleteModifySecurity -PermitType Allow + Add-GPOPermission -Type AuthenticatedUsers -IncludePermissionType GpoRead -PermitType Allow +} -WhatIf + # Apply perrmissions for Domain Controllers Invoke-GPOZaurrPermission -Verbose -Linked DomainControllers -IncludeDomains 'ad.evotec.xyz' { Set-GPOOwner -Type Administrative Remove-GPOPermission -Type NotAdministrative, NotWellKnownAdministrative -IncludePermissionType GpoEdit, GpoEditDeleteModifySecurity -PermitType Allow - Add-GPOPermission -Type -} #-WhatIf + Add-GPOPermission -Type Administrative -IncludePermissionType GpoEditDeleteModifySecurity -PermitType Allow + Add-GPOPermission -Type AuthenticatedUsers -IncludePermissionType GpoRead -PermitType Allow +} -WhatIf +#> # Apply permissions for Regions, with exclusions for those 4 groups $Exclude = @( 'CN=ITR01_AD Admins,OU=Security,OU=Groups,OU=Production,DC=ad,DC=evotec,DC=xyz' - 'CN=ITR02_AD Admins,OU=Security,OU=Groups,OU=Production,DC=ad,DC=evotec,DC=xyz' - 'CN=ITR03_AD Admins,OU=Security,OU=Groups,OU=Production,DC=ad,DC=evotec,DC=xyz' - 'CN=ITR04_AD Admins,OU=Security,OU=Groups,OU=Production,DC=ad,DC=evotec,DC=xyz' ) Invoke-GPOZaurrPermission -Verbose -SearchBase 'OU=ITR01,DC=ad,DC=evotec,DC=xyz' { Set-GPOOwner -Type Administrative Remove-GPOPermission -Type NotAdministrative, NotWellKnownAdministrative -IncludePermissionType GpoEdit, GpoEditDeleteModifySecurity -PermitType Allow -ExcludePrincipal $Exclude -ExcludePrincipalType DistinguishedName + Add-GPOPermission -Type Administrative -IncludePermissionType GpoEditDeleteModifySecurity -PermitType Allow + Add-GPOPermission -Type AuthenticatedUsers -IncludePermissionType GpoRead -PermitType Allow } #-WhatIf +$Exclude = @( + 'CN=ITR02_AD Admins,OU=Security,OU=Groups,OU=Production,DC=ad,DC=evotec,DC=xyz' + #'CN=ITR03_AD Admins,OU=Security,OU=Groups,OU=Production,DC=ad,DC=evotec,DC=xyz' + #'CN=ITR04_AD Admins,OU=Security,OU=Groups,OU=Production,DC=ad,DC=evotec,DC=xyz' +) + Invoke-GPOZaurrPermission -Verbose -SearchBase 'OU=ITR02,DC=ad,DC=evotec,DC=xyz' { Set-GPOOwner -Type Administrative Remove-GPOPermission -Type NotAdministrative, NotWellKnownAdministrative -IncludePermissionType GpoEdit, GpoEditDeleteModifySecurity -PermitType Allow -ExcludePrincipal $Exclude -ExcludePrincipalType DistinguishedName -} #-WhatIf \ No newline at end of file + Add-GPOPermission -Type Administrative -IncludePermissionType GpoEditDeleteModifySecurity -PermitType Allow + Add-GPOPermission -Type AuthenticatedUsers -IncludePermissionType GpoRead -PermitType Allow +} #-WhatIf diff --git a/Private/Get-PrivPermission.ps1 b/Private/Get-PrivPermission.ps1 index 9466aa0..65f8bd8 100644 --- a/Private/Get-PrivPermission.ps1 +++ b/Private/Get-PrivPermission.ps1 @@ -2,6 +2,7 @@ [cmdletBinding()] param( [Microsoft.GroupPolicy.Gpo] $GPO, + [Object] $SecurityRights, [string[]] $Principal, [validateset('DistinguishedName', 'Name', 'Sid')][string] $PrincipalType = 'Sid', @@ -18,18 +19,16 @@ [switch] $IncludeGPOObject, [System.Collections.IDictionary] $ADAdministrativeGroups, - [validateSet('Unknown', 'NotWellKnown', 'NotWellKnownAdministrative', 'NotAdministrative', 'Administrative', 'All', 'Default')][string[]] $Type, - [System.Collections.IDictionary] $Accounts + [validateSet('AuthenticatedUsers', 'DomainComputers', 'Unknown', 'WellKnownAdministrative', 'NotWellKnown', 'NotWellKnownAdministrative', 'NotAdministrative', 'Administrative', 'All')][string[]] $Type = 'All', + [System.Collections.IDictionary] $Accounts, + [System.Collections.IDictionary] $ExtendedForestInformation ) Begin { Write-Verbose "Get-PrivPermission - Processing $($GPO.DisplayName) from $($GPO.DomainName)" } Process { - $SecurityRights = $GPO.GetSecurityInfo() $SecurityRights | ForEach-Object -Process { - #Get-GPPermissions -Guid $GPO.ID -DomainName $GPO.DomainName -All -Server $QueryServer | ForEach-Object -Process { $GPOPermission = $_ - if ($PermitType -ne 'All') { if ($PermitType -eq 'Deny') { if ($GPOPermission.Denied -eq $false) { @@ -46,7 +45,11 @@ } if ($IncludePermissionType) { if ($IncludePermissionType -notcontains $GPOPermission.Permission) { - return + if ($IncludePermissionType -eq 'GpoRead' -and $GPOPermission.Permission -eq 'GpoApply') { + # We treat GpoApply as GpoRead as well. This is because when GpoApply is set it becomes GpoRead as well but of course not vice versa + } else { + return + } } } if ($SkipWellKnown.IsPresent -or $Type -contains 'NotWellKnown') { @@ -73,12 +76,30 @@ return } } + if ($Type -contains 'WellKnownAdministrative' -and $Type -notcontains 'All') { + # We check for SYSTEM account + # Maybe we should make it a function and provide more + if ($GPOPermission.Trustee.Sid -ne 'S-1-5-18') { + return + } + } if ($Type -contains 'Unknown' -and $Type -notcontains 'All') { # May need updates if there's more types if ($GPOPermission.Trustee.SidType -ne 'Unknown') { return } } + if ($Type -contains 'AuthenticatedUsers' -and $Type -notcontains 'All') { + if ($GPOPermission.Trustee.Sid -ne 'S-1-5-11') { + return + } + } + if ($Type -contains 'DomainComputers' -and $Type -notcontains 'All') { + $DomainComputersSID = -join ($ExtendedForestInformation['DomainsExtended'][$GPO.DomainName].DomainSID, '-515') + if ($GPOPermission.Trustee.Sid -ne $DomainComputersSID) { + return + } + } if ($Principal) { if ($PrincipalType -eq 'Sid') { if ($Principal -notcontains $GPOPermission.Trustee.Sid.Value) { diff --git a/Public/Add-GPOPermission.ps1 b/Public/Add-GPOPermission.ps1 index 97df2a7..3df5a9d 100644 --- a/Public/Add-GPOPermission.ps1 +++ b/Public/Add-GPOPermission.ps1 @@ -3,28 +3,39 @@ param( [validateset('WellKnownAdministrative', 'Administrative', 'AuthenticatedUsers', 'Default')][string] $Type = 'Default', [Microsoft.GroupPolicy.GPPermissionType] $IncludePermissionType, - [alias('Principal')][Array] $Trustee, - [alias('PrincipalType')][validateset('DistinguishedName', 'Name', 'Sid')][string] $TrusteeType = 'DistinguishedName' + [alias('Trustee')][Array] $Principal, + [alias('TrusteeType')][validateset('DistinguishedName', 'Name', 'Sid')][string] $PrincipalType = 'DistinguishedName', + [validateSet('Allow', 'Deny')][string] $PermitType = 'Allow' ) if ($Type -eq 'Default') { @{ Action = 'Add' - Type = 'Standard' - Trustee = $Trustee + Type = 'Default' + Principal = $Principal IncludePermissionType = $IncludePermissionType - TrusteeType = $TrusteeType + PrincipalType = $PrincipalType + PermitType = $PermitType } } elseif ($Type -eq 'AuthenticatedUsers') { @{ Action = 'Add' Type = 'AuthenticatedUsers' IncludePermissionType = $IncludePermissionType + PermitType = $PermitType } } elseif ($Type -eq 'Administrative') { @{ Action = 'Add' Type = 'Administrative' IncludePermissionType = $IncludePermissionType + PermitType = $PermitType + } + } elseif ($Type -eq 'WellKnownAdministrative') { + @{ + Action = 'Add' + Type = 'WellKnownAdministrative' + IncludePermissionType = $IncludePermissionType + PermitType = $PermitType } } } \ No newline at end of file diff --git a/Public/Add-GPOZaurrPermission.ps1 b/Public/Add-GPOZaurrPermission.ps1 index abf93a8..9727c3a 100644 --- a/Public/Add-GPOZaurrPermission.ps1 +++ b/Public/Add-GPOZaurrPermission.ps1 @@ -12,10 +12,14 @@ [validateset('WellKnownAdministrative', 'Administrative', 'AuthenticatedUsers', 'Default')][string] $Type = 'Default', - [string] $Principal, - [alias('IncludePermissionType')][Microsoft.GroupPolicy.GPPermissionType[]] $PermissionType, + [alias('Trustee')][string] $Principal, + [alias('TrusteeType')][validateset('DistinguishedName', 'Name', 'Sid')][string] $PrincipalType = 'DistinguishedName', + + [Parameter(Mandatory)][alias('IncludePermissionType')][Microsoft.GroupPolicy.GPPermissionType] $PermissionType, [switch] $Inheritable, + [validateSet('Allow', 'Deny', 'All')][string] $PermitType = 'All', + [alias('ForestName')][string] $Forest, [string[]] $ExcludeDomains, [alias('Domain', 'Domains')][string[]] $IncludeDomains, @@ -23,145 +27,180 @@ [System.Collections.IDictionary] $ADAdministrativeGroups, [int] $LimitProcessing ) - Begin { - #$Count = 0 - $ForestInformation = Get-WinADForestDetails -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExtendedForestInformation $ExtendedForestInformation - if (-not $ADAdministrativeGroups) { - $ADAdministrativeGroups = Get-ADADministrativeGroups -Type DomainAdmins, EnterpriseAdmins -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExtendedForestInformation $ExtendedForestInformation - } - $ForestInformation = Get-ADForest + $ForestInformation = Get-WinADForestDetails -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExtendedForestInformation $ExtendedForestInformation -Extended + if (-not $ADAdministrativeGroups) { + $ADAdministrativeGroups = Get-ADADministrativeGroups -Type DomainAdmins, EnterpriseAdmins -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExtendedForestInformation $ExtendedForestInformation } - Process { - if ($GPOName) { - $Splat = @{ - GPOName = $GPOName - } - } elseif ($GPOGUID) { - $Splat = @{ - GPOGUID = $GPOGUID - } - } else { - $Splat = @{ - - } + if ($GPOName) { + $Splat = @{ + GPOName = $GPOName } - - $Splat['IncludeGPOObject'] = $true - $Splat['Forest'] = $Forest - $Splat['IncludeDomains'] = $Domain - #$Splat['ExcludeDomains'] = $ExcludeDomains - #$Splat['ExtendedForestInformation'] = $ExtendedForestInformation - #$Splat['ExcludePermissionType'] = $ExcludePermissionType - #$Splat['IncludePermissionType'] = $PermissionType- - $Splat['SkipWellKnown'] = $SkipWellKnown.IsPresent - $Splat['SkipAdministrative'] = $SkipAdministrative.IsPresent - - # Get-GPOZaurrPermission @Splat - - #Set-GPPermission -PermissionLevel $PermissionType -TargetName $Principal -TargetType Group -Verbose -DomainName 'ad.evotec.xyz' -Name $GPOName -Replace #-WhatIf - - $AdministrativeExists = @{ - DomainAdmins = $false - EnterpriseAdmins = $false + } elseif ($GPOGUID) { + $Splat = @{ + GPOGUID = $GPOGUID } + } else { + $Splat = @{} + } + $Splat['IncludeGPOObject'] = $true + $Splat['Forest'] = $Forest + $Splat['IncludeDomains'] = $IncludeDomains + if ($Type -ne 'Default') { + $Splat['Type'] = $Type + } + $Splat['PermitType'] = $PermitType + $Splat['Principal'] = $Principal + if ($PrincipalType) { + $Splat.PrincipalType = $PrincipalType + } + $Splat['ExcludeDomains'] = $ExcludeDomains + $Splat['ExtendedForestInformation'] = $ExtendedForestInformation + #$Splat['ExcludePermissionType'] = $ExcludePermissionType + $Splat['IncludePermissionType'] = $PermissionType + $Splat['SkipWellKnown'] = $SkipWellKnown.IsPresent + $Splat['SkipAdministrative'] = $SkipAdministrative.IsPresent - #continue - [Array] $GPOPermissions = Get-GPOZaurrPermission @Splat - [Array] $LimitedPermissions = foreach ($GPOPermission in $GPOPermissions) { - #$GPOPermission = $_ - # continue + $AdministrativeExists = @{ + DomainAdmins = $false + EnterpriseAdmins = $false + } + + # This should always return results. When no data is found it should return basic information that will allow us to add credentials. + [Array] $GPOPermissions = Get-GPOZaurrPermission @Splat -ReturnSecurityWhenNoData + # When it has GPOSecurityPermissionItem property it means it has permissions, if it doesn't it means we have clean object to process + if ($GPOPermissions.GPOSecurityPermissionItem) { + # Permission exists, but may be incomplete + foreach ($GPOPermission in $GPOPermissions) { if ($Type -eq 'Default') { - if ($GPOPermission.Name -eq $Principal -and $GPOPermission.Permission -eq $PermissionType) { - #Write-Verbose "Add-GPOZaurrPermission - Permission $PermissionType already set for $($GPOPermission.Name) / $($GPOPermission.DomainName)" - $GPOPermission - break - } + # We were looking for specific principal and we got it. nothing to do + # this is for standard users such as przemyslaw.klys / adam.gonzales + return } elseif ($Type -eq 'Administrative') { + # We are looking for administrative but we need to make sure we got correct administrative if ($GPOPermission.Permission -eq $PermissionType) { $AdministrativeGroup = $ADAdministrativeGroups['BySID'][$GPOPermission.SID] if ($AdministrativeGroup) { - if ($GPOPermission.SID -like '*-512') { - #Write-Verbose "Add-GPOZaurrPermission - Permission $PermissionType already set for $($GPOPermission.Name) / $($GPOPermission.DomainName)" + $DomainAdminsSID = -join ($ForestInformation['DomainsExtended'][$GPOPermission.DomainName].DomainSID, '-512') + $EnterpriseAdminsSID = -join ($ForestInformation['DomainsExtended'][$GPOPermission.DomainName].DomainSID, '-519') + if ($GPOPermission.SID -eq $DomainAdminsSID) { $AdministrativeExists['DomainAdmins'] = $true - } elseif ($GPOPermission.SID -like '*-519') { - #Write-Verbose "Add-GPOZaurrPermission - Permission $PermissionType already set for $($GPOPermission.Name) / $($GPOPermission.DomainName)" + } elseif ($GPOPermission.SID -eq $EnterpriseAdminsSID) { $AdministrativeExists['EnterpriseAdmins'] = $true } } } } elseif ($Type -eq 'WellKnownAdministrative') { - if ($GPOPermission.Name -eq $Principal -and $GPOPermission.Permission -eq $PermissionType) { - #Write-Verbose "Add-GPOZaurrPermission - Permission $PermissionType already set for $($GPOPermission.Name) / $($GPOPermission.DomainName)" - $GPOPermission - break - } + # this is for SYSTEM account + return } elseif ($Type -eq 'AuthenticatedUsers') { - if ($GPOPermission.Name -eq $Principal -and $GPOPermission.Permission -eq $PermissionType) { - #Write-Verbose "Add-GPOZaurrPermission - Permission $PermissionType already set for $($GPOPermission.Name) / $($GPOPermission.DomainName)" - $GPOPermission - break - } + # this is for Authenticated Users + return } - # Write-Verbose "Test" - # $GPOPermission - - - - - #$GPOPermission.GPOSecurity.Add - #void Add(Microsoft.GroupPolicy.GPPermission item) - #void ICollection[GPPermission].Add(Microsoft.GroupPolicy.GPPermission item) - #int IList.Add(System.Object value) - - - # $GPOPermission.GPOObject.SetSecurityInfo($GPOPermission.GPOSecurity) } - if ($GPOPermissions.Count -gt 0) { - if ($LimitedPermissions.Count -gt 0) { - #$LimitedPermissions - } else { - if ($Type -eq 'Administrative') { - if ($AdministrativeExists['DomainAdmins'] -eq $false) { - $Principal = $ADAdministrativeGroups[$GPOPermission.DomainName]['DomainAdmins'] - Write-Verbose "Add-GPOZaurrPermission - Adding permission $PermissionType for $($Principal)" - $AddPermission = [Microsoft.GroupPolicy.GPPermission]::new($Principal, $PermissionType, $Inheritable.IsPresent) - $GPOPermissions[0].GPOSecurity.Add($AddPermission) - $GPOPermissions[0].GPOObject.SetSecurityInfo( $GPOPermissions[0].GPOSecurity) + } + if (-not $GPOPermissions) { + # This is bad - things went wrong + Write-Warning "Add-GPOZaurrPermission - Couldn't get permissions for GPO. Things aren't what they should be. Skipping!" + } else { + $GPO = $GPOPermissions[0] + if ($GPOPermissions.GPOSecurityPermissionItem) { + # We asked, we got response, now we need to check if maybe we're missing one of the two administrative groups + if ($Type -eq 'Administrative') { + # this is a case where something was returned. Be it Domain Admins or Enterprise Admins or both. But we still need to check because it may have been Domain Admins from other domain or just one of the two required groups + if ($AdministrativeExists['DomainAdmins'] -eq $false) { + $Principal = $ADAdministrativeGroups[$GPO.DomainName]['DomainAdmins'] + Write-Verbose "Add-GPOZaurrPermission - Adding permission $PermissionType for $($Principal) to $($GPO.DisplayName) at $($GPO.DomainName)" + if ($PSCmdlet.ShouldProcess($GPO.DisplayName, "Adding $Principal / $PermissionType to $($GPO.DisplayName) at $($GPO.DomainName)")) { + try { + $AddPermission = [Microsoft.GroupPolicy.GPPermission]::new($Principal, $PermissionType, $Inheritable.IsPresent) + $GPO.GPOSecurity.Add($AddPermission) + $GPO.GPOObject.SetSecurityInfo($GPO.GPOSecurity) + } catch { + Write-Warning "Add-GPOZaurrPermission - Adding permission $PermissionType failed for $($Principal) with error: $($_.Exception.Message)" + } } - if ($AdministrativeExists['EnterpriseAdmins'] -eq $false) { - $Principal = $ADAdministrativeGroups[$ForestInformation.RootDomain]['EnterpriseAdmins'] - Write-Verbose "Add-GPOZaurrPermission - Adding permission $PermissionType for $($Principal)" - $AddPermission = [Microsoft.GroupPolicy.GPPermission]::new($Principal, $PermissionType, $Inheritable.IsPresent) - $GPOPermissions[0].GPOSecurity.Add($AddPermission) - $GPOPermissions[0].GPOObject.SetSecurityInfo( $GPOPermissions[0].GPOSecurity) + } + if ($AdministrativeExists['EnterpriseAdmins'] -eq $false) { + $Principal = $ADAdministrativeGroups[$ForestInformation.Forest.RootDomain]['EnterpriseAdmins'] + Write-Verbose "Add-GPOZaurrPermission - Adding permission $PermissionType for $($Principal) to $($GPO.DisplayName) at $($GPO.DomainName)" + if ($PSCmdlet.ShouldProcess($GPO.DisplayName, "Adding $Principal / $PermissionType to $($GPO.DisplayName) at $($GPO.DomainName)")) { + try { + $AddPermission = [Microsoft.GroupPolicy.GPPermission]::new($Principal, $PermissionType, $Inheritable.IsPresent) + $GPO.GPOSecurity.Add($AddPermission) + $GPO.GPOObject.SetSecurityInfo($GPO.GPOSecurity) + } catch { + Write-Warning "Add-GPOZaurrPermission - Adding permission $PermissionType failed for $($Principal) with error: $($_.Exception.Message)" + } } - } elseif ($Type -eq 'Default') { + } + } elseif ($Type -eq 'Default') { + # This shouldn't really happen, as if we got response, and it didn't exists it wouldn't be here + Write-Warning "Add-GPOZaurrPermission - Adding permission $PermissionType skipped for $($Principal). This shouldn't even happen!" + } + } else { + # We got no response. That means we either asked incorrectly or we need to fix permission. Trying to do so + if ($Type -eq 'Default') { + Write-Verbose "Add-GPOZaurrPermission - Adding permission $PermissionType for $($Principal) to $($GPO.DisplayName) at $($GPO.DomainName)" + if ($PSCmdlet.ShouldProcess($GPO.DisplayName, "Adding $Principal / $PermissionType to $($GPO.DisplayName) at $($GPO.DomainName)")) { try { Write-Verbose "Add-GPOZaurrPermission - Adding permission $PermissionType for $($Principal)" $AddPermission = [Microsoft.GroupPolicy.GPPermission]::new($Principal, $PermissionType, $Inheritable.IsPresent) - $GPOPermissions[0].GPOSecurity.Add($AddPermission) - $GPOPermissions[0].GPOObject.SetSecurityInfo($GPOPermission.GPOSecurity) + $GPO.GPOSecurity.Add($AddPermission) + $GPO.GPOObject.SetSecurityInfo($GPO.GPOSecurity) } catch { Write-Warning "Add-GPOZaurrPermission - Adding permission $PermissionType failed for $($Principal) with error: $($_.Exception.Message)" } } - - <# - [Microsoft.GroupPolicy.GPPermission]::new - - OverloadDefinitions - ------------------- - Microsoft.GroupPolicy.GPPermission new(string trustee, Microsoft.GroupPolicy.GPPermissionType rights, bool inheritable) - Microsoft.GroupPolicy.GPPermission new(System.Security.Principal.IdentityReference identity, Microsoft.GroupPolicy.GPPermissionType rights, bool inheritable) - - #> + } elseif ($Type -eq 'Administrative') { + # this is a case where both Domain Admins/Enterprise Admins were missing + $Principal = $ADAdministrativeGroups[$GPO.DomainName]['DomainAdmins'] + Write-Verbose "Add-GPOZaurrPermission - Adding permission $PermissionType for $($Principal) to $($GPO.DisplayName) at $($GPO.DomainName)" + if ($PSCmdlet.ShouldProcess($GPO.DisplayName, "Adding $Principal / $PermissionType to $($GPO.DisplayName) at $($GPO.DomainName)")) { + try { + $AddPermission = [Microsoft.GroupPolicy.GPPermission]::new($Principal, $PermissionType, $Inheritable.IsPresent) + $GPO.GPOSecurity.Add($AddPermission) + $GPO.GPOObject.SetSecurityInfo($GPO.GPOSecurity) + } catch { + Write-Warning "Add-GPOZaurrPermission - Adding permission $PermissionType failed for $($Principal) with error: $($_.Exception.Message)" + } + } + $Principal = $ADAdministrativeGroups[$ForestInformation.Forest.RootDomain]['EnterpriseAdmins'] + Write-Verbose "Add-GPOZaurrPermission - Adding permission $PermissionType for $($Principal) to $($GPO.DisplayName) at $($GPO.DomainName)" + if ($PSCmdlet.ShouldProcess($GPO.DisplayName, "Adding $Principal / $PermissionType to $($GPO.DisplayName) at $($GPO.DomainName)")) { + try { + $AddPermission = [Microsoft.GroupPolicy.GPPermission]::new($Principal, $PermissionType, $Inheritable.IsPresent) + $GPO.GPOSecurity.Add($AddPermission) + $GPO.GPOObject.SetSecurityInfo($GPO.GPOSecurity) + } catch { + Write-Warning "Add-GPOZaurrPermission - Adding permission $PermissionType failed for $($Principal) with error: $($_.Exception.Message)" + } + } + } elseif ($Type -eq 'WellKnownAdministrative') { + $Principal = 'S-1-5-18' + Write-Verbose "Add-GPOZaurrPermission - Adding permission $PermissionType for $($Principal) to $($GPO.DisplayName) at $($GPO.DomainName)" + if ($PSCmdlet.ShouldProcess($GPO.DisplayName, "Adding $Principal (SYSTEM) / $PermissionType to $($GPO.DisplayName) at $($GPO.DomainName)")) { + try { + $AddPermission = [Microsoft.GroupPolicy.GPPermission]::new($Principal, $PermissionType, $Inheritable.IsPresent) + $GPO.GPOSecurity.Add($AddPermission) + $GPO.GPOObject.SetSecurityInfo($GPO.GPOSecurity) + } catch { + Write-Warning "Add-GPOZaurrPermission - Adding permission $PermissionType failed for $($Principal) (SYSTEM) with error: $($_.Exception.Message)" + } + } + } elseif ($Type -eq 'AuthenticatedUsers') { + $Principal = 'S-1-5-11' + Write-Verbose "Add-GPOZaurrPermission - Adding permission $PermissionType for $($Principal) to $($GPO.DisplayName) at $($GPO.DomainName)" + if ($PSCmdlet.ShouldProcess($GPO.DisplayName, "Adding $Principal (Authenticated Users) / $PermissionType to $($GPO.DisplayName) at $($GPO.DomainName)")) { + try { + $AddPermission = [Microsoft.GroupPolicy.GPPermission]::new($Principal, $PermissionType, $Inheritable.IsPresent) + $GPO.GPOSecurity.Add($AddPermission) + $GPO.GPOObject.SetSecurityInfo($GPO.GPOSecurity) + } catch { + Write-Warning "Add-GPOZaurrPermission - Adding permission $PermissionType failed for $($Principal) (Authenticated Users) with error: $($_.Exception.Message)" + } + } } - } else { - Write-Warning "Add-GPOZaurrPermission - GPO $($GPOPermissions[0].GPOName) has no permissions. Weird." } - } - - End { } } \ No newline at end of file diff --git a/Public/Get-GPOZaurrPermission.ps1 b/Public/Get-GPOZaurrPermission.ps1 index 3290a01..fef74ac 100644 --- a/Public/Get-GPOZaurrPermission.ps1 +++ b/Public/Get-GPOZaurrPermission.ps1 @@ -10,7 +10,7 @@ [string[]] $Principal, [validateset('DistinguishedName', 'Name', 'Sid')][string] $PrincipalType = 'Sid', - [validateSet('Unknown', 'NotWellKnown', 'NotWellKnownAdministrative', 'NotAdministrative', 'Administrative', 'All')][string[]] $Type = 'All', + [validateSet('AuthenticatedUsers', 'DomainComputers', 'Unknown', 'WellKnownAdministrative', 'NotWellKnown', 'NotWellKnownAdministrative', 'NotAdministrative', 'Administrative', 'All')][string[]] $Type = 'All', [switch] $SkipWellKnown, [switch] $SkipAdministrative, @@ -30,10 +30,11 @@ [string[]] $ExcludeDomains, [alias('Domain', 'Domains')][string[]] $IncludeDomains, [System.Collections.IDictionary] $ExtendedForestInformation, - [System.Collections.IDictionary] $ADAdministrativeGroups + [System.Collections.IDictionary] $ADAdministrativeGroups, + [switch] $ReturnSecurityWhenNoData # if no data return all data ) Begin { - $ForestInformation = Get-WinADForestDetails -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExtendedForestInformation $ExtendedForestInformation + $ForestInformation = Get-WinADForestDetails -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExtendedForestInformation $ExtendedForestInformation -Extended if (-not $ADAdministrativeGroups) { $ADAdministrativeGroups = Get-ADADministrativeGroups -Type DomainAdmins, EnterpriseAdmins -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExtendedForestInformation $ExtendedForestInformation } @@ -86,24 +87,46 @@ } } Get-GPO @getGPOSplat | ForEach-Object -Process { + $GPOSecurity = $_.GetSecurityInfo() $getPrivPermissionSplat = @{ - Principal = $Principal - PrincipalType = $PrincipalType - PermitType = $PermitType - Accounts = $Accounts - Type = $Type - GPO = $_ - SkipWellKnown = $SkipWellKnown.IsPresent - SkipAdministrative = $SkipAdministrative.IsPresent - IncludeOwner = $IncludeOwner.IsPresent - IncludeGPOObject = $IncludeGPOObject.IsPresent - IncludePermissionType = $IncludePermissionType - ExcludePermissionType = $ExcludePermissionType - ExcludePrincipal = $ExcludePrincipal - ExcludePrincipalType = $ExcludePrincipalType - ADAdministrativeGroups = $ADAdministrativeGroups + Principal = $Principal + PrincipalType = $PrincipalType + PermitType = $PermitType + Accounts = $Accounts + Type = $Type + GPO = $_ + SkipWellKnown = $SkipWellKnown.IsPresent + SkipAdministrative = $SkipAdministrative.IsPresent + IncludeOwner = $IncludeOwner.IsPresent + IncludeGPOObject = $IncludeGPOObject.IsPresent + IncludePermissionType = $IncludePermissionType + ExcludePermissionType = $ExcludePermissionType + ExcludePrincipal = $ExcludePrincipal + ExcludePrincipalType = $ExcludePrincipalType + ADAdministrativeGroups = $ADAdministrativeGroups + ExtendedForestInformation = $ForestInformation + SecurityRights = $GPOSecurity + } + $Output = Get-PrivPermission @getPrivPermissionSplat + if (-not $Output) { + if ($ReturnSecurityWhenNoData) { + # there is no data to return, but we need to have GPO information to process ADD permissions. + $ReturnObject = [PSCustomObject] @{ + DisplayName = $_.DisplayName # : ALL | Enable RDP + GUID = $_.ID + DomainName = $_.DomainName # : ad.evotec.xyz + Enabled = $_.GpoStatus + Description = $_.Description + CreationDate = $_.CreationTime + ModificationTime = $_.ModificationTime + GPOObject = $_ + GPOSecurity = $GPOSecurity + } + $ReturnObject + } + } else { + $Output } - Get-PrivPermission @getPrivPermissionSplat } } } diff --git a/Public/Invoke-GPOZaurrPermission.ps1 b/Public/Invoke-GPOZaurrPermission.ps1 index 9ca5d0a..0a01340 100644 --- a/Public/Invoke-GPOZaurrPermission.ps1 +++ b/Public/Invoke-GPOZaurrPermission.ps1 @@ -92,146 +92,84 @@ [parameter(ParameterSetName = 'Linked')] [System.Collections.IDictionary] $ExtendedForestInformation ) - Begin { - $ForestInformation = Get-WinADForestDetails -Extended -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExtendedForestInformation $ExtendedForestInformation - $ADAdministrativeGroups = Get-ADADministrativeGroups -Type DomainAdmins, EnterpriseAdmins -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExtendedForestInformation $ForestInformation - <# - $Script:Actions = @{ - GpoApply = @{ - Remove = @{ - NotAdministrative = $false - NotWellKnownAdministrative = $false - } - Add = @{ - Administrative = $false - WellKnownAdministrative = $false - } - } - GpoRead = @{ - Remove = @{ - NotAdministrative = $false - NotWellKnownAdministrative = $false - } - Add = @{ - Administrative = $false - WellKnownAdministrative = $false - } - } - GpoCustom = @{ - Remove = @{ - NotAdministrative = $false - NotWellKnownAdministrative = $false - } - Add = @{ - Administrative = $false - WellKnownAdministrative = $false - } - } - GpoEditDeleteModifySecurity = @{ - Remove = @{ - NotAdministrative = $false - NotWellKnownAdministrative = $false - } - Add = @{ - Administrative = $false - WellKnownAdministrative = $false - } - } - GpoEdit = @{ - Remove = @{ - NotAdministrative = $false - NotWellKnownAdministrative = $false - } - Add = @{ - Administrative = $false - WellKnownAdministrative = $false - } - } - } - #> + if ($PermissionRules) { + $Rules = & $PermissionRules + } else { + Write-Warning "Invoke-GPOZaurrPermission - No rules defined. Stopping processing." + return } - Process { + $ForestInformation = Get-WinADForestDetails -Extended -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExtendedForestInformation $ExtendedForestInformation + $ADAdministrativeGroups = Get-ADADministrativeGroups -Type DomainAdmins, EnterpriseAdmins -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExtendedForestInformation $ForestInformation - if ($PermissionRules) { - $Rules = & $PermissionRules - <# - foreach ($Rule in $Rules) { + $Splat = @{ + Forest = $Forest + IncludeDomains = $IncludeDomains + ExcludeDomains = $ExcludeDomains + ExtendedForestInformation = $ForestInformation + } + if ($ADObject) { + $Splat['ADObject'] = $ADObject + } elseif ($Linked) { + $Splat['Linked'] = $Linked + } elseif ($GPOName) { - #$Actions["$Rule."] + } elseif ($GPOGuid) { - if ($Rule.Action -eq 'Remove' -and $Rule.Type -contains 'NotWellKnownAdministrative') { - #$Actions.NotWellKnownAdministrative = $true - } - if ($Rule.Action -eq 'Remove' -and $Rule.Type -contains 'NotAdministrative') { - #$Actions.Remove.NotAdministrative = $true - } - } - #> + } else { + if ($Filter) { + $Splat['Filter'] = $Filter } + if ($SearchBase) { + $Splat['SearchBase'] = $SearchBase + } + if ($SearchScope) { + $Splat['SearchScope'] = $SearchScope + } + } - if ($GPOName -or $GPOGuid) { - - } else { - - $Splat = @{ - Forest = $Forest - IncludeDomains = $IncludeDomains - ExcludeDomains = $ExcludeDomains - ExtendedForestInformation = $ForestInformation - } - if ($ADObject) { - $Splat['ADObject'] = $ADObject - } elseif ($Linked) { - $Splat['Linked'] = $Linked - } else { - if ($Filter) { - $Splat['Filter'] = $Filter - } - if ($SearchBase) { - $Splat['SearchBase'] = $SearchBase - } - if ($SearchScope) { - $Splat['SearchScope'] = $SearchScope - } - } - - Get-GPOZaurrLink @Splat | ForEach-Object -Process { - $GPO = $_ - foreach ($Rule in $Rules) { - if ($Rule.Action -eq 'Owner') { - if ($Rule.Type -eq 'Administrative') { - $AdministrativeGroup = $ADAdministrativeGroups['ByNetBIOS']["$($GPO.Owner)"] - if (-not $AdministrativeGroup) { - $DefaultPrincipal = $ADAdministrativeGroups["$($GPO.DomainName)"]['DomainAdmins'] - Write-Verbose "Invoke-GPOZaurrPermission - Changing GPO: $($GPO.DisplayName) from domain: $($GPO.DomainName) from owner $($GPO.Owner) to $DefaultPrincipal" - #Set-ADACLOwner -ADObject $GPO.GPODistinguishedName -Principal $DefaultPrincipal -Verbose:$false -WhatIf:$WhatIfPreference - Set-GPOZaurrOwner -GPOGuid $GPO.Guid -IncludeDomains $GPO.Domain -Principal $DefaultPrincipal -WhatIf:$WhatIfPreference - } - } elseif ($Rule.Type -eq 'Default') { - Write-Verbose "Invoke-GPOZaurrPermission - Changing GPO: $($GPO.DisplayName) from domain: $($GPO.DomainName) from owner $($GPO.Owner) to $($Rule.Principal)" - #Set-ADACLOwner -ADObject $GPO.GPODistinguishedName -Principal $Rule.Principal -Verbose:$false -WhatIf:$WhatIfPreference - Set-GPOZaurrOwner -GPOGuid $GPO.Guid -IncludeDomains $GPO.Domain -Principal $Rule.Principal -WhatIf:$WhatIfPreference - } - continue - } - if ($Rule.Action -eq 'Remove') { - $GPOPermissions = Get-GPOZaurrPermission -GPOGuid $GPO.GUID -IncludeDomains $GPO.DomainName -IncludePermissionType $Rule.IncludePermissionType -ExcludePermissionType $Rule.ExcludePermissionType -Type $Rule.Type -IncludeGPOObject -PermitType $Rule.PermitType -Principal $Rule.Principal -PrincipalType $Rule.PrincipalType -ExcludePrincipal $Rule.ExcludePrincipal -ExcludePrincipalType $Rule.ExcludePrincipalType - foreach ($Permission in $GPOPermissions) { - Remove-PrivPermission -Principal $Permission.Sid -PrincipalType Sid -GPOPermission $Permission -IncludePermissionType $Permission.Permission - } - continue - } - if ($Rule.Action -eq 'Add') { - #$GPOPermissions = Get-GPOZaurrPermission -GPOGuid $_.GUID -IncludePermissionType $Rule.IncludePermissionType -ExcludePermissionType $Rule.ExcludePermissionType -Type 'All' -IncludeGPOObject - # foreach ($Permission in $GPOPermissions) { - Add-GPOZaurrPermission -GPOGuid $GPO.GUID -IncludeDomains $GPO.DomainName -Type $Rule.Type -PermissionType $Rule.IncludePermissionType -ADAdministrativeGroups $ADAdministrativeGroups - # } + Get-GPOZaurrLink @Splat | ForEach-Object -Process { + $GPO = $_ + foreach ($Rule in $Rules) { + if ($Rule.Action -eq 'Owner') { + if ($Rule.Type -eq 'Administrative') { + $AdministrativeGroup = $ADAdministrativeGroups['ByNetBIOS']["$($GPO.Owner)"] + if (-not $AdministrativeGroup) { + $DefaultPrincipal = $ADAdministrativeGroups["$($GPO.DomainName)"]['DomainAdmins'] + Write-Verbose "Invoke-GPOZaurrPermission - Changing GPO: $($GPO.DisplayName) from domain: $($GPO.DomainName) from owner $($GPO.Owner) to $DefaultPrincipal" + #Set-ADACLOwner -ADObject $GPO.GPODistinguishedName -Principal $DefaultPrincipal -Verbose:$false -WhatIf:$WhatIfPreference + Set-GPOZaurrOwner -GPOGuid $GPO.Guid -IncludeDomains $GPO.Domain -Principal $DefaultPrincipal -WhatIf:$WhatIfPreference } + } elseif ($Rule.Type -eq 'Default') { + Write-Verbose "Invoke-GPOZaurrPermission - Changing GPO: $($GPO.DisplayName) from domain: $($GPO.DomainName) from owner $($GPO.Owner) to $($Rule.Principal)" + #Set-ADACLOwner -ADObject $GPO.GPODistinguishedName -Principal $Rule.Principal -Verbose:$false -WhatIf:$WhatIfPreference + Set-GPOZaurrOwner -GPOGuid $GPO.Guid -IncludeDomains $GPO.Domain -Principal $Rule.Principal -WhatIf:$WhatIfPreference } + } elseif ($Rule.Action -eq 'Remove') { + $GPOPermissions = Get-GPOZaurrPermission -GPOGuid $GPO.GUID -IncludeDomains $GPO.DomainName -IncludePermissionType $Rule.IncludePermissionType -ExcludePermissionType $Rule.ExcludePermissionType -Type $Rule.Type -IncludeGPOObject -PermitType $Rule.PermitType -Principal $Rule.Principal -PrincipalType $Rule.PrincipalType -ExcludePrincipal $Rule.ExcludePrincipal -ExcludePrincipalType $Rule.ExcludePrincipalType + foreach ($Permission in $GPOPermissions) { + Remove-PrivPermission -Principal $Permission.Sid -PrincipalType Sid -GPOPermission $Permission -IncludePermissionType $Permission.Permission + } + } elseif ($Rule.Action -eq 'Add') { + + $SplatPermissions = @{ + Forest = $Forest + IncludeDomains = $IncludeDomains + ExcludeDomains = $ExcludeDomains + ExtendedForestInformation = $ForestInformation + + GPOGuid = $GPO.GUID + IncludePermissionType = $Rule.IncludePermissionType + Type = $Rule.Type + PermitType = $Rule.PermitType + Principal = $Rule.Principal + ADAdministrativeGroups = $ADAdministrativeGroups + } + if ($Rule.PrincipalType) { + $SplatPermissions.PrincipalType = $Rule.PrincipalType + } + Add-GPOZaurrPermission @SplatPermissions } } } - End { - } } \ No newline at end of file