diff --git a/Docs/Set-GPOZaurrOwner.md b/Docs/Set-GPOZaurrOwner.md index 1e3b1c4..b6c5f22 100644 --- a/Docs/Set-GPOZaurrOwner.md +++ b/Docs/Set-GPOZaurrOwner.md @@ -182,7 +182,7 @@ Accept wildcard characters: False Type: String[] Parameter Sets: Type Aliases: -Accepted values: EmptyOrUnknown, NonAdministrative +Accepted values: EmptyOrUnknown, NotAdministrative Required: True Position: Named diff --git a/Examples/Example-03-RestoreGPO.ps1 b/Examples/Example-03-RestoreGPO.ps1 index 43d35a9..441f084 100644 --- a/Examples/Example-03-RestoreGPO.ps1 +++ b/Examples/Example-03-RestoreGPO.ps1 @@ -1,6 +1,6 @@ Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force -$RestoreFrom = 'C:\Users\przemyslaw.klys\Desktop\GPO\2020-04-20_15_51_00' +$RestoreFrom = 'C:\Users\przemyslaw.klys\Desktop\GPO\2020-04-26_10_29_34' $BackupInformation = Get-GPOZaurrBackupInformation -BackupFolder $RestoreFrom $BackupInformation | Format-Table -a diff --git a/Examples/Example-08-ListingPermissionsAdministrative.ps1 b/Examples/Example-08-ListingPermissionsAdministrative.ps1 new file mode 100644 index 0000000..64d66ca --- /dev/null +++ b/Examples/Example-08-ListingPermissionsAdministrative.ps1 @@ -0,0 +1,4 @@ +Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force + +$T = Get-GPOZaurrPermission -GPOName 'Default Domain Policy' -Type 'All' +$T | Format-Table * \ No newline at end of file diff --git a/Examples/Example-11-ReplaceGPOOwnerAutomated.ps1 b/Examples/Example-11-ReplaceGPOOwnerAutomated.ps1 index 4ac63ba..98557e5 100644 --- a/Examples/Example-11-ReplaceGPOOwnerAutomated.ps1 +++ b/Examples/Example-11-ReplaceGPOOwnerAutomated.ps1 @@ -1,13 +1,13 @@ Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force # This Example shows how to deal with GPOs that have owner that doesn't exists anymore (deleted userr or diff domain) - EmptyOrUnknown -# And also can fix at the same time NonAdministrative - this basically looks for users/groups that are not Domain Admins or Enterprise Admins +# And also can fix at the same time NotAdministrative - this basically looks for users/groups that are not Domain Admins or Enterprise Admins # regardless if current user is still Domain Admin or not $GPOs = Get-GPOZaurr #-GPOName 'New Group Policy Object' $GPOs | Format-Table DisplayName, Owner, OwnerSID, OwnerType -Set-GPOZaurrOwner -Type 'EmptyOrUnknown' -Verbose -LimitProcessing 1 -WhatIf +Set-GPOZaurrOwner -Type EmptyOrUnknown -Verbose -LimitProcessing 1 -WhatIf $GPOs = Get-GPOZaurr #-GPOName 'New Group Policy Object' $GPOs | Format-Table DisplayName, Owner, OwnerSID \ No newline at end of file diff --git a/Examples/Example-14-ListingGPOsPerOU1.ps1 b/Examples/Example-14-ListingGPOsPerOU1.ps1 index 87d3113..0ceeafe 100644 --- a/Examples/Example-14-ListingGPOsPerOU1.ps1 +++ b/Examples/Example-14-ListingGPOsPerOU1.ps1 @@ -1,3 +1,3 @@ Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force -Get-GPOZaurrLink | Format-Table -AutoSize \ No newline at end of file +Get-GPOZaurrLink | Format-Table -AutoSize * \ No newline at end of file diff --git a/Examples/Example-14-ListingGPOsSpecial.ps1 b/Examples/Example-14-ListingGPOsSpecial.ps1 new file mode 100644 index 0000000..4f51ff2 --- /dev/null +++ b/Examples/Example-14-ListingGPOsSpecial.ps1 @@ -0,0 +1,11 @@ +Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force + +Clear-Host + +Get-GPOZaurrLink -Linked Root | Format-Table -AutoSize + +Get-GPOZaurrLink -Linked Site | Format-Table -AutoSize + +Get-GPOZaurrLink -Linked DomainControllers | Format-Table -AutoSize + +Get-GPOZaurrLink -Linked Other | Format-Table -AutoSize \ No newline at end of file diff --git a/Examples/Example-16-AddRemoveGPOPermission.ps1 b/Examples/Example-16-AddRemoveGPOPermission.ps1 new file mode 100644 index 0000000..b70f3e7 --- /dev/null +++ b/Examples/Example-16-AddRemoveGPOPermission.ps1 @@ -0,0 +1,42 @@ +#Clear-Host +Import-Module "$PSScriptRoot\..\GPoZaurr.psd1" -Force + +$ApprovedGroups = @( + 'GDS-TestGroup10' +) +$RootGroups = @( + #'przemyslaw.klys' +) + + + +Invoke-GPOZaurrPermission -Linked Root -Verbose { #-IncludePermissionType GpoEdit, GpoEditDeleteModifySecurity -Type NotAdministrative, NotWellKnownAdministrative -Verbose { + Set-GPOOwner -Type Administrative + #Set-GPOOwner -Principal 'EVOTEC\Enterprise Admins' + #Set-GPOOwner -Principal 'Domain Admins' + Remove-GPOPermission -Type Administrative -IncludePermissionType GPOCustom + Remove-GPOPermission -Type NotAdministrative, NotWellKnownAdministrative -IncludePermissionType GpoEdit, GpoEditDeleteModifySecurity + Add-GPOPermission -Type Administrative -IncludePermissionType GpoEditDeleteModifySecurity + #Add-GPOPermission -Type WellKnownAdministrative -IncludePermissionType GpoEditDeleteModifySecurity +} #-WhatIf #| Format-Table * +#-ApprovedGroups $ApprovedGroups -Trustee $RootGroups -TrusteeType Name -TrusteePermissionType GpoEditDeleteModifySecurity -WhatIf | Format-Table * + + +return +Get-GPOZaurrLink -Linked Root | ForEach-Object { + Get-GPOZaurrPermission -GPOGuid $_.GUID -IncludePermissionType 'GpoEdit', 'GpoEditDeleteModifySecurity' -Type 'NotAdministrative', 'NotWellKnownAdministrative' -IncludeGPOObject | ForEach-Object { + $_ + } +} | Format-Table -a * + +#Get-GPOZaurrLink -Linked Site | Format-Table -AutoSize + +#Get-GPOZaurrLink -Linked DomainControllers | Format-Table -AutoSize + +#Get-GPOZaurrLink -Linked Other | Format-Table -AutoSize + +#Get-GPOZaurrLink -SearchBase 'CN=Configuration,DC=ad,DC=evotec,DC=xyz' | Format-Table -AutoSize + +#Get-AdObject -SearchBase 'DC=ad,DC=evotec,DC=xyz' -Server 'ad.evotec.xyz' -Filter "(ObjectClass -eq 'site') -or (ObjectClass -eq 'organizationalUnit' -or ObjectClass -eq 'domainDNS')" -SearchScope Subtree # + +#Get-ADObject -SearchBase 'CN=Configuration,DC=ad,DC=evotec,DC=xyz' | fl \ No newline at end of file diff --git a/GPOZaurr.psd1 b/GPOZaurr.psd1 index 81350fa..374efb4 100644 --- a/GPOZaurr.psd1 +++ b/GPOZaurr.psd1 @@ -5,9 +5,9 @@ CompatiblePSEditions = 'Desktop' Copyright = '(c) 2011 - 2020 Przemyslaw Klys @ Evotec. All rights reserved.' Description = 'Group Policy Eater' - FunctionsToExport = 'Add-GPOZaurrPermission', 'Backup-GPOZaurr', 'Get-GPOZaurr', 'Get-GPOZaurrBackupInformation', 'Get-GPOZaurrLink', 'Get-GPOZaurrPassword', 'Get-GPOZaurrPermission', 'Get-GPOZaurrWMI', 'New-GPOZaurrWMI', 'Remove-GPOZaurr', 'Remove-GPOZaurrPermission', 'Remove-GPOZaurrWMI', 'Restore-GPOZaurr', 'Save-GPOZaurrFiles', 'Set-GPOZaurrOwner' + FunctionsToExport = 'Add-GPOPermission', 'Add-GPOZaurrPermission', 'Backup-GPOZaurr', 'Get-GPOZaurr', 'Get-GPOZaurrBackupInformation', 'Get-GPOZaurrLink', 'Get-GPOZaurrPassword', 'Get-GPOZaurrPermission', 'Get-GPOZaurrWMI', 'Invoke-GPOZaurrPermission', 'New-GPOZaurrWMI', 'Remove-GPOPermission', 'Remove-GPOZaurr', 'Remove-GPOZaurrPermission', 'Remove-GPOZaurrWMI', 'Restore-GPOZaurr', 'Save-GPOZaurrFiles', 'Set-GPOOwner', 'Set-GPOZaurrOwner' GUID = 'f7d4c9e4-0298-4f51-ad77-e8e3febebbde' - ModuleVersion = '0.0.19' + ModuleVersion = '0.0.21' PowerShellVersion = '5.1' PrivateData = @{ PSData = @{ @@ -17,11 +17,11 @@ } } RequiredModules = @{ - ModuleVersion = '0.0.135' + ModuleVersion = '0.0.137' ModuleName = 'PSSharedGoods' Guid = 'ee272aa8-baaa-4edf-9f45-b6d6f7d844fe' }, @{ - ModuleVersion = '0.0.48' + ModuleVersion = '0.0.51' ModuleName = 'ADEssentials' Guid = '9fc9fd61-7f11-4f4b-a527-084086f1905f' }, 'ActiveDirectory', 'GroupPolicy', 'CimCmdlets', 'Microsoft.PowerShell.Management', 'Microsoft.PowerShell.Utility' diff --git a/Private/Get-ADAdministrativeGroups.ps1 b/Private/Get-ADAdministrativeGroups.ps1 index beb71b4..c3535e0 100644 --- a/Private/Get-ADAdministrativeGroups.ps1 +++ b/Private/Get-ADAdministrativeGroups.ps1 @@ -1,5 +1,4 @@ - -function Get-ADADministrativeGroups { +function Get-ADADministrativeGroups { <# .SYNOPSIS Short description diff --git a/Private/Get-PrivGPOZaurrLInk.ps1 b/Private/Get-PrivGPOZaurrLInk.ps1 index 6c18448..0fedd33 100644 --- a/Private/Get-PrivGPOZaurrLInk.ps1 +++ b/Private/Get-PrivGPOZaurrLInk.ps1 @@ -6,7 +6,7 @@ [System.Collections.IDictionary] $GPOCache ) if ($Object.GpLink -and $Object.GpLink.Trim() -ne '') { - $Object.GpLink -split { $_ -eq '[' -or $_ -eq ']' } -replace ';0' -replace 'LDAP://' | ForEach-Object { + $Object.GpLink -split { $_ -eq '[' -or $_ -eq ']' } -replace ';0' -replace 'LDAP://' | ForEach-Object -Process { if ($_) { $Output = [ordered] @{ DistinguishedName = $Object.DistinguishedName @@ -14,7 +14,7 @@ Guid = [Regex]::Match( $_, '(?={)(.*)(?<=})').Value -replace '{' -replace '}' } if ($GPOCache -and -not $Limited) { - $Output['Name'] = $GPOCache[$Output['Guid']].DisplayName + $Output['DisplayName'] = $GPOCache[$Output['Guid']].DisplayName $Output['DomainName'] = $GPOCache[$Output['Guid']].DomainName $Output['Owner'] = $GPOCache[$Output['Guid']].Owner $Output['GpoStatus'] = $GPOCache[$Output['Guid']].GpoStatus @@ -23,12 +23,12 @@ $Output['ModificationTime'] = $GPOCache[$Output['Guid']].ModificationTime } $Output['GPODomainDistinguishedName'] = ConvertFrom-DistinguishedName -DistinguishedName $_ -ToDC - $Output['GPOLink'] = $_ + $Output['GPODistinguishedName'] = $_ [PSCustomObject] $Output } } } elseif ($Object.LinkedGroupPolicyObjects -and $Object.LinkedGroupPolicyObjects.Trim() -ne '') { - $Object.LinkedGroupPolicyObjects -split { $_ -eq '[' -or $_ -eq ']' } -replace ';0' -replace 'LDAP://' | ForEach-Object { + $Object.LinkedGroupPolicyObjects -split { $_ -eq '[' -or $_ -eq ']' } -replace ';0' -replace 'LDAP://' | ForEach-Object -Process { if ($_) { $Output = [ordered] @{ DistinguishedName = $Object.DistinguishedName @@ -45,7 +45,7 @@ $Output['ModificationTime'] = $GPOCache[$Output['Guid']].ModificationTime } $Output['GPODomainDistinguishedName'] = ConvertFrom-DistinguishedName -DistinguishedName $_ -ToDC - $Output['GPOLink'] = $_ + $Output['GPODistinguishedName'] = $_ [PSCustomObject] $Output } } diff --git a/Private/Get-PrivPermission.ps1 b/Private/Get-PrivPermission.ps1 index 8acf1af..1bc156b 100644 --- a/Private/Get-PrivPermission.ps1 +++ b/Private/Get-PrivPermission.ps1 @@ -9,42 +9,49 @@ [Microsoft.GroupPolicy.GPPermissionType[]] $ExcludePermissionType, [switch] $IncludeGPOObject, [System.Collections.IDictionary] $ADAdministrativeGroups, - [string[]] $Type, + [validateSet('Unknown', 'NotWellKnown', 'NotWellKnownAdministrative', 'NotAdministrative','Administrative', 'All')][string[]] $Type, [System.Collections.IDictionary] $Accounts ) Write-Verbose "Get-GPOZaurrPermission - Processing $($GPO.DisplayName) from $($GPO.DomainName)" $SecurityRights = $GPO.GetSecurityInfo() - $Index = 0 $SecurityRights | ForEach-Object -Process { #Get-GPPermissions -Guid $GPO.ID -DomainName $GPO.DomainName -All -Server $QueryServer | ForEach-Object -Process { $GPOPermission = $_ if ($ExcludePermissionType -contains $GPOPermission.Permission) { - $Index++ return } if ($IncludePermissionType) { if ($IncludePermissionType -notcontains $GPOPermission.Permission) { - $Index++ return } } - if ($SkipWellKnown.IsPresent) { + if ($SkipWellKnown.IsPresent -or $Type -contains 'NotWellKnown') { if ($GPOPermission.Trustee.SidType -eq 'WellKnownGroup') { - $Index++ return } } - if ($SkipAdministrative.IsPresent) { + if ($SkipAdministrative.IsPresent -or $Type -contains 'NotAdministrative') { $IsAdministrative = $ADAdministrativeGroups['BySID'][$GPOPermission.Trustee.Sid.Value] if ($IsAdministrative) { - $Index++ + return + } + } + if ($Type -contains 'Administrative' -and $Type -notcontains 'All') { + $IsAdministrative = $ADAdministrativeGroups['BySID'][$GPOPermission.Trustee.Sid.Value] + if (-not $IsAdministrative) { + return + } + } + if ($Type -contains 'NotWellKnownAdministrative' -and $Type -notcontains 'All') { + # We check for SYSTEM account + # Maybe we should make it a function and provide more + if ($GPOPermission.Trustee.Sid -eq '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') { - $Index++ return } } @@ -94,10 +101,9 @@ if ($IncludeGPOObject) { $ReturnObject['GPOObject'] = $GPO $ReturnObject['GPOSecurity'] = $SecurityRights - $ReturnObject['GPOSecurityPermissionIndex'] = $Index + $ReturnObject['GPOSecurityPermissionIndex'] = $GPOPermission } [PSCustomObject] $ReturnObject - $Index++ } if ($IncludeOwner.IsPresent) { if ($GPO.Owner) { diff --git a/Private/Get-XMLGPO.ps1 b/Private/Get-XMLGPO.ps1 index 0c74ca9..30a5584 100644 --- a/Private/Get-XMLGPO.ps1 +++ b/Private/Get-XMLGPO.ps1 @@ -45,7 +45,7 @@ } elseif ($WellKnown.Name) { $OwnerType = 'WellKnown' } else { - $OwnerType = 'NonAdministrative' + $OwnerType = 'NotAdministrative' } } else { $OwnerType = 'EmptyOrUnknown' @@ -53,48 +53,51 @@ } if ($PermissionsOnly) { [PsCustomObject] @{ - 'DisplayName' = $XMLContent.GPO.Name - 'DomainName' = $XMLContent.GPO.Identifier.Domain.'#text' - 'GUID' = $XMLContent.GPO.Identifier.Identifier.InnerText - 'Enabled' = $Enabled - 'Name' = $XMLContent.GPO.SecurityDescriptor.Owner.Name.'#text' - 'Sid' = $XMLContent.GPO.SecurityDescriptor.Owner.SID.'#text' + 'DisplayName' = $XMLContent.GPO.Name + 'DomainName' = $XMLContent.GPO.Identifier.Domain.'#text' + 'GUID' = $XMLContent.GPO.Identifier.Identifier.InnerText -replace '{' -replace '}' + 'Enabled' = $Enabled + 'Name' = $XMLContent.GPO.SecurityDescriptor.Owner.Name.'#text' + 'Sid' = $XMLContent.GPO.SecurityDescriptor.Owner.SID.'#text' #'SidType' = if (($XMLContent.GPO.SecurityDescriptor.Owner.SID.'#text').Length -le 10) { 'WellKnown' } else { 'Other' } - 'PermissionType' = 'Allow' - 'Inherited' = $false - 'Permissions' = 'Owner' + 'PermissionType' = 'Allow' + 'Inherited' = $false + 'Permissions' = 'Owner' + 'GPODistinguishedName' = $GPO.Path } $XMLContent.GPO.SecurityDescriptor.Permissions.TrusteePermissions | ForEach-Object -Process { if ($_) { [PsCustomObject] @{ - 'DisplayName' = $XMLContent.GPO.Name - 'DomainName' = $XMLContent.GPO.Identifier.Domain.'#text' - 'GUID' = $XMLContent.GPO.Identifier.Identifier.InnerText - 'Enabled' = $Enabled - 'Name' = $_.trustee.name.'#Text' - 'Sid' = $_.trustee.SID.'#Text' + 'DisplayName' = $XMLContent.GPO.Name + 'DomainName' = $XMLContent.GPO.Identifier.Domain.'#text' + 'GUID' = $XMLContent.GPO.Identifier.Identifier.InnerText -replace '{' -replace '}' + 'Enabled' = $Enabled + 'Name' = $_.trustee.name.'#Text' + 'Sid' = $_.trustee.SID.'#Text' #'SidType' = if (($XMLContent.GPO.SecurityDescriptor.Owner.SID.'#text').Length -le 10) { 'WellKnown' } else { 'Other' } - 'PermissionType' = $_.type.PermissionType - 'Inherited' = if ($_.Inherited -eq 'false') { $false } else { $true } - 'Permissions' = $_.Standard.GPOGroupedAccessEnum + 'PermissionType' = $_.type.PermissionType + 'Inherited' = if ($_.Inherited -eq 'false') { $false } else { $true } + 'Permissions' = $_.Standard.GPOGroupedAccessEnum + 'GPODistinguishedName' = $GPO.Path } } } } elseif ($OwnerOnly) { [PsCustomObject] @{ - 'DisplayName' = $XMLContent.GPO.Name - 'DomainName' = $XMLContent.GPO.Identifier.Domain.'#text' - 'GUID' = $XMLContent.GPO.Identifier.Identifier.InnerText - 'Enabled' = $Enabled - 'Owner' = $XMLContent.GPO.SecurityDescriptor.Owner.Name.'#text' - 'OwnerSID' = $XMLContent.GPO.SecurityDescriptor.Owner.SID.'#text' - 'OwnerType' = $OwnerType + 'DisplayName' = $XMLContent.GPO.Name + 'DomainName' = $XMLContent.GPO.Identifier.Domain.'#text' + 'GUID' = $XMLContent.GPO.Identifier.Identifier.InnerText -replace '{' -replace '}' + 'Enabled' = $Enabled + 'Owner' = $XMLContent.GPO.SecurityDescriptor.Owner.Name.'#text' + 'OwnerSID' = $XMLContent.GPO.SecurityDescriptor.Owner.SID.'#text' + 'OwnerType' = $OwnerType + 'GPODistinguishedName' = $GPO.Path } } else { [PsCustomObject] @{ 'DisplayName' = $XMLContent.GPO.Name 'DomainName' = $XMLContent.GPO.Identifier.Domain.'#text' - 'GUID' = $XMLContent.GPO.Identifier.Identifier.InnerText + 'GUID' = $XMLContent.GPO.Identifier.Identifier.InnerText -replace '{' -replace '}' 'Linked' = $Linked 'LinksCount' = $LinksCount 'Enabled' = $Enabled @@ -115,7 +118,7 @@ 'WMIFilter' = $GPO.WmiFilter.name 'WMIFilterDescription' = $GPO.WmiFilter.Description - 'DistinguishedName' = $GPO.Path + 'GPODistinguishedName' = $GPO.Path 'SDDL' = if ($Splitter -ne '') { $XMLContent.GPO.SecurityDescriptor.SDDL.'#text' -join $Splitter } else { $XMLContent.GPO.SecurityDescriptor.SDDL.'#text' } 'Owner' = $XMLContent.GPO.SecurityDescriptor.Owner.Name.'#text' 'OwnerSID' = $XMLContent.GPO.SecurityDescriptor.Owner.SID.'#text' diff --git a/Private/Remove-PrivPermission.ps1 b/Private/Remove-PrivPermission.ps1 new file mode 100644 index 0000000..bc4258f --- /dev/null +++ b/Private/Remove-PrivPermission.ps1 @@ -0,0 +1,47 @@ +function Remove-PrivPermission { + [cmdletBinding(SupportsShouldProcess)] + param( + [string] $Principal, + [validateset('DistinguishedName', 'Name', 'Sid')][string] $PrincipalType = 'DistinguishedName', + [PSCustomObject] $GPOPermission, + [alias('PermissionType')][Microsoft.GroupPolicy.GPPermissionType[]] $IncludePermissionType + + ) + 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)")) { + try { + Write-Verbose "Remove-GPOZaurrPermission - Removing permission $IncludePermissionType for $($Principal) / $($GPOPermission.Name)" + $GPOPermission.GPOSecurity.Remove($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) { + if ($PSCmdlet.ShouldProcess($GPOPermission.DisplayName, "Removing $($GPOPermission.Sid)/$($GPOPermission.Name) from domain $($GPOPermission.DomainName)")) { + try { + Write-Verbose "Remove-GPOZaurrPermission - Removing permission $IncludePermissionType for $($Principal) / $($GPOPermission.Name)" + $GPOPermission.GPOSecurity.Remove($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) { + if ($PSCmdlet.ShouldProcess($GPOPermission.DisplayName, "Removing $($GPOPermission.Sid)/$($GPOPermission.Name) from domain $($GPOPermission.DomainName)")) { + try { + Write-Verbose "Remove-GPOZaurrPermission - Removing permission $IncludePermissionType for $($Principal)" + $GPOPermission.GPOSecurity.Remove($GPOPermission.GPOSecurityPermissionIndex) + $GPOPermission.GPOObject.SetSecurityInfo($GPOPermission.GPOSecurity) + } catch { + Write-Warning "Remove-GPOZaurrPermission - Adding permission $IncludePermissionType failed for $($Principal) with error: $($_.Exception.Message)" + } + } + } + } +} diff --git a/Public/Add-GPOPermission.ps1 b/Public/Add-GPOPermission.ps1 new file mode 100644 index 0000000..d61c465 --- /dev/null +++ b/Public/Add-GPOPermission.ps1 @@ -0,0 +1,30 @@ +function Add-GPOPermission { + [cmdletBinding()] + 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' + ) + if ($Type -eq 'Default'){ + @{ + Action = 'Add' + Type = 'Standard' + Trustee = $Trustee + IncludePermissionType = $IncludePermissionType + TrusteeType = $TrusteeType + } + } elseif ($Type -eq 'AuthenticatedUsers') { + @{ + Action = 'Add' + Type = 'AuthenticatedUsers' + IncludePermissionType = $IncludePermissionType + } + } elseif ($Type -eq 'Administrative') { + @{ + Action = 'Add' + Type = 'Administrative' + IncludePermissionType = $IncludePermissionType + } + } +} \ No newline at end of file diff --git a/Public/Add-GPOZaurrPermission.ps1 b/Public/Add-GPOZaurrPermission.ps1 index 8da4276..abf93a8 100644 --- a/Public/Add-GPOZaurrPermission.ps1 +++ b/Public/Add-GPOZaurrPermission.ps1 @@ -10,22 +10,28 @@ [Parameter(ParameterSetName = 'ADObject', Mandatory)] [alias('OrganizationalUnit', 'DistinguishedName')][Microsoft.ActiveDirectory.Management.ADObject[]] $ADObject, + [validateset('WellKnownAdministrative', 'Administrative', 'AuthenticatedUsers', 'Default')][string] $Type = 'Default', + [string] $Principal, - [Microsoft.GroupPolicy.GPPermissionType[]] $PermissionType, + [alias('IncludePermissionType')][Microsoft.GroupPolicy.GPPermissionType[]] $PermissionType, [switch] $Inheritable, [alias('ForestName')][string] $Forest, [string[]] $ExcludeDomains, [alias('Domain', 'Domains')][string[]] $IncludeDomains, [System.Collections.IDictionary] $ExtendedForestInformation, - + [System.Collections.IDictionary] $ADAdministrativeGroups, [int] $LimitProcessing ) Begin { - $Count = 0 + #$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 } Process { - if ($GPOName) { $Splat = @{ GPOName = $GPOName @@ -42,9 +48,9 @@ $Splat['IncludeGPOObject'] = $true $Splat['Forest'] = $Forest - $Splat['IncludeDomains'] = $IncludeDomains - $Splat['ExcludeDomains'] = $ExcludeDomains - $Splat['ExtendedForestInformation'] = $ExtendedForestInformation + $Splat['IncludeDomains'] = $Domain + #$Splat['ExcludeDomains'] = $ExcludeDomains + #$Splat['ExtendedForestInformation'] = $ExtendedForestInformation #$Splat['ExcludePermissionType'] = $ExcludePermissionType #$Splat['IncludePermissionType'] = $PermissionType- $Splat['SkipWellKnown'] = $SkipWellKnown.IsPresent @@ -54,15 +60,47 @@ #Set-GPPermission -PermissionLevel $PermissionType -TargetName $Principal -TargetType Group -Verbose -DomainName 'ad.evotec.xyz' -Name $GPOName -Replace #-WhatIf + $AdministrativeExists = @{ + DomainAdmins = $false + EnterpriseAdmins = $false + } + #continue [Array] $GPOPermissions = Get-GPOZaurrPermission @Splat [Array] $LimitedPermissions = foreach ($GPOPermission in $GPOPermissions) { #$GPOPermission = $_ # continue - 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 + 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 + } + } elseif ($Type -eq '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)" + $AdministrativeExists['DomainAdmins'] = $true + } elseif ($GPOPermission.SID -like '*-519') { + #Write-Verbose "Add-GPOZaurrPermission - Permission $PermissionType already set for $($GPOPermission.Name) / $($GPOPermission.DomainName)" + $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 + } + } 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 + } } # Write-Verbose "Test" # $GPOPermission @@ -78,20 +116,37 @@ # $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 ($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) + } + } elseif ($Type -eq 'Default') { + 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) + } catch { + Write-Warning "Add-GPOZaurrPermission - Adding permission $PermissionType failed for $($Principal) with error: $($_.Exception.Message)" + } + } - if ($LimitedPermissions.Count -gt 0) { - #$LimitedPermissions - } else { - 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) - } catch { - Write-Warning "Add-GPOZaurrPermission - Adding permission $PermissionType failed for $($Principal) with error: $($_.Exception.Message)" - } - - <# + <# [Microsoft.GroupPolicy.GPPermission]::new OverloadDefinitions @@ -100,8 +155,12 @@ Microsoft.GroupPolicy.GPPermission new(System.Security.Principal.IdentityReference identity, Microsoft.GroupPolicy.GPPermissionType rights, bool inheritable) #> + } + } else { + Write-Warning "Add-GPOZaurrPermission - GPO $($GPOPermissions[0].GPOName) has no permissions. Weird." } } + End { } diff --git a/Public/Get-GPOZaurrBackupInformation.ps1 b/Public/Get-GPOZaurrBackupInformation.ps1 index b6bcca1..372229a 100644 --- a/Public/Get-GPOZaurrBackupInformation.ps1 +++ b/Public/Get-GPOZaurrBackupInformation.ps1 @@ -11,15 +11,15 @@ if ($Folder) { if ((Test-Path -LiteralPath "$Folder\manifest.xml")) { [xml] $Xml = Get-Content -LiteralPath "$Folder\manifest.xml" - $Xml.Backups.BackupInst | ForEach-Object { + $Xml.Backups.BackupInst | ForEach-Object -Process { [PSCustomObject] @{ DisplayName = $_.GPODisplayName.'#cdata-section' DomainName = $_.GPODomain.'#cdata-section' - Guid = $_.GPOGUid.'#cdata-section' - DomainGuid = $_.GPODomainGuid.'#cdata-section' + Guid = $_.GPOGUid.'#cdata-section' -replace '{' -replace '}' + DomainGuid = $_.GPODomainGuid.'#cdata-section' -replace '{' -replace '}' DomainController = $_.GPODomainController.'#cdata-section' - BackupTime = $_.BackupTime.'#cdata-section' - ID = $_.ID.'#cdata-section' + BackupTime = [DateTime]::Parse($_.BackupTime.'#cdata-section') + ID = $_.ID.'#cdata-section' -replace '{' -replace '}' Comment = $_.Comment.'#cdata-section' } } diff --git a/Public/Get-GPOZaurrLink.ps1 b/Public/Get-GPOZaurrLink.ps1 index 6fe8e33..3dfaf64 100644 --- a/Public/Get-GPOZaurrLink.ps1 +++ b/Public/Get-GPOZaurrLink.ps1 @@ -4,11 +4,12 @@ [parameter(ValueFromPipeline, ValueFromPipelineByPropertyName)][Microsoft.ActiveDirectory.Management.ADObject[]] $ADObject, [switch] $Limited, [System.Collections.IDictionary] $GPOCache, - - [string] $Filter = '*', + # weirdly enough site doesn't really work this way unless you give it 'CN=Configuration,DC=ad,DC=evotec,DC=xyz' as SearchBase + [string] $Filter = "(objectClass -eq 'organizationalUnit' -or objectClass -eq 'domainDNS' -or objectClass -eq 'site')", [string] $SearchBase, [Microsoft.ActiveDirectory.Management.ADSearchScope] $SearchScope, + [validateset('Root', 'DomainControllers', 'Site', 'Other')][string] $Linked, [alias('ForestName')][string] $Forest, [string[]] $ExcludeDomains, @@ -29,27 +30,95 @@ } Process { if (-not $ADObject) { - foreach ($Domain in $ForestInformation.Domains) { - $Splat = @{ - Filter = $Filter - Properties = 'distinguishedName', 'gplink', 'CanonicalName' - Server = $ForestInformation['QueryServers'][$Domain]['HostName'][0] - } - if ($PSBoundParameters.ContainsKey('SearchBase')) { - $DomainDistinguishedName = $ForestInformation['DomainsExtended'][$Domain]['DistinguishedName'] - if ($SearchBase -notlike "*$DomainDistinguishedName") { - # we check if SearchBase is part of domain distinugishname. If it isn't we skip - continue + if ($Linked) { + foreach ($Domain in $ForestInformation.Domains) { + $Splat = @{ + #Filter = $Filter + Properties = 'distinguishedName', 'gplink', 'CanonicalName' + # Filter = "(objectClass -eq 'organizationalUnit' -or objectClass -eq 'domainDNS' -or objectClass -eq 'site')" + Server = $ForestInformation['QueryServers'][$Domain]['HostName'][0] + } + if ($Linked -contains 'DomainControllers') { + $SearchBase = $ForestInformation['DomainsExtended'][$Domain]['DomainControllersContainer'] + #if ($SearchBase -notlike "*$DomainDistinguishedName") { + # we check if SearchBase is part of domain distinugishname. If it isn't we skip + # continue + #} + $Splat['Filter'] = "(objectClass -eq 'organizationalUnit')" + $Splat['SearchBase'] = $SearchBase + Get-ADObject @Splat | ForEach-Object -Process { + Get-PrivGPOZaurrLink -Object $_ -Limited:$Limited.IsPresent -GPOCache $GPOCache + } + } + if ($Linked -contains 'Root') { + $SearchBase = $ForestInformation['DomainsExtended'][$Domain]['DistinguishedName'] + #if ($SearchBase -notlike "*$DomainDistinguishedName") { + # we check if SearchBase is part of domain distinugishname. If it isn't we skip + # continue + # } + $Splat['Filter'] = "objectClass -eq 'domainDNS'" + $Splat['SearchBase'] = $SearchBase + Get-ADObject @Splat | ForEach-Object -Process { + Get-PrivGPOZaurrLink -Object $_ -Limited:$Limited.IsPresent -GPOCache $GPOCache + } + } + if ($Linked -contains 'Site') { + # Sites are defined only in primary domain + if ($ForestInformation['DomainsExtended'][$Domain]['DNSRoot'] -eq $ForestInformation['DomainsExtended'][$Domain]['Forest']) { + $SearchBase = -join ("CN=Configuration,", $ForestInformation['DomainsExtended'][$Domain]['DistinguishedName']) + # if ($SearchBase -notlike "*$DomainDistinguishedName") { + # we check if SearchBase is part of domain distinugishname. If it isn't we skip + #continue + #} + $Splat['Filter'] = "(objectClass -eq 'site')" + $Splat['SearchBase'] = $SearchBase + Get-ADObject @Splat | ForEach-Object -Process { + Get-PrivGPOZaurrLink -Object $_ -Limited:$Limited.IsPresent -GPOCache $GPOCache + } + } + } + if ($Linked -contains 'Other') { + $SearchBase = $ForestInformation['DomainsExtended'][$Domain]['DistinguishedName'] + #if ($SearchBase -notlike "*$DomainDistinguishedName") { + # we check if SearchBase is part of domain distinugishname. If it isn't we skip + # continue + #} + $Splat['Filter'] = "(objectClass -eq 'organizationalUnit')" + $Splat['SearchBase'] = $SearchBase + Get-ADObject @Splat | ForEach-Object -Process { + if ($_.DistinguishedName -eq $ForestInformation['DomainsExtended'][$Domain]['DistinguishedName']) { + # other skips Domain Root + } elseif ($_.DistinguishedName -eq $ForestInformation['DomainsExtended'][$Domain]['DomainControllersContainer']) { + # other skips Domain Controllers + } else { + Get-PrivGPOZaurrLink -Object $_ -Limited:$Limited.IsPresent -GPOCache $GPOCache + } + } } - $Splat['SearchBase'] = $SearchBase - - } - if ($PSBoundParameters.ContainsKey('SearchScope')) { - $Splat['SearchScope'] = $SearchScope } + } else { + foreach ($Domain in $ForestInformation.Domains) { + $Splat = @{ + Filter = $Filter + Properties = 'distinguishedName', 'gplink', 'CanonicalName' + Server = $ForestInformation['QueryServers'][$Domain]['HostName'][0] + } + if ($PSBoundParameters.ContainsKey('SearchBase')) { + $DomainDistinguishedName = $ForestInformation['DomainsExtended'][$Domain]['DistinguishedName'] + if ($SearchBase -notlike "*$DomainDistinguishedName") { + # we check if SearchBase is part of domain distinugishname. If it isn't we skip + continue + } + $Splat['SearchBase'] = $SearchBase - Get-ADObject @Splat | ForEach-Object { - Get-PrivGPOZaurrLink -Object $_ -Limited:$Limited.IsPresent -GPOCache $GPOCache + } + if ($PSBoundParameters.ContainsKey('SearchScope')) { + $Splat['SearchScope'] = $SearchScope + } + + Get-ADObject @Splat | ForEach-Object { + Get-PrivGPOZaurrLink -Object $_ -Limited:$Limited.IsPresent -GPOCache $GPOCache + } } } } else { diff --git a/Public/Get-GPOZaurrPermission.ps1 b/Public/Get-GPOZaurrPermission.ps1 index 3b1c6e6..3f9236b 100644 --- a/Public/Get-GPOZaurrPermission.ps1 +++ b/Public/Get-GPOZaurrPermission.ps1 @@ -7,7 +7,7 @@ [Parameter(ParameterSetName = 'GPOGUID')] [alias('GUID', 'GPOID')][string] $GPOGuid, - [validateSet('Unknown', 'All')][string[]] $Type = 'All', + [validateSet('Unknown', 'NotWellKnown', 'NotWellKnownAdministrative', 'NotAdministrative', 'Administrative','All')][string[]] $Type = 'All', [switch] $SkipWellKnown, [switch] $SkipAdministrative, diff --git a/Public/Invoke-GPOZaurrPermission.ps1 b/Public/Invoke-GPOZaurrPermission.ps1 new file mode 100644 index 0000000..d54b5e1 --- /dev/null +++ b/Public/Invoke-GPOZaurrPermission.ps1 @@ -0,0 +1,163 @@ +function Invoke-GPOZaurrPermission { + [cmdletBinding(SupportsShouldProcess)] + param( + [scriptblock] $PermissionRules, + [validateset('Root', 'DomainControllers', 'Site', 'Other')][string] $Linked, + [Microsoft.GroupPolicy.GPPermissionType[]] $IncludePermissionType, + [Microsoft.GroupPolicy.GPPermissionType[]] $ExcludePermissionType, + [validateSet('Unknown', 'NotWellKnown', 'NotWellKnownAdministrative', 'NotAdministrative', 'All')][string[]] $Type, + [Array] $ApprovedGroups, + [alias('Principal')][Array] $Trustee, + [Microsoft.GroupPolicy.GPPermissionType] $TrusteePermissionType, + [alias('PrincipalType')][validateset('DistinguishedName', 'Name', 'Sid')][string] $TrusteeType = 'DistinguishedName' + ) + Begin { + $ADAdministrativeGroups = Get-ADADministrativeGroups -Type DomainAdmins, EnterpriseAdmins -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExtendedForestInformation $ExtendedForestInformation + $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 + } + } + } + } + Process { + if ($PermissionRules) { + $Rules = & $PermissionRules + foreach ($Rule in $Rules) { + + #$Actions["$Rule."] + + 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 + } + } + #$RemoveRules = $Rules | Where-Object { $_.Action -eq 'Remove' } + #$AddRules = $Rules | Where-Object { $_.Action -eq 'Add' } + } + Get-GPOZaurrLink -Linked $Linked | ForEach-Object -Process { + $GPO = $_ + #$GPOPermissions = Get-GPOZaurrPermission -GPOGuid $_.GUID <#-IncludePermissionType $IncludePermissionType -ExcludePermissionType $ExcludePermissionType -Type $Type#> -IncludeGPOObject + + #foreach ($Permission in $Script:Actions.Keys) { + # $Script:Actions[$Permission] + #} + + 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 "Set-GPOZaurrOwner - 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 + } + } elseif ($Rule.Type -eq 'Default') { + Write-Verbose "Set-GPOZaurrOwner - 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 + } + continue + } + if ($Rule.Action -eq 'Remove') { + $GPOPermissions = Get-GPOZaurrPermission -GPOGuid $_.GUID -IncludePermissionType $Rule.IncludePermissionType -ExcludePermissionType $Rule.ExcludePermissionType -Type $Rule.Type -IncludeGPOObject + foreach ($Permission in $GPOPermissions) { + Remove-PrivPermission -Principal $Permission.Sid -PrincipalType Sid -GPOPermission $Permission -IncludePermissionType $Permission.Permission -IncludeDomains $GPO.DomainName + } + 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 $_.GUID -IncludeDomains $GPO.DomainName -Type $Rule.Type -PermissionType $Rule.IncludePermissionType -ADAdministrativeGroups $ADAdministrativeGroups + # } + } + } + + <# + foreach ($Rule in $Rules) { + if ($Rule.Action -eq 'Remove') { + foreach ($Permission in $GPOPermissions) { + + #$Permission + #Write-Verbose "Remove-GPOZaurrPermission1 - Removing permission $IncludePermissionType for $($Permission.Name) / $($Permission.Permission)" + Remove-PrivPermission -Principal $Permission.Sid -PrincipalType Sid -GPOPermission $Permission -IncludePermissionType $Permission.Permission + # $Permission + #Remove-GPOZaurrPermission -Type 'Default' -Principal $Permission.Sid - + } + } + if ($Rule.Action -eq 'Add') { + foreach ($Permission in $GPOPermissions) { + + } + } + } + #> + <# + Get-GPOZaurrPermission -GPOGuid $_.GUID -IncludePermissionType $IncludePermissionType -ExcludePermissionType $ExcludePermissionType -Type $Type -IncludeGPOObject | ForEach-Object { + $Permission = $_ + $Permission | Format-Table -a * + foreach ($Rule in $Rules) { + if ($Rule.Action -eq 'Remove') { + #$Permission + Write-Verbose "Remove-GPOZaurrPermission1 - Removing permission $IncludePermissionType for $($Permission.Name) / $($Permission.Permission)" + Remove-PrivPermission -Principal $Permission.Sid -PrincipalType Sid -GPOPermission $Permission -IncludePermissionType $Permission.Permission + # $Permission + #Remove-GPOZaurrPermission -Type 'Default' -Principal $Permission.Sid - + } + } + } + #> + } + } + End { + + } +} \ No newline at end of file diff --git a/Public/Remove-GPOPermission.ps1 b/Public/Remove-GPOPermission.ps1 new file mode 100644 index 0000000..a661cc7 --- /dev/null +++ b/Public/Remove-GPOPermission.ps1 @@ -0,0 +1,45 @@ +function Remove-GPOPermission { + [cmdletBinding()] + param( + [validateSet('Unknown', 'NotWellKnown', 'NotWellKnownAdministrative', 'Administrative', 'NotAdministrative', 'All')][string[]] $Type, + [Microsoft.GroupPolicy.GPPermissionType[]] $IncludePermissionType, + [Microsoft.GroupPolicy.GPPermissionType[]] $ExcludePermissionType + ) + + if ($Type) { + @{ + Action = 'Remove' + Type = $Type + IncludePermissionType = $IncludePermissionType + ExcludePermissionType = $ExcludePermissionType + } + } + <# + foreach ($T in $Type) { + foreach ($Permission in $IncludePermissionType) { + if ($T -eq 'NotWellKnownAdministrative') { + $Script:Actions[$Permission][$T] = $true + } elseif ($T -eq 'NotAdministrative') { + $Script:Actions[$Permission][$T] = $true + } + } + } + #> +} +<# +function Find-GPOPermission { + param( + $GPOPermissions, + [Microsoft.GroupPolicy.GPPermissionType[]] $IncludePermissionType, + [bool] $NotAdministrative, + [bool] $NotWellKnownAdministrative + ) + foreach ($Permission in $GPOPermissions) { + if ($Permission.Permission -in $IncludePermissionType) { + if ($NotAdministrative -and $NotWellKnownAdministrative) { + $Permission + } + } + } +} +#> \ No newline at end of file diff --git a/Public/Remove-GPOZaurrPermission.ps1 b/Public/Remove-GPOZaurrPermission.ps1 index 632d579..af2ed17 100644 --- a/Public/Remove-GPOZaurrPermission.ps1 +++ b/Public/Remove-GPOZaurrPermission.ps1 @@ -10,7 +10,7 @@ [string] $Principal, [validateset('DistinguishedName', 'Name', 'Sid')][string] $PrincipalType = 'DistinguishedName', - [validateset('Unknown', 'Named', 'NonAdministrative', 'Default')][string[]] $Type = 'Default', + [validateset('Unknown', 'Named', 'NotAdministrative', 'Default')][string[]] $Type = 'Default', [alias('PermissionType')][Microsoft.GroupPolicy.GPPermissionType[]] $IncludePermissionType, [Microsoft.GroupPolicy.GPPermissionType[]] $ExcludePermissionType, @@ -119,10 +119,12 @@ } #> } - if ($Type -contains 'NonAdministrative') { + 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 { @@ -154,6 +156,7 @@ } } } + #> } #Set-GPPermission -PermissionLevel None -TargetName $GPOPermission.Sid -Verbose -DomainName $GPOPermission.DomainName -Guid $GPOPermission.GUID #-WhatIf diff --git a/Public/Set-GPOOwner.ps1 b/Public/Set-GPOOwner.ps1 new file mode 100644 index 0000000..e1e9973 --- /dev/null +++ b/Public/Set-GPOOwner.ps1 @@ -0,0 +1,22 @@ +function Set-GPOOwner { + [cmdletBinding()] + param( + [validateset('Administrative', 'Default')][string] $Type = 'Default', + [string] $Principal + ) + if ($Type -eq 'Default') { + if ($Principal) { + @{ + Action = 'Owner' + Type = 'Default' + Principal = $Principal + } + } + } elseif ($Type -eq 'Administrative') { + @{ + Action = 'Owner' + Type = 'Administrative' + Principal = '' + } + } +} \ No newline at end of file diff --git a/Public/Set-GPOZaurrOwner.ps1 b/Public/Set-GPOZaurrOwner.ps1 index d41fbe6..6b3b1ac 100644 --- a/Public/Set-GPOZaurrOwner.ps1 +++ b/Public/Set-GPOZaurrOwner.ps1 @@ -2,7 +2,7 @@ [cmdletBinding(SupportsShouldProcess, DefaultParameterSetName = 'Type')] param( [Parameter(ParameterSetName = 'Type', Mandatory)] - [validateset('EmptyOrUnknown', 'NonAdministrative', 'All')][string[]] $Type, + [validateset('EmptyOrUnknown', 'NotAdministrative', 'All')][string[]] $Type, [Parameter(ParameterSetName = 'Named')][string] $GPOName, [Parameter(ParameterSetName = 'Named')][alias('GUID', 'GPOID')][string] $GPOGuid, @@ -43,32 +43,32 @@ # Regardless who is the owner it is overwritten if ($Principal) { Write-Verbose "Set-GPOZaurrOwner - Changing GPO: $($GPO.DisplayName) from domain: $($GPO.DomainName) from owner $($GPO.Owner)/$($GPO.OwnerSID) to $Principal" - Set-ADACLOwner -ADObject $GPO.DistinguishedName -Principal $DefaultPrincipal -Verbose:$false -WhatIf:$WhatIfPreference + Set-ADACLOwner -ADObject $GPO.GPODistinguishedName -Principal $Principal -Verbose:$false -WhatIf:$WhatIfPreference } else { $DefaultPrincipal = $ADAdministrativeGroups["$($GPO.DomainName)"]['DomainAdmins'] Write-Verbose "Set-GPOZaurrOwner - Changing GPO: $($GPO.DisplayName) from domain: $($GPO.DomainName) from owner $($GPO.Owner)/$($GPO.OwnerSID) to $DefaultPrincipal" - Set-ADACLOwner -ADObject $GPO.DistinguishedName -Principal $DefaultPrincipal -Verbose:$false -WhatIf:$WhatIfPreference - $Count++ - if ($Count -eq $LimitProcessing) { - break - } + Set-ADACLOwner -ADObject $GPO.GPODistinguishedName -Principal $DefaultPrincipal -Verbose:$false -WhatIf:$WhatIfPreference + } + $Count++ + if ($Count -eq $LimitProcessing) { + break } } - if ($Type -contains 'NonAdministrative' -and $Type -notcontains 'All') { + if ($Type -contains 'NotAdministrative' -and $Type -notcontains 'All') { if ($GPO.Owner) { $AdministrativeGroup = $ADAdministrativeGroups['ByNetBIOS']["$($GPO.Owner)"] if (-not $AdministrativeGroup) { if ($Principal) { Write-Verbose "Set-GPOZaurrOwner - Changing GPO: $($GPO.DisplayName) from domain: $($GPO.DomainName) from owner $($GPO.Owner)/$($GPO.OwnerSID) to $Principal" - Set-ADACLOwner -ADObject $GPO.DistinguishedName -Principal $DefaultPrincipal -Verbose:$false -WhatIf:$WhatIfPreference + Set-ADACLOwner -ADObject $GPO.GPODistinguishedName -Principal $DefaultPrincipal -Verbose:$false -WhatIf:$WhatIfPreference } else { $DefaultPrincipal = $ADAdministrativeGroups["$($GPO.DomainName)"]['DomainAdmins'] Write-Verbose "Set-GPOZaurrOwner - Changing GPO: $($GPO.DisplayName) from domain: $($GPO.DomainName) from owner $($GPO.Owner)/$($GPO.OwnerSID) to $DefaultPrincipal" - Set-ADACLOwner -ADObject $GPO.DistinguishedName -Principal $DefaultPrincipal -Verbose:$false -WhatIf:$WhatIfPreference - $Count++ - if ($Count -eq $LimitProcessing) { - break - } + Set-ADACLOwner -ADObject $GPO.GPODistinguishedName -Principal $DefaultPrincipal -Verbose:$false -WhatIf:$WhatIfPreference + } + $Count++ + if ($Count -eq $LimitProcessing) { + break } } } @@ -77,11 +77,11 @@ if ($null -eq $GPO.Owner) { if ($Principal) { Write-Verbose "Set-GPOZaurrOwner - Changing GPO: $($GPO.DisplayName) from domain: $($GPO.DomainName) from owner NULL/$($GPO.OwnerSID) to $Principal" - Set-ADACLOwner -ADObject $GPO.DistinguishedName -Principal $DefaultPrincipal -Verbose:$false -WhatIf:$WhatIfPreference + Set-ADACLOwner -ADObject $GPO.GPODistinguishedName -Principal $Principal -Verbose:$false -WhatIf:$WhatIfPreference } else { $DefaultPrincipal = $ADAdministrativeGroups["$($GPO.DomainName)"]['DomainAdmins'] Write-Verbose "Set-GPOZaurrOwner - Changing GPO: $($GPO.DisplayName) from domain: $($GPO.DomainName) from owner NULL/$($GPO.OwnerSID) to $DefaultPrincipal" - Set-ADACLOwner -ADObject $GPO.DistinguishedName -Principal $DefaultPrincipal -Verbose:$false -WhatIf:$WhatIfPreference + Set-ADACLOwner -ADObject $GPO.GPODistinguishedName -Principal $DefaultPrincipal -Verbose:$false -WhatIf:$WhatIfPreference } $Count++ if ($Count -eq $LimitProcessing) { @@ -95,11 +95,11 @@ $GPO = $_ if ($Principal) { Write-Verbose "Set-GPOZaurrOwner - Changing GPO: $($GPO.DisplayName) from domain: $($GPO.DomainName) from owner $($GPO.Owner)/$($GPO.OwnerSID) to $Principal" - Set-ADACLOwner -ADObject $GPO.DistinguishedName -Principal $Principal -Verbose:$false -WhatIf:$WhatIfPreference + Set-ADACLOwner -ADObject $GPO.GPODistinguishedName -Principal $Principal -Verbose:$false -WhatIf:$WhatIfPreference } else { $DefaultPrincipal = $ADAdministrativeGroups["$($GPO.DomainName)"]['DomainAdmins'] Write-Verbose "Set-GPOZaurrOwner - Changing GPO: $($GPO.DisplayName) from domain: $($GPO.DomainName) from owner $($GPO.Owner)/$($GPO.OwnerSID) to $DefaultPrincipal" - Set-ADACLOwner -ADObject $GPO.DistinguishedName -Principal $DefaultPrincipal -Verbose:$false -WhatIf:$WhatIfPreference + Set-ADACLOwner -ADObject $GPO.GPODistinguishedName -Principal $DefaultPrincipal -Verbose:$false -WhatIf:$WhatIfPreference } $Count++ if ($Count -eq $LimitProcessing) {