authorized root certificates, list
for current user:
dir Cert:\CurrentUser\AuthRoot
for Local Machine:
dir Cert:\LocalMachine\AuthRoot
CA property type information – not all that useful unless you’re curious about what properties are available
certutil -capropinfo
only works if you’re already on the server housing the CA. Otherwise:
CertUtil: No local Certification Authority; use -config option
CertUtil: No more data is available.
exports the CA database and private key information to the specified path
Backup-CARoleService -Path "C:\CABackup"
exports the CA database to the specified path, does not back up the CA private key information.
Backup-CARoleService -Path "C:\CABackup" -DatabaseOnly
exports the CA private key information to the specified path, does not back up the CA database.
Backup-CARoleService -Path "C:\CABackup" -KeyOnly
This only pops up a form with an interactive list from which to choose. And if you inspect that list. If you actually pick one of the lines in the list with your mouse, then it’ll display the server in the command line so you can copy that to supply to the inevitable requests to supply the name of that server when you issue other commands but aren’t actually on that server.
certutil -config - -ping
And then it just hangs there waiting for you to select one
or exit the command. If you just run certutil
all by itself,
it’ll give you the info you want as just a bunch of lines,
along with a bunch of other information
that’s probably irrelevant most of the time. Below ought to work to
get more targeted info. It’s kind of clunky trying to extract the
pertinent info - especially since it displays one way in server 2016
and different delimiters in 2012 R2, but it works so far.
$result
=
@()
foreach
($line
in
(certutil)) {
if
($line
-like
"Entry*") {
$entry
= (($line
-split
" ")[1] -split
":")[0]
}
elseif
($line
-like
"
Name:*") {
$name
= ($line
-split
'"')[1]
if
($null
-eq
$name) {
# if the line above didn't get anything,
then Server 2012 R2 delineates begin "`" end "'"
$name
= ($line
-split
'`')[1]
$name
= ($name
-split
"'")[0]
}
}
elseif
($line
-like
" Server:*") {
$server
= ($line
-split
'"')[1]
if
($null
-eq
$server) {
# if the line above didn't get anything, then Server 2012 R2
delineates begin "`" end "'"
$server
= ($line
-split
'`')[1]
$server
= ($server
-split
"'")[0]
}
$result
+=
New-Object
-TypeName PSObject -Property
@{
entry
=
$entry
name
=
$name
server
=
$server}
}
}
$result
=
$result | select entry,
name, server
$result
| ft
certificate, inspect – see inspect cert, openSSL, inspect
certificate, properties – see inspect cert, openSSL, inspect
certificates, find – see – see also file location of certs, list all certs residing on local PC, local certificate, verify
find all certs on local machine suitable to sign code
Get-ChildItem Cert:\LocalMachine\My -Recurse | ? {$_.EnhancedKeyUsages -contains "Code Signing"}
find cert for a script
Get-AuthenticodeSignature -FilePath "C:\Jobs\myscript.ps1"
if it isn’t signed, it will return one row saying so
current user, list all certs for
$certs
=
Get-ChildItem
-Path Cert:\CurrentUser\My
$certs
|
select Subject,
NotAfter,
FriendlyName,
Issuer
|
ft
-a
delete all local machine certs – see also delete one local machine cert, export all local machine certs, import all local machine certs, import one local machine cert, import one local machine cert and display its thumbprint
$certs
=
Get-ChildItem
-Path Cert:\LocalMachine\My
foreach
($cert
in
$certs) {
Remove-Item
-Path "Cert:\LocalMachine\My\$($cert.Thumbprint)"
-Force
}
verify they’re all gone
certutil -verifystore MY
It’s possible one or more remain that show up
when you run the command above but which don’t show up in the console.
If so, see hidden certs, remove
where you’ll use the thumbprint from the certutil -verifystore MY
command you just ran.
delete one local machine cert – see also export all local machine certs, import all local machine certs, import one local machine cert, import one local machine cert and display its thumbprint
$issuedTo
=
"Test-CA"
$cert
=
Get-ChildItem
-Path Cert:\LocalMachine\My
|
?
{$_.Subject
-like
"*CN=$issuedTo*"}
if
($cert) {
Remove-Item
-Path
"Cert:\LocalMachine\My\$($cert.Thumbprint)"
-Force
Write-Host
"Certificate with 'Issued To'
$issuedTo
has been deleted."
-ForegroundColor Green
}
else
{
Write-Host
"Certificate
with 'Issued To'
$issuedTo not found."
-ForegroundColor Red
}
digitally sign a script – see code signing
expires – when do the certificates on this machine expire?
$certs
=
Get-ChildItem
-Path Cert:\LocalMachine\My
$certs
|
select Subject,
NotAfter,
FriendlyName,
Issuer
|
ft
-a
export all local machine certs – see also delete all local machine certs, import all local machine certs, import one local machine cert, import one local machine cert and display its thumbprint
export each cert in local certs to a file suitable to import later with the file name corresponding to the “Issued To” field when viewed in the console
$certs
=
Get-ChildItem
-Path Cert:\LocalMachine\My
foreach
($cert
in
$certs) {
$issuedTo
=
($cert.Subject
-split
",")[0]
-replace
"CN=",
""
-replace
"[^a-zA-Z0-9]",
" "
$certPath
=
"C:\certExports\$issuedTo.cer"
Export-Certificate
-Cert
$cert
-FilePath
$certPath
}
- Current User Certificates
- Public keys:
$env:APPDATA\Microsoft\SystemCertificates\My\Certificates
- Private keys:
$env:APPDATA\Microsoft\Crypto\RSA
- Public keys:
- Local Machine Certificates
- Public keys:
$env:ProgramData\Microsoft\SystemCertificates\My\Certificates
- Private keys:
$env:ProgramData\Microsoft\Crypto\RSA
- Public keys:
if you run command to look at local computer personal certs
certutil -verifystore MY
and then compare with what you see when you look in the console,
you may see extra certs that show up in the command that don’t show up
in the console. If you want remove one of those hidden certs, look for a
line beginning with “Cert Hash(sha1)
”. This is the same as the
cert’s thumbprint. You’ll need that for the next command
which deletes this cert:
Remove-Item -Path Cert:\LocalMachine\My\dec8e0e89a5c5fa6c2faa2e8cc8da47664ee1d3b -DeleteKey
replacing “dec8e0e89a5c5fa6c2faa2e8cc8da47664ee1d3b
” above with the
cert’s thumbprint.
import all local machine certs – see also delete all local machine certs, export all local machine certs, import all local machine certs, import one local machine cert, import one local machine cert and display its thumbprint
$certFiles
=
Get-ChildItem
-Path C:\certExports\*.cer
foreach
($certFile
in
$certFiles) {
Import-Certificate
-FilePath $certFile.FullName
-CertStoreLocation Cert:\LocalMachine\My
}
import one local machine cert – see also delete all local machine certs, export all local machine certs, import all local machine certs, import one local machine cert and display its thumbprint
Import-Certificate -FilePath "C:\certExports\test CA 1.cer" -CertStoreLocation Cert:\LocalMachine\My
or a more complicated way which seems to do about the same:
$certPath
=
"C:\certs\testcert.cer"
$certs
=
New-Object
System.Security.Cryptography.X509Certificates.X509Certificate2Collection
$certs.Import($certPath)
$personalStore
=
New-ObjectSystem.Security.Cryptography.X509Certificates.X509Store("My",
"LocalMachine")
$personalStore.Open("ReadWrite")
$personalStore.AddRange($certs)
$personalStore.Close()
import one local machine cert and display its thumbprint – see also delete all local machine certs, export all local machine certs, import all local machine certs,
this shows the thumbprint but doesn’t import
$certPath
=
"C:\certExports\test CA 1.cer"
$cert
=
New-Object
System.Security.Cryptography.X509Certificates.X509Certificate2
$cert.Import($certPath)
$thumbprint
=
$cert.Thumbprint
Write-Host
"Thumbprint:
$thumbprint"
running this immediately after finishes by importing
Import-Certificate -FilePath $certPath -CertStoreLocation Cert:\LocalMachine\My
Verify the Certificate in the Store
gci -Path Cert:\LocalMachine\My | ? {$_.Thumbprint -eq $thumbprint} | select Thumbprint, Subject, NotAfter, FriendlyName | ft -a
import certificate chain – cert file often ends with "p7b"
into local machine \ computer
Import-Certificate -FilePath "C:\Path\To\Your\CertificateChain.p7b" -CertStoreLocation "Cert:\LocalMachine\My"
Traverse all the branches and leaves of a certificate
and discover nested properties with a recursive function.
This function will iterate through each property and, if it finds an object, it will dive deeper into its properties.
Store each property encountered as a custom object in array “$results
”.
Append 2 spaces at the beginning of each displayed property
for each additional nesting level beyond the top level.
IndentLevel
parameter is used to calculate the indentation string.
Each object in the results array includes the indentation string to format the output properly.
This also has special code to handle System.Security.Cryptography.Oid
objects.
function
Get-Properties
{
param
(
[Parameter(Mandatory=$true)]
[psobject]$Object,
[string]$Prefix
=
"",
[int]$IndentLevel
=
0
)
$results
=
@()
$indent
=
" "
*
$IndentLevel
$Object
|
Get-Member
-MemberType Properties | % {
$property
=
$_.Name
$value
=
$Object.$property
$indentedProperty
=
"$indent$Prefix$property"
if
($value
-is
[System.Collections.IEnumerable]
-and
-not
($value
-is
[string])) {
$results
+=
[pscustomobject]@{Property
=
$indentedProperty;
Value
=
""}
foreach
($item
in
$value) {$results
+=
Get-Properties
-Object
$item
-Prefix
"$Prefix$property."
-IndentLevel ($IndentLevel
+
1)}
}
elseif
($value
-is
[psobject]) {
$results
+=
[pscustomobject]@{Property
=
$indentedProperty;
Value
=
""}
$results
+=
Get-Properties
-Object
$value
-Prefix
"$Prefix$property."
-IndentLevel ($IndentLevel
+
1)
}
elseif
($value
-is
[System.Security.Cryptography.Oid]) {
$results
+=
[pscustomobject]@{Property
=
$indentedProperty;
Value
=
""}
$results
+=
[pscustomobject]@{Property
=
"$indentedProperty.FriendlyName";
Value
=
$value.FriendlyName}
$results
+=
[pscustomobject]@{Property
=
"$indentedProperty.Value";
Value
=
$value.Value}
}
else
{$results
+=
[pscustomobject]@{Property
=
$indentedProperty;
Value
=
$value}}
}
return
$results
}
$cert
=
Get-ChildItem
-Path Cert:\LocalMachine\My
|
Select-Object
-First
1
$properties
=
Get-Properties
-Object
$cert
$properties
|
ft
-a
|
Out-String
|
Set-Clipboard
# Export to clipboard
$properties
|
ogv
intermediate CA certificate store, view
pops up a form with a list
certutil -enterprise -viewstore CA
same window whether or not you include the ending “CA”
key missing – see key, repair
key, repair – see also private key missing or not available on the server
specify the cert subject. You can also omit the leading
“CN=
” and replace “-eq
”
with “-like
”
$keySubject = "CN=maltesefalcon.net"
Find the certificate thumbprint
$cert
=
gci
-Path Cert:\LocalMachine\My
|
?
{$_.Subject
-eq
"$keySubject"}
$thumbprint
=
$cert.Thumbprint
run certutil to repair the store to associate the private key with the certificate
certutil
-repairstore my $thumbprint
$cert
=
Get-ChildItem
-Path Cert:\LocalMachine\My
|
?
{$_.Subject
-eq
"$keySubject"}
After running the repair command, verify that the certificate now has the private key
if
($cert.HasPrivateKey) {Write-Host
"The certificate has a private key."
-ForegroundColor Green}
else {Write-Host
"The certificate does not have a private key."
-ForegroundColor Red}
list all certs for or available to local computer – see also file location of certs, list all certs residing on local PC local certificate, verify
$certs
=
Get-ChildItem
-Path Cert:\
-Recurse
$certs.Count
$certs
|
Get-Member
|
?
{$_.MemberType
-like
"*property*"}
$certs
|
select PSPath,
Issuer
|
ogv
This lists all certs for or available to your local PC; this isn’t the same as the certs residing on your local PC, which are likely fewer.
certutil -viewstore "My"
will pop up a screen showing local cert, check certificate path tab
list all certs residing on local PC – see also file location of certs, list all certs for or available to local computer
lists all certs certs residing on your local PC; this isn’t the same as the certs for or available to your local PC, which are likely more.
Get-ChildItem -Path "Cert:\LocalMachine\My" | Select Thumbprint, Subject, NotAfter, FriendlyName | ogv
or
Set-Location
Cert:\LocalMachine\My
Get-ChildItem
|
Select Thumbprint,
Subject,
NotAfter,FriendlyName
or, lists local certs, whether they are End-Entity, Intermediate or Root, their thumbprint and whether they have a private key. See also .pfx file, examine certs which has very similar logic, except it’s getting the same info from the pfx file from which these certs may have been imported.
$certs
=
Get-ChildItem
-Path
Cert:\LocalMachine\My
$certs
|
%
{
if
($_.HasPrivateKey) {$color
=
"Green";
$text
=
"has"}
else
{$color
=
"Red";
$text
=
"does NOT have"}
# if $pfxData.EndEntityCertificates -contains $_ returns True if
the current certificate ($_) is in the EndEntityCertificates collection,
indicating that it is an end-entity certificate.
if
($pfxData.EndEntityCertificates
-contains
$_) {$type
=
"End-Entity"}
# if subject = issuer, self-signed and means root.
elseif
($_.Subject
-eq
$_.Issuer) {$type
=
"Root"}
else
{$type
=
"Intermediate"}
Write-Host
$type
-ForegroundColor Yellow
-NoNewline
Write-Host
" certificate
"
-NoNewline
Write-Host
"$($_.Subject) "
-ForegroundColor Cyan -NoNewline
Write-Host
"thumbprint
"
-NoNewline
Write-Host
"$($_.Thumbprint)
"
-ForegroundColor Magenta
-NoNewline
Write-Host
$text
-ForegroundColor
$color
-NoNewline
Write-Host
" a private key"
}
OpenSSL, download – see also OpenSSL module, install
OpenSSL’s download page only lists tar.gz files. Shining Light has EXE and MSI. After download and install, inspect path to see whether it’s been added (probably not):
$Env:Path -split(";") | sort $_
and add if necessary
$Env:Path += ";C:\Program Files\OpenSSL-Win64\bin"
$path
=
"C:\certs\Dragoon.pem"
openssl
x509
-in
$path
-text
-noout
OpenSSL module, install – see also OpenSSL, download
I haven’t had much luck installing this module so have resorted to downloading and installing OpenSSL instead.
Install-Module -Name OpenSSL
after the obligatory
Untrusted repository
You are installing the modules from an untrusted repository. If you trust this repository, change its InstallationPolicy value by running the Set-PSRepository cmdlet. Are you sure you want to
install the modules from 'PSGallery'?
[Y] Yes [A] Yes to All [N] No
[L] No to All [S] Suspend [?] Help (default is "N"): y
returns
Install-Package: The following commands are already available on this system:'Get-Certificate,New-SelfSignedCertificate'. This module 'OpenSSL' may override the existing commands. If you still want to install this module 'OpenSSL', use -AllowClobber parameter.
when I go on to
Install-Module -Name OpenSSL -AllowClobber
immediately came back to the command prompt, not giving much assurance that it was really installed. When I run:
Get-Module
the module doesn’t show
Find-Module -Name OpenSSL
shows one from the PSGallery Repository. Run
Set-PSRepository -Name PSGallery -InstallationPolicy Trusted
seems to work (no error, anyway) but running
Install-Module -Name OpenSSL -AllowClobber
still fails to show the module after running
Get-Module
again. So, I gave up.
p7b file, import into certs – see import certificate chain
.pfx file, examine certs – see also list all certs residing on local PC, inspect cert, openSSL, inspect
$password
=
ConvertTo-SecureString
-String
"topsecret"
-AsPlainText -Force
$pfxData
=
Get-PfxData
-FilePath
"C:\certs\test.pfx"
-Password
$password
$pfxData.EndEntityCertificates
+$pfxData.OtherCertificates
|
%
{
if
($_.HasPrivateKey) {$color
=
"Green";
$text
=
"has"}
else
{$color
=
"Red";
$text
=
"does NOT have"}
# if $pfxData.EndEntityCertificates -contains $_ returns True if
the current certificate ($_) is in the EndEntityCertificates collection,
indicating that it is an end-entity certificate.
if
($pfxData.EndEntityCertificates
-contains
$_) {$type
=
"End-Entity"}
# if subject = issuer, self-signed and means root.
elseif
($_.Subject
-eq
$_.Issuer) {$type
=
"Root"}
else
{$type
=
"Intermediate"}
Write-Host
$type
-ForegroundColor Yellow
-NoNewline
Write-Host
" certificate
"
-NoNewline
Write-Host
"$($_.Subject)
"
-ForegroundColor Cyan
-NoNewline
Write-Host
"thumbprint
"
-NoNewline
Write-Host
"$($_.Thumbprint)
"
-ForegroundColor Magenta
-NoNewline
Write-Host
$text
-ForegroundColor
$color
-NoNewline
Write-Host
" a private key"
}
.pfx file, inspect certs – see .pfx file, examine certs, also list all certs residing on local PC, inspect cert, openSSL, inspect
private key missing or not available on the server – see also key, repair
Check to see if your cert can see the private key
$cert
=
Get-ChildItem
-Path Cert:\LocalMachine\My |
?
{$_.Subject
-like
"*test*"}
$keyContainer
=
$cert.PrivateKey.CspKeyContainerInfo.UniqueKeyContainerName
$keyPath
=
"C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys\$keyContainer"
if
(Test-Path
$keyPath) {Write-Host
"The private
key is available on the server."
-ForegroundColor Green}
else
{Write-Host
"The private
key is not available on the server."
-ForegroundColor Red}
get the serial number
certutil -store My
fix using the serial number you get from the
certutil store My
command above
certutil -repairstore My "70000816489e16f675d0202321000000081648"
properties of certificate – see inspect cert, openSSL, inspect
repair key – see private key missing or not available on the server, key, repair
script, digitally sign – see code signing
$cert
=
New-SelfSignedCertificate
-Type CodeSigningCert
-DnsName
"basketweaving.edu"
-CertStoreLocation
"Cert:\LocalMachine\My"
Export-PfxCertificate
-Cert
$cert
-FilePath "C:\scripts\DSC.pfx"
-Password (ConvertTo-SecureString
-String
"password"
-Force
-AsPlainText)
server where certificate authority resides – see certificate authority, find
thumbprint, get from cert – see also delete all local machine certs, import all local machine certs, import one local machine cert
if the “Issued to” in the console is “test CA 1”
$issuedTo
=
"test CA 1"
$cert
=
Get-ChildItem
-Path Cert:\LocalMachine\My
|
?
{$_.Subject
-like
"*CN=$issuedTo*"}
$thumbprint
=
$cert.Thumbprint
Write-Host
some commands, such as
certutil -verifystore MY
don’t return any properties that are obviously a thumbprint.
The command above returns records that include “Cert Hash(sha1):
”
followed by a string of hex characters though, which is the same as the thumbprint.
pops up a form with a list
certutil -enterprise -viewstore Root
If you don’t include the ending “Root”, seems to default to default to what you’d get if you instead specified “CA” at the end.
user, current, list all certs for – see current user, list all certs for
verify certificates in local store
returns True
or False
.
Also verifies if you have a chain (root - intermediate - local).
$cert
=
Get-ChildItem
-Path Cert:\LocalMachine\My |
?
{$_.Subject
-like
"*MyCert*"}
Test-Certificate
-Cert
$cert
gives a lot more detail
certutil -verifystore MY
“You have a private key that corresponds to this certificate.” is missing