Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Identifying Certificate by "Certificate Template Name" in PowerShell

I need to use a PowerShell script to pick the certificate with "Certificate Template Name" as "Machine." In certmgr.msc, this has "Certificate Template" with value of "Computer." In Details, the same one has "Certificate Template Name" as "Machine."

How can I use either of these values in a PowerShell script?

Thus far, I have:

get-childitem cert:\localmachine\my | where-object {$_.}

I've tried just about every method that intellisense loads, but have not been able to find anything that meets my needs.

Thank You,

like image 498
SauerTrout Avatar asked Apr 10 '17 15:04

SauerTrout


People also ask

How do I find certificate template name?

In the MMC, double-click the CA name, right-click Certificate Templates, and then click Manage. The Certificate Templates console opens. All of the certificate templates are displayed in the details pane.

How do I find certificate information in PowerShell?

You can access the certificate store using MMC or using CertMgr. msc command. There are certificates stored for CurrentUser, ServiceAccount, and Local Computer. To access the certificate store using PowerShell, you need to access the PSDrive, and Certificates are stored in the drive called Cert as you can see below.

How do I get a certificate name with thumbprint?

The certificate can also be found using MMC by searching using the harsh algorithm used (e.g. SHA1). Right-click Certificates (Local Computer) in MMC > Find Certificates, and pick the hash algorithm under Look in Field, with the thumbprint in the Contains box. The gif below covers both methods mentioned.

What is certificate template?

A certificate template defines the policies and rules that a CA uses when a request for a certificate is received. Many built-in templates can be viewed using the Certificate Templates snap-in (see Figure 12.17).


3 Answers

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) }}
like image 96
SauerTrout Avatar answered Oct 17 '22 01:10

SauerTrout


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
        }
    }
}
like image 2
Leon Bouquiet Avatar answered Oct 17 '22 02:10

Leon Bouquiet


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
  }
}
like image 1
Slogmeister Extraordinaire Avatar answered Oct 17 '22 02:10

Slogmeister Extraordinaire