Identifying Certificate by "Certificate Template Name" in PowerShell Identifying Certificate by "Certificate Template Name" in PowerShell powershell powershell

Identifying Certificate by "Certificate Template Name" in PowerShell


Here is a solution sans-modules:

$templateName = 'Super Cool *'Get-ChildItem 'Cert:\LocalMachine\My' | Where-Object{ $_.Extensions | Where-Object{ ($_.Oid.FriendlyName -eq 'Certificate Template Information') -and ($_.Format(0) -match $templateName) }}


In addition to the answers already posted, let me share what works for me:

# Example usage:#   ls 'Cert:\LocalMachine\My' | ForEach-Object { Get-CertificateTemplateName $_ }#function Get-CertificateTemplateName($certificate){    # The template name is stored in the Extension data.     # If available, the best is the extension named "Certificate Template Name", since it contains the exact name.    $templateExt = $certificate.Extensions | Where-Object{ ( $_.Oid.FriendlyName -eq 'Certificate Template Name') } | Select-Object -First 1       if($templateExt) {        return $templateExt.Format(1)    }    else {        # Our fallback option is the "Certificate Template Information" extension, it contains the name as part of a string like:        # "Template=Web Server v2(1.3.6.1.4.1.311.21.8.2499889.12054413.13650051.8431889.13164297.111.14326010.6783216)"        $templateExt = $certificate.Extensions | Where-Object{ ( $_.Oid.FriendlyName -eq 'Certificate Template Information') } | Select-Object -First 1           if($templateExt) {            $information = $templateExt.Format(1)            # Extract just the template name in $Matches[1]            if($information -match "^Template=(.+)\([0-9\.]+\)") {                return $Matches[1]            } else {                # No regex match, just return the complete information then                return $information            }        } else {            # No template name found            return $null        }    }}


Here's a native PowerShell solution:

Thanks go to the PowerShell Gallery

<#.SYNOPSIS Outputs an object consisting of the template name (Template), an OID (OID), the minor version (MinorVersion), and the major version (MajorVersion)..DESCRIPTION Outputs an object consisting of the template name (Template), an OID (OID), the minor version (MinorVersion), and the major version (MajorVersion). This information is derived from the Certificate Extensions..PARAMETER Certificate A X509Certificate2 object.EXAMPLE Get-ChildItem "Cert:\LocalMachine\My" | Get-CertificateTemplate.EXAMPLE Get-ChildItem "Cert:\LocalMachine\My" | Select-Object Name,Thumbprint,@{Name="Template";Expression={Get-CertificateTemplate $_}}.INPUTS Any X509Certificate2 object.OUTPUTS [PSCustomObject] @{Template=<template name; OID=<oid string>; MajorVersion=<major version num>; MinorVersion=<minor version num> }#>function Get-CertificateTemplate {  [CmdletBinding(SupportsShouldProcess=$false)]  [OutputType([string])]  Param([Parameter(Mandatory=$true, ValueFromPipeline=$true)] [ValidateNotNull()] [Security.Cryptography.X509Certificates.X509Certificate2]$Certificate)  Process {    $regExPrimary=[System.Text.RegularExpressions.Regex]::new("Template=([\w\s\d\.]+)\(((?:\d+.)+)\), Major Version Number=(\d+), Minor Version Number=(\d+)",[System.Text.RegularExpressions.RegexOptions]::None)    $regExSecondary=[System.Text.RegularExpressions.Regex]::new("Template=((?:\d+.)+), Major Version Number=(\d+), Minor Version Number=(\d+)",[System.Text.RegularExpressions.RegexOptions]::None)    $temp = $Certificate.Extensions | Where-Object { $_.Oid.FriendlyName -eq "Certificate Template Name" }    if ($temp -eq $null) {      Write-Verbose "Did not find 'Certificate Template Name' extension"      $temp=$Certificate.Extensions | Where-Object { $_.Oid.Value -eq "1.3.6.1.4.1.311.21.7" }    }    else { Write-Verbose "Found 'Certificate Template Name' extension" }    $Matches=$regExPrimary.Matches($temp.Format($false))    if ($Matches.Count -gt 0) {      $object=@{Template=$Matches[0].Groups[1].Value; OID=$Matches[0].Groups[2].Value;                 MajorVersion=$Matches[0].Groups[3].Value; MinorVersion=$Matches[0].Groups[4].Value;                Thumbprint=$Certificate.Thumbprint }    }    else {      $Matches=$regExSecondary.Matches($temp.Format($false))      if ($Matches.Count -gt 0) {        Write-Verbose "Found certificate without a valid Template Name"        $object=@{Template=$Matches[0].Groups[1].Value; OID=$Matches[0].Groups[1].Value;                   MajorVersion=$Matches[0].Groups[2].Value; MinorVersion=$Matches[0].Groups[3].Value;                  Thumbprint=$Certificate.Thumbprint }      }      else {        Write-Verbose "Found root certificate"        $object=@{Template="Root Certificate"; OID=""; MajorVersion=""; MinorVersion=""; Thumbprint=$Certificate.Thumbprint }      }    }    return [PSCustomObject]$object  }}