Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create Get-PublishedTemplates #161

Closed
73 changes: 73 additions & 0 deletions Private/Get-PublishedTemplates.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
function Get-PublishedTemplates {
<#
.SYNOPSIS
Get published certificate templates from Active Directory.

.DESCRIPTION
Gets all templates from Active Directory and identifies which ones are published.

.EXAMPLE
Get-PublishedTemplates

.NOTES
If either of these flags are set, the template is considered published:
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your logic doesn't seem consistent with what's actually published, but it's very possible I'm missing something.

Your code returns this from my lab CA:
image

But the Certificate Templates list on my lab CA looks like this:
image

Which matches CA's object's cetificateTemplates attribute expanded:
image

Note: The Certificate Templates pane shows the templates displayName attribute while the expanded certificateTemplates list shows the name attribute.

This function should be rewritten to see if the template name exists within the certificateTemplates attribute on any pKIEnrollmentService object. We already collect the required attribute in Get-ADCSObject, so I think you could:

  1. Collect all the published template names from all the CA objects
  2. De-duplicate the list and store it as $PublishedTemplates
  3. Loop through the templates to see if $PublishedTemplates -contains $TemplateName
  4. Return $true or $false to enrich the template object as a custom attribute.

Or whatever you want to do. You probably have a more elegant way of doing it.

Copy link
Collaborator Author

@SamErde SamErde Sep 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thinking about de-duplicating the list and the possibility of different versions of a template being published on different CAs. Is that possible, and if so: does a published template on multiple CAs have the same OID for each instance, or a unique one per CA?

EDIT: I think I found that the answer is no to both questions. One version across all CAs and the same OID for the template on all CAs.


- CT_FLAG_IS_CA (0x1): This bit indicates whether the template is for a Certification Authority (CA). If this bit is set, the template is considered published.
- CT_FLAG_IS_DEFAULT (0x2): This bit indicates whether the template is a default template. If this bit is set, the template is also considered published.

If pkiEnrollmentFlag has 0x10 (CT_FLAG_PUBLISH_TO_DS) set, the certificate is published to Active Directory.
#>
[CmdletBinding()]
param (
# Use the ADCSObjects already found
[Parameter(Mandatory,ValueFromPipeline)]
$ADCSObjects
)

#region Get Templates With ADSI Searcher
$ADSISearcher = [adsisearcher]'(objectClass=*)'
$ADSISearcher.SearchRoot = [adsi]'LDAP://RootDSE'
$ConfigurationNamingContext = $ADSISearcher.SearchRoot.Properties['configurationNamingContext'][0]

# Set the [adsisearcher] filter, search root, and other options
$ADSISearcher = [adsisearcher]'(objectClass=pKICertificateTemplate)'
$ADSISearcher.SearchRoot = [ADSI]"LDAP://CN=Certificate Templates,CN=Public Key Services,CN=Services,$ConfigurationNamingContext"

$Results = $ADSISearcher.FindAll()

[array]$Templates = @()

foreach ($item in $Results) {
$Template = $item.GetDirectoryEntry()
$TemplateName = $Template.Properties['Name'][0]
$OID = $item.Properties['mspki-cert-template-oid'][0]
$Flags = $Template.Properties['flags'][0]
$EnrollmentFlag = $item.Properties['mspki-enrollment-flag'][0]
$LastModified = $item.Properties['whenchanged'][0]
$Revision = $item.Properties['Revision'][0]
$MinorRevision = $item.Properties['mspki-template-minor-revision'][0]

# Check if the template is published
$IsPublished = (($Flags -band 0x1) -ne 0 -or ($Flags -band 0x2) -ne 0) -or ($EnrollmentFlag -band 0x10)

$Templates += (
[PSCustomObject]@{
Name = $TemplateName
OID = $OID
Flags = $Flags
EnrollmentFlag = $EnrollmentFlag
IsPublished = $IsPublished
LastModified = $LastModified
Revision = $Revision
MinorRevision = $MinorRevision
}
)
}
#endregion Get Templates With ADSI Searcher

$Templates = $ADCSObjects.Where({$_.objectClass -eq 'pKICertificateTemplate'}) | Sort-Object Name
$PublishedTemplates = $ADCSObjects.Where({$_.displayName})


return $Templates | Where-Object {$_.IsPublished -eq $true}
}
Loading