mirror of
https://github.com/EvotecIT/GPOZaurr.git
synced 2026-07-26 11:49:17 +00:00
423 lines
19 KiB
PowerShell
423 lines
19 KiB
PowerShell
function Get-PrivPermission {
|
|
<#
|
|
.SYNOPSIS
|
|
Retrieves permissions for a specified Group Policy Object (GPO) based on various criteria.
|
|
|
|
.DESCRIPTION
|
|
This function retrieves permissions for a specified Group Policy Object (GPO) based on the provided parameters. It allows filtering by principal, permission type, and other criteria.
|
|
|
|
.PARAMETER GPO
|
|
Specifies the Group Policy Object (GPO) for which permissions will be retrieved.
|
|
|
|
.PARAMETER SecurityRights
|
|
Specifies the security rights to be evaluated for the GPO.
|
|
|
|
.PARAMETER Principal
|
|
Specifies the principal for which permissions will be retrieved.
|
|
|
|
.PARAMETER PrincipalType
|
|
Specifies the type of principal to filter by. Valid values are 'DistinguishedName', 'Name', 'NetbiosName', or 'Sid'.
|
|
|
|
.PARAMETER SkipWellKnown
|
|
Skips well-known principals when evaluating permissions.
|
|
|
|
.PARAMETER SkipAdministrative
|
|
Skips administrative principals when evaluating permissions.
|
|
|
|
.PARAMETER IncludeOwner
|
|
Includes the owner of the GPO in the permission results.
|
|
|
|
.PARAMETER IncludePermissionType
|
|
Specifies the permission types to include in the results.
|
|
|
|
.PARAMETER ExcludePermissionType
|
|
Specifies the permission types to exclude from the results.
|
|
|
|
.PARAMETER PermitType
|
|
Specifies the type of permissions to include. Valid values are 'Allow', 'Deny', or 'All'.
|
|
|
|
.PARAMETER ExcludePrincipal
|
|
Specifies principals to exclude from the results.
|
|
|
|
.PARAMETER ExcludePrincipalType
|
|
Specifies the type of principal to exclude. Valid values are 'DistinguishedName', 'Name', or 'Sid'.
|
|
|
|
.PARAMETER IncludeGPOObject
|
|
Includes the GPO object in the permission results.
|
|
|
|
.PARAMETER ADAdministrativeGroups
|
|
Specifies the Active Directory administrative groups to consider.
|
|
|
|
.PARAMETER Type
|
|
Specifies the type of principals to include. Valid values are 'AuthenticatedUsers', 'DomainComputers', 'Unknown', 'WellKnownAdministrative', 'NotWellKnown', 'NotWellKnownAdministrative', 'NotAdministrative', 'Administrative', or 'All'.
|
|
|
|
.PARAMETER ExtendedForestInformation
|
|
Specifies extended forest information to be used in evaluation.
|
|
|
|
.EXAMPLE
|
|
Get-PrivPermission -GPO $GPO -SecurityRights $SecurityRights -Principal 'Domain Admins' -PrincipalType 'Name' -PermitType 'Allow'
|
|
|
|
Retrieves permissions for the specified GPO where 'Domain Admins' have 'Allow' permissions.
|
|
|
|
.EXAMPLE
|
|
Get-PrivPermission -GPO $GPO -SecurityRights $SecurityRights -Principal 'S-1-5-21-3623811015-3361044348-30300820-1013' -PrincipalType 'Sid' -PermitType 'Deny'
|
|
|
|
Retrieves permissions for the specified GPO where the principal with the SID 'S-1-5-21-3623811015-3361044348-30300820-1013' has 'Deny' permissions.
|
|
#>
|
|
[cmdletBinding()]
|
|
param(
|
|
[Microsoft.GroupPolicy.Gpo] $GPO,
|
|
[Object] $SecurityRights,
|
|
|
|
[string[]] $Principal,
|
|
[validateset('DistinguishedName', 'Name', 'NetbiosName', 'Sid')][string] $PrincipalType = 'Sid',
|
|
|
|
[switch] $SkipWellKnown,
|
|
[switch] $SkipAdministrative,
|
|
[switch] $IncludeOwner,
|
|
[Microsoft.GroupPolicy.GPPermissionType[]] $IncludePermissionType,
|
|
[Microsoft.GroupPolicy.GPPermissionType[]] $ExcludePermissionType,
|
|
[validateSet('Allow', 'Deny', 'All')][string] $PermitType = 'All',
|
|
|
|
[string[]] $ExcludePrincipal,
|
|
[validateset('DistinguishedName', 'Name', 'Sid')][string] $ExcludePrincipalType = 'Sid',
|
|
|
|
[switch] $IncludeGPOObject,
|
|
[System.Collections.IDictionary] $ADAdministrativeGroups,
|
|
[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 | ForEach-Object -Process {
|
|
$GPOPermission = $_
|
|
if ($PermitType -ne 'All') {
|
|
if ($PermitType -eq 'Deny') {
|
|
if ($GPOPermission.Denied -eq $false) {
|
|
return
|
|
}
|
|
} else {
|
|
if ($GPOPermission.Denied -eq $true) {
|
|
return
|
|
}
|
|
}
|
|
}
|
|
if ($ExcludePermissionType -contains $GPOPermission.Permission) {
|
|
return
|
|
}
|
|
if ($IncludePermissionType) {
|
|
if ($IncludePermissionType -notcontains $GPOPermission.Permission) {
|
|
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') {
|
|
if ($GPOPermission.Trustee.SidType -eq 'WellKnownGroup') {
|
|
return
|
|
}
|
|
}
|
|
if ($SkipAdministrative.IsPresent -or $Type -contains 'NotAdministrative') {
|
|
$IsAdministrative = $ADAdministrativeGroups['BySID'][$GPOPermission.Trustee.Sid.Value]
|
|
if ($IsAdministrative) {
|
|
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 '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 ($GPOPermission.Trustee.Domain) {
|
|
$UserMerge = -join ($GPOPermission.Trustee.Domain, '\', $GPOPermission.Trustee.Name)
|
|
} else {
|
|
$UserMerge = $null
|
|
}
|
|
if ($Principal) {
|
|
if ($PrincipalType -eq 'Sid') {
|
|
if ($Principal -notcontains $GPOPermission.Trustee.Sid.Value) {
|
|
return
|
|
}
|
|
} elseif ($PrincipalType -eq 'DistinguishedName') {
|
|
if ($Principal -notcontains $GPOPermission.Trustee.DSPath) {
|
|
return
|
|
}
|
|
} elseif ($PrincipalType -eq 'Name') {
|
|
if ($Principal -notcontains $GPOPermission.Trustee.Name) {
|
|
return
|
|
}
|
|
} elseif ($PrincipalType -eq 'NetbiosName') {
|
|
if ($Principal -notcontains $UserMerge) {
|
|
return
|
|
}
|
|
}
|
|
}
|
|
if ($ExcludePrincipal) {
|
|
if ($ExcludePrincipalType -eq 'Sid') {
|
|
if ($ExcludePrincipal -contains $GPOPermission.Trustee.Sid.Value) {
|
|
return
|
|
}
|
|
} elseif ($ExcludePrincipalType -eq 'DistinguishedName') {
|
|
if ($ExcludePrincipal -contains $GPOPermission.Trustee.DSPath) {
|
|
return
|
|
}
|
|
} elseif ($ExcludePrincipalType -eq 'Name') {
|
|
if ($ExcludePrincipal -contains $GPOPermission.Trustee.Name) {
|
|
return
|
|
}
|
|
} elseif ($ExcludePrincipalType -eq 'NetbiosName') {
|
|
if ($ExcludePrincipal -contains $UserMerge) {
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
<#
|
|
# Sets permissions name, domain, distinguishedname to proper values
|
|
if ($GPOPermission.Trustee.Name) {
|
|
$DomainPlusName = -join ($GPOPermission.Trustee.Domain, '\', $GPOPermission.Trustee.Name)
|
|
if ($GPOPermission.Trustee.DSPath) {
|
|
$NetbiosConversion = ConvertFrom-NetbiosName -Identity $DomainPlusName
|
|
if ($NetbiosConversion.DomainName) {
|
|
$UserNameDomain = $NetbiosConversion.DomainName
|
|
$UserName = $NetbiosConversion.Name
|
|
}
|
|
} else {
|
|
$UserNameDomain = ''
|
|
$Username = $DomainPlusName
|
|
}
|
|
} else {
|
|
$DomainPlusName = ''
|
|
$UserNameDomain = ''
|
|
$Username = ''
|
|
}
|
|
#>
|
|
|
|
# I don't trust the returned data, some stuff like 'alias' shows up for groups. To unify it with everything else... using my own function
|
|
$PermissionAccount = Get-WinADObject -Identity $GPOPermission.Trustee.Sid.Value -AddType -Cache -Verbose:$false
|
|
if ($PermissionAccount) {
|
|
$UserNameDomain = $PermissionAccount.DomainName
|
|
$UserName = $PermissionAccount.Name
|
|
$SidType = $PermissionAccount.Type
|
|
$ObjectClass = $PermissionAccount.ObjectClass
|
|
} else {
|
|
$ConvertFromSID = ConvertFrom-SID -SID $GPOPermission.Trustee.Sid.Value
|
|
$UserNameDomain = ''
|
|
$Username = $ConvertFromSID.Name
|
|
$SidType = $ConvertFromSID.Type
|
|
if ($SidType -eq 'Unknown') {
|
|
$ObjectClass = 'unknown'
|
|
} else {
|
|
$ObjectClass = 'foreignSecurityPrincipal'
|
|
}
|
|
}
|
|
$ReturnObject = [ordered] @{
|
|
DisplayName = $GPO.DisplayName # : ALL | Enable RDP
|
|
GUID = $GPO.ID
|
|
DomainName = $GPO.DomainName # : ad.evotec.xyz
|
|
Enabled = $GPO.GpoStatus
|
|
Description = $GPO.Description
|
|
CreationDate = $GPO.CreationTime
|
|
ModificationTime = $GPO.ModificationTime
|
|
PermissionType = if ($GPOPermission.Denied -eq $true) { 'Deny' } else { 'Allow' }
|
|
Permission = $GPOPermission.Permission # : GpoEditDeleteModifySecurity
|
|
Inherited = $GPOPermission.Inherited # : False
|
|
PrincipalNetBiosName = $UserMerge
|
|
PrincipalDistinguishedName = $GPOPermission.Trustee.DSPath #: CN = Domain Admins, CN = Users, DC = ad, DC = evotec, DC = xyz
|
|
PrincipalDomainName = $UserNameDomain #: EVOTEC
|
|
PrincipalName = $UserName #: Domain Admins
|
|
PrincipalSid = $GPOPermission.Trustee.Sid.Value #: S - 1 - 5 - 21 - 853615985 - 2870445339 - 3163598659 - 512
|
|
PrincipalSidType = $SidType #$GPOPermission.Trustee.SidType #: Group
|
|
PrincipalObjectClass = $ObjectClass
|
|
}
|
|
|
|
|
|
if ($IncludeGPOObject) {
|
|
$ReturnObject['GPOObject'] = $GPO
|
|
$ReturnObject['GPOSecurity'] = $SecurityRights
|
|
$ReturnObject['GPOSecurityPermissionItem'] = $GPOPermission
|
|
}
|
|
[PSCustomObject] $ReturnObject
|
|
}
|
|
if ($IncludeOwner) {
|
|
if ($GPO.Owner) {
|
|
# I don't trust the returned data, some stuff like 'alias' shows up for groups. To unify it with everything else... using my own function
|
|
$OwnerAccount = Get-WinADObject -Identity $GPO.Owner -AddType -Cache -Verbose:$false
|
|
if ($OwnerAccount) {
|
|
$UserNameDomain = $OwnerAccount.DomainName
|
|
$UserName = $OwnerAccount.Name
|
|
$SidType = $OwnerAccount.Type
|
|
$OwnerObjectClass = $OwnerAccount.ObjectClass
|
|
$SID = $OwnerAccount.ObjectSID
|
|
} else {
|
|
$ConvertFromSID = ConvertFrom-SID -SID $GPO.Owner
|
|
$UserNameDomain = ''
|
|
$Username = $ConvertFromSID.Name
|
|
$SidType = $ConvertFromSID.Type
|
|
if ($SidType -eq 'Unknown') {
|
|
$OwnerObjectClass = 'unknown'
|
|
} else {
|
|
$OwnerObjectClass = 'foreignSecurityPrincipal'
|
|
}
|
|
$SID = $ConvertFromSID.SID
|
|
}
|
|
} else {
|
|
$UserName = ''
|
|
$UserNameDomain = ''
|
|
$SID = ''
|
|
$SIDType = 'Unknown'
|
|
$DistinguishedName = ''
|
|
$OwnerObjectClass = 'unknown'
|
|
}
|
|
# We have to process it for owners after querying user because $Owners are not as established as standard permissions so we don't know a lot
|
|
|
|
if ($Type -contains 'Administrative' -and $Type -notcontains 'All') {
|
|
if ($SID) {
|
|
$IsAdministrative = $ADAdministrativeGroups['BySID'][$SID]
|
|
if (-not $IsAdministrative) {
|
|
return
|
|
}
|
|
} else {
|
|
# if there is no SID, it's not administrative
|
|
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 ($SID -eq 'S-1-5-18') {
|
|
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 ($SID -ne 'S-1-5-18') {
|
|
return
|
|
}
|
|
}
|
|
if ($Type -contains 'Unknown' -and $Type -notcontains 'All') {
|
|
# May need updates if there's more types
|
|
if ($SidType -ne 'Unknown') {
|
|
return
|
|
}
|
|
}
|
|
if ($Type -contains 'AuthenticatedUsers' -and $Type -notcontains 'All') {
|
|
if ($SID -ne 'S-1-5-11') {
|
|
return
|
|
}
|
|
}
|
|
if ($Type -contains 'DomainComputers' -and $Type -notcontains 'All') {
|
|
$DomainComputersSID = -join ($ExtendedForestInformation['DomainsExtended'][$GPO.DomainName].DomainSID, '-515')
|
|
if ($SID -ne $DomainComputersSID) {
|
|
return
|
|
}
|
|
}
|
|
|
|
if ($Principal) {
|
|
if ($PrincipalType -eq 'Sid') {
|
|
if ($Principal -notcontains $SID) {
|
|
return
|
|
}
|
|
} elseif ($PrincipalType -eq 'DistinguishedName') {
|
|
if ($Principal -notcontains $DistinguishedName) {
|
|
return
|
|
}
|
|
} elseif ($PrincipalType -eq 'Name') {
|
|
if ($Principal -notcontains $UserName) {
|
|
return
|
|
}
|
|
} elseif ($PrincipalType -eq 'NetbiosName') {
|
|
if ($Principal -notcontains $GPO.Owner) {
|
|
return
|
|
}
|
|
}
|
|
}
|
|
if ($ExcludePrincipal) {
|
|
if ($ExcludePrincipalType -eq 'Sid') {
|
|
if ($ExcludePrincipal -contains $SID) {
|
|
return
|
|
}
|
|
} elseif ($ExcludePrincipalType -eq 'DistinguishedName') {
|
|
if ($ExcludePrincipal -contains $DistinguishedName) {
|
|
return
|
|
}
|
|
} elseif ($ExcludePrincipalType -eq 'Name') {
|
|
if ($ExcludePrincipal -contains $UserName) {
|
|
return
|
|
}
|
|
} elseif ($ExcludePrincipalType -eq 'NetbiosName') {
|
|
if ($ExcludePrincipal -contains $GPO.Owner) {
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
$ReturnObject = [ordered] @{
|
|
DisplayName = $GPO.DisplayName # : ALL | Enable RDP
|
|
GUID = $GPO.Id
|
|
DomainName = $GPO.DomainName # : ad.evotec.xyz
|
|
Enabled = $GPO.GpoStatus
|
|
Description = $GPO.Description
|
|
CreationDate = $GPO.CreationTime
|
|
ModificationTime = $GPO.ModificationTime
|
|
PermissionType = 'Allow'
|
|
Permission = 'GpoOwner' # : GpoEditDeleteModifySecurity
|
|
Inherited = $false # : False
|
|
PrincipalNetBiosName = $GPO.Owner
|
|
PrincipalDistinguishedName = $DistinguishedName #: CN = Domain Admins, CN = Users, DC = ad, DC = evotec, DC = xyz
|
|
PrincipalDomainName = $UserNameDomain
|
|
PrincipalName = $UserName
|
|
PrincipalSid = $SID #: S - 1 - 5 - 21 - 853615985 - 2870445339 - 3163598659 - 512
|
|
PrincipalSidType = $SIDType # #: Group
|
|
PrincipalObjectClass = $OwnerObjectClass
|
|
}
|
|
if ($IncludeGPOObject) {
|
|
$ReturnObject['GPOObject'] = $GPO
|
|
$ReturnObject['GPOSecurity'] = $SecurityRights
|
|
$ReturnObject['GPOSecurityPermissionItem'] = $null
|
|
}
|
|
[PSCustomObject] $ReturnObject
|
|
}
|
|
}
|
|
End {
|
|
|
|
}
|
|
} |