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,
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.
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.
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.
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).
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
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With