ADCSTemplateParser.psm1

function Get-SidfromHex {
    param
    (
        [string]$Sid
    )
    $ByteSid = New-Object Byte[] 150

    for ($i = 0; $i -lt $Sid.Length ; $i += 2) {
       $ByteSid.Set(($i/2),([Byte]::Parse($Sid.Substring($i, 2), [System.Globalization.NumberStyles]::HexNumber)))
    }
    New-Object System.Security.Principal.SecurityIdentifier($ByteSid,0)
}

function Get-NtSecurityDescriptor { 
    param
    (
        [string]$SecurityDescriptor
    )
    $ntsecdesc = New-Object Byte[] ($SecurityDescriptor.Length)

    for ($i = 0; $i -lt $SecurityDescriptor.Length ; $i += 2) {
        $ntsecdesc.Set(($i/2),([Byte]::Parse($SecurityDescriptor.Substring($i, 2), [System.Globalization.NumberStyles]::HexNumber)))
    }

    [System.Security.AccessControl.RawSecurityDescriptor]::new($ntsecdesc,0)
}

function Get-ATPTemplate
{
    param
    (
        [String]$TemplateFile
    )
    $Contents = Get-Content $TemplateFile -Raw
    $temp = @{}
    $templates = @{}
    [regex]::Matches($Contents,'\[(.+?)\]')| ForEach-Object {$templates[$_.Value.replace('[','').replace(']','')]=@()}
    foreach ($key in $($templates.Keys)) {$temp[$key] = [regex]::Match($Contents,'\[' + ($key) + '\]' + '(?>.+?|\n)+?\r\n\r\n\r\n')}
    foreach ($template in $($temp.Keys)) {
        $temp.$template.Value|Out-File "$env:TEMP\temptemplate.txt" -Force
        Switch -Regex -File ("$env:TEMP\temptemplate.txt") {
            '\s*(.+?)\s*=\s*"(.*?)"(?:,\s"?(.*?)")?.*?(.*)' {
                $name,$value1,$value2,$hex = $matches[1..4]
                if ($value2) {$Value = "$value1, $value2"} else {$Value = $value1}
                $templates[$template] += [pscustomobject]@{
                    'Name' = $name
                    'Value' = $Value
                    'Second value' = $hex
                } 
            }        
        
        }
        Remove-Item -Path "$env:TEMP\temptemplate.txt" -Force

        $description = [regex]::Matches([regex]::Match($temp.$template.Value,'nTSecurityDescriptor\s=(.*?|\n)+05 0b 00 00 00').Value,'(?:[0-9a-fA-F]{2}\s[0-9a-fA-F]{2}\s)+')|% {$_.Value}
        if ($description) {
            $templates[$template] += [pscustomobject]@{
                        'Name' = 'nTSecurityDescriptor'
                        'Value' = Get-NtSecurityDescriptor -SecurityDescriptor (-split($description) -join '')
                        
            }
        }
    }
        
    $templates
}