Skip to content

Instantly share code, notes, and snippets.

@tmap
Created December 11, 2024 09:52
Show Gist options
  • Save tmap/ebac0f0a80a15f0182ba238c7772af94 to your computer and use it in GitHub Desktop.
Save tmap/ebac0f0a80a15f0182ba238c7772af94 to your computer and use it in GitHub Desktop.
function Get-CertificateTemplateAccess {
[CmdletBinding()]
param(
[Parameter(Mandatory=$false)]
[string]$TemplateName = "*",
[Parameter(Mandatory=$false)]
[string]$IdentityReference = "*",
[Parameter(Mandatory=$false)]
[string]$AccessRights = "*",
[Parameter(Mandatory=$false)]
[switch]$RiskyAce,
[Parameter(Mandatory=$false)]
[switch]$ExcludeDefaultAdmins,
[Parameter(Mandatory=$false)]
[string]$Domain
)
# Check PowerShell version and set compatibility variables
$isPSCore = $PSVersionTable.PSVersion.Major -ge 6
if ($isPSCore) {
Write-Host "This cmdlet only supports Windows Powershell 5"
Return
}
# Get the current domain and configuration naming context
$CurrentDomain = (Get-ADDomain -Server $Domain).NetBIOSName
$ConfigNC = (Get-ADRootDSE -Server $Domain).configurationNamingContext
# Get all certificate templates
$templates = Get-ADObject -Server $Domain -Filter "objectClass -eq 'pKICertificateTemplate'" -SearchBase "CN=Certificate Templates,CN=Public Key Services,CN=Services,$ConfigNC" -Properties DisplayName, nTSecurityDescriptor |
Where-Object { $_.DisplayName -like $TemplateName }
foreach ($template in $templates) {
$acl = $template.nTSecurityDescriptor
foreach ($ace in $acl.Access) {
$includeEntry = $true
# Store SID and try to resolve to name
$sid = $ace.IdentityReference
$identityName = $sid # Default to SID if name cannot be resolved
if ($sid -match '^S-') { # Basic SID format check
try {
$adObject = Get-ADObject -Server $Domain -Filter { ObjectSID -eq $sid } -Properties Name -ErrorAction Stop
if ($adObject) {
$identityName = $adObject.Name
}
} catch {
# If translation fails, keep $identityName as the SID
}
}
# Apply filters
if ($ExcludeDefaultAdmins) {
$excludedPattern = "Enterprise Admins|Domain Admins|$CurrentDomain\Domain Controllers"
if ($identityName -match $excludedPattern) {
$includeEntry = $false
}
}
if ($RiskyAce) {
if ($ace.ActiveDirectoryRights -notmatch 'GenericAll|WriteDacl|WriteOwner') {
$includeEntry = $false
}
}
if ($identityName -notlike $IdentityReference) {
$includeEntry = $false
}
if ($ace.ActiveDirectoryRights -notlike $AccessRights) {
$includeEntry = $false
}
if ($includeEntry) {
$template | Select-Object -Property @{Name='TemplateName';Expression={$_.DisplayName}},
@{Name='Access';Expression={$ace.ActiveDirectoryRights}},
@{Name='SID';Expression={$sid}},
@{Name='IdentityName';Expression={$identityName}},
@{Name='AccessControlType';Expression={$ace.AccessControlType}},
@{Name='IsInherited';Expression={$ace.IsInherited}},
@{Name='InheritanceFlags';Expression={$ace.InheritanceFlags}},
@{Name='PropagationFlags';Expression={$ace.PropagationFlags}},
@{Name='Owner';Expression={$acl.Owner}}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment