Private/Get-ADCSTemplate.ps1
Function Get-ADCSTemplate { <# .SYNOPSIS Returns properties of Active Directory Certificate Template(s). .DESCRIPTION Retrieves properties of one or all Active Directory Certificate Templates from the Configuration Naming Context. Supports pipeline input and credential delegation. .PARAMETER DisplayName Name of the certificate template to retrieve. If omitted, returns all templates. .PARAMETER Server FQDN of Active Directory Domain Controller to target. If not specified, discovers nearest writable DC. .INPUTS System.String You can pipe the DisplayName parameter to this function. .OUTPUTS Microsoft.ActiveDirectory.Management.ADEntity Returns Active Directory objects representing the certificate templates. .EXAMPLE Get-ADCSTemplate Returns all certificate templates. .EXAMPLE Get-ADCSTemplate -DisplayName 'PowerShellCMS' Returns specific template named 'PowerShellCMS'. .EXAMPLE Get-ADCSTemplate | Sort-Object Name | Format-Table Name, Created, Modified Lists all templates sorted by name showing creation and modification dates. .EXAMPLE 'WebServer','UserCert' | Get-ADCSTemplate Returns templates via pipeline input. .NOTES Used Functions: Name ║ Module/Namespace ════════════════════════════════════════╬══════════════════════════════ Get-ADObject ║ ActiveDirectory Get-ADDomainController ║ ActiveDirectory Write-Progress ║ Microsoft.PowerShell.Utility Write-Verbose ║ Microsoft.PowerShell.Utility Write-Debug ║ Microsoft.PowerShell.Utility Write-Warning ║ Microsoft.PowerShell.Utility Write-Error ║ Microsoft.PowerShell.Utility Get-FunctionDisplay ║ EguibarIT .NOTES Version: 2.1 DateModified: 22/May/2025 LastModifiedBy: Vicente Rodriguez Eguibar vicente@eguibar.com Eguibar IT http://www.eguibarit.com .LINK https://www.powershellgallery.com/packages/ADCSTemplate/1.0.1.0/Content/ADCSTemplate.psm1 https://github.com/PowerShell/xCertificate .LINK https://github.com/vreguibar/EguibarIT/blob/main/Private/Get-ADCSTemplate.ps1 .COMPONENT Active Directory Certificate Services .ROLE PKI Administration .FUNCTIONALITY Certificate Template Management #> [CmdletBinding( SupportsShouldProcess = $false, ConfirmImpact = 'Low' )] [OutputType([Microsoft.ActiveDirectory.Management.ADEntity])] param( [Parameter(Mandatory = $false, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, ValueFromRemainingArguments = $false, Position = 0)] [string] $DisplayName, [Parameter(Mandatory = $false, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, ValueFromRemainingArguments = $false, Position = 1)] [ValidateNotNullOrEmpty()] [Alias('DomainController', 'DC')] [string] $Server ) Begin { Set-StrictMode -Version Latest # Output header information if ($null -ne $Variables -and $null -ne $Variables.Header) { $txt = ($Variables.Header -f (Get-Date).ToString('dd/MMM/yyyy'), $MyInvocation.Mycommand, (Get-FunctionDisplay -HashTable $PsBoundParameters -Verbose:$False) ) Write-Verbose -Message $txt } #end if ############################## # Module imports Import-MyModule -ModuleName 'ActiveDirectory' -Verbose:$false ############################## # Variables Definition [hashtable]$Splat = [hashtable]::New([StringComparer]::OrdinalIgnoreCase) [hashtable]$GetDCParams = [hashtable]::New([StringComparer]::OrdinalIgnoreCase) [hashtable]$CommonParams = [hashtable]::New([StringComparer]::OrdinalIgnoreCase) try { # Get DC if not specified if (-not $PSBoundParameters.ContainsKey('Server')) { $GetDCParams = @{ Discover = $true ForceDiscover = $true Writable = $true ErrorAction = 'Stop' } $Server = (Get-ADDomainController @GetDCParams).HostName[0] Write-Verbose -Message ('Using Domain Controller: {0}' -f $Server) } #end If # Prepare common parameters $CommonParams = @{ Server = $Server ErrorAction = 'Stop' } } catch { Write-Error -Message ('Failed to initialize: {0}' -f $_.Exception.Message) return } #end Try } #end Begin Process { try { # Get template path from configuration NC $TemplatePath = 'CN=Certificate Templates,CN=Public Key Services,CN=Services,{0}' -f $Variables.configurationNamingContext # Process each template name if specified if ($PSBoundParameters.ContainsKey('DisplayName')) { $total = $DisplayName.Count $current = 0 foreach ($template in $DisplayName) { $current++ Write-Progress -Activity 'Processing Certificate Templates' ` -Status ('Processing template {0}' -f $template) ` -PercentComplete (($current / $total) * 100) $LDAPFilter = '(&(objectClass=pKICertificateTemplate)(displayName={0}))' -f $template Write-Verbose -Message ('Searching for template: {0}' -f $template) $Splat = @{ SearchScope = 'Subtree' SearchBase = $TemplatePath LDAPFilter = $LDAPFilter Properties = '*' } $Splat += $CommonParams $result = Get-ADObject @Splat if ($result) { Write-Verbose -Message ('Found template: {0}' -f $result.Name) Write-Debug -Message (' Template details: Created={0}, Modified={1}' -f $result.Created, $result.Modified ) $result } else { Write-Warning -Message ('Template not found: {0}' -f $template) } #end If-Else } #end ForEach Write-Progress -Activity 'Processing Certificate Templates' -Completed } else { # Get all templates Write-Verbose -Message 'Retrieving all certificate templates' $Splat = @{ SearchScope = 'Subtree' SearchBase = $TemplatePath LDAPFilter = '(objectClass=pKICertificateTemplate)' Properties = '*' } $Splat += $CommonParams $result = Get-ADObject @Splat Write-Verbose -Message ('Found {0} templates' -f $result.Count) $result } #end If-Else } catch [Microsoft.ActiveDirectory.Management.ADServerDownException] { Write-Error -Message ('Domain Controller {0} is not accessible' -f $Server) } catch [System.UnauthorizedAccessException] { Write-Error -Message 'Access denied. Check credentials and permissions' } catch { Write-Error -Message ('An error occurred: {0}' -f $_.Exception.Message) } #end Try-Catch } #end Process End { # Display function footer if variables exist if ($null -ne $Variables -and $null -ne $Variables.Footer) { $txt = ($Variables.Footer -f $MyInvocation.InvocationName, 'getting Cert Template (Private Function).' ) Write-Verbose -Message $txt } #end if } #end End } #end Function Get-ADCSTemplate |