Skip to content

Instantly share code, notes, and snippets.

@emmaly
Created February 7, 2024 02:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save emmaly/1cd451e112d31c6da2c921b8f7dca2ed to your computer and use it in GitHub Desktop.
Save emmaly/1cd451e112d31c6da2c921b8f7dca2ed to your computer and use it in GitHub Desktop.
Convert-ACLToCustomObject
function Convert-ACLToCustomObject {
param ([Parameter(Mandatory = $true)]$ACL)
# Define a custom type
class CustomADObject {
[object]$ADObject
[string]$Guid
CustomADObject([object]$ADObject, [string]$Guid) {
$this.ADObject = $ADObject
$this.Guid = $Guid
}
[string] ToString() {
if ($this.ADObject -and $this.ADObject.adminDisplayName) {
return $this.ADObject.adminDisplayName
} elseif ($this.Guid -ne "00000000-0000-0000-0000-000000000000") {
return $this.Guid
}
return $null
}
}
# Define our cache
$ADObjectCache = @{}
# Helper function to get ADObject by SchemaIdGuid
function Get-ADObjectBySchemaIdGuid {
[CmdletBinding()]
param (
[Parameter(Mandatory = $true)]
[string]$SchemaIdGuid
)
process {
try {
# Return $null if the GUID is all zeroes
if ($SchemaIdGuid -eq "00000000-0000-0000-0000-000000000000") {
return $null
}
$byteArray = [Guid]::Parse($SchemaIdGuid).ToByteArray()
$ldapGuid = ""
foreach ($byte in $byteArray) {
$ldapGuid += "\" + $byte.ToString("X2")
}
$schemaObject = Get-ADObject -SearchBase (Get-ADRootDSE).schemaNamingContext -LDAPFilter "(schemaIDGUID=$ldapGuid)" -Properties *
if ($schemaObject) {
return $schemaObject
} else {
# Write-Warning "No object found with the specified GUID: $SchemaIdGuid"
return $null
}
} catch {
Write-Error "An error occurred: $_"
}
}
}
# Helper function to process the GUID
function ProcessGuid {
param ([string]$Guid)
# Get the ADObject via the caching function
$object = Get-CachedADObjectByGuid $Guid
# Return a new CustomADObject
return [CustomADObject]::new($object, $Guid)
}
# Helper function to get ADObject with caching, including caching misses
function Get-CachedADObjectByGuid {
param ([string]$Guid)
# Check if the cache contains the key
if (-not $ADObjectCache.ContainsKey($Guid)) {
# Store either the ADObject or $null if not found
$ADObjectCache[$Guid] = Get-ADObjectBySchemaIdGuid -SchemaIdGuid $Guid
}
# Return the cached result (could be an ADObject or $null)
return $ADObjectCache[$Guid]
}
# Process each ACL entry
$ACL.Access | ForEach-Object {
# Get object types using the caching function
$objectType = ProcessGuid $_.ObjectType
$inheritedObjectType = ProcessGuid $_.InheritedObjectType
# Construct the resulting final custom object with the properties
[PSCustomObject]@{
IdentityReference = $_.IdentityReference
ObjectType = $objectType
ObjectFlags = $_.ObjectFlags
InheritedObjectType = $inheritedObjectType
InheritanceType = $_.InheritanceType
IsInherited = $_.IsInherited
InheritanceFlags = $_.InheritanceFlags
AccessControlType = $_.AccessControlType
ActiveDirectoryRights = $_.ActiveDirectoryRights
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment