-
Notifications
You must be signed in to change notification settings - Fork 30
/
Copy pathFind-Certificate.ps1
93 lines (79 loc) · 4.16 KB
/
Find-Certificate.ps1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
<#
.SYNOPSIS
Searches a certificate store for certificates.
.OUTPUTS
System.Security.Cryptography.X509Certificates.X509Certificate2[] of found certificates.
.LINK
https://msdn.microsoft.com/library/system.security.cryptography.x509certificates.x509findtype.aspx
.LINK
https://msdn.microsoft.com/library/ms148581.aspx
.LINK
https://msdn.microsoft.com/library/system.security.cryptography.x509certificates.x509certificate2.aspx
.EXAMPLE
Find-Certificate.ps1 -FindValue ExampleCert -FindType FindBySubjectName -StoreName TrustedPeople -StoreLocation LocalMachine
Searches Cert:\LocalMachine\TrustedPeople for a certificate with a subject name of "ExampleCert".
.EXAMPLE
Find-Certificate.ps1 ExampleCert FindBySubjectName TrustedPeople LocalMachine
Uses positional parameters to search Cert:\LocalMachine\TrustedPeople for a cert with subject of "ExampleCert".
#>
#Requires -Version 3
[CmdletBinding()][OutputType([Security.Cryptography.X509Certificates.X509Certificate2[]])] Param(
<#
The value to search for, usually a string.
For a FindType of FindByTimeValid, FindByTimeNotYetValid, or FindByTimeExpired, the FindValue must be a datetime.
For a FindType of FindByApplicationPolicy or FindByCertificatePolicy, the FindValue can be a string or a System.Security.Cryptography.Oid.
For a FindType of FindByKeyUsage, the FindValue can be a string or an int bitmask.
#>
[Parameter(Position=0,Mandatory=$true)][Alias('Certificate','Value')] $FindValue,
<#
The field of the certificate to compare to FindValue.
e.g. FindBySubjectName, FindByKeyUsage, FindByIssuerDistinguishedName
For a FindType of FindByTimeValid, FindByTimeNotYetValid, or FindByTimeExpired, the FindValue should be a datetime.
For a FindType of FindByApplicationPolicy or FindByCertificatePolicy, the FindValue can be a string or a System.Security.Cryptography.Oid.
For a FindType of FindByKeyUsage, the FindValue can be a string or an int bitmask.
Omitting a FindType or StoreName will search all stores and common fields.
#>
[Parameter(Position=1)][Alias('Type','Field')][Security.Cryptography.X509Certificates.X509FindType] $FindType,
<#
The name of the certificate store to search.
e.g. My, TrustedPeople, Root
Omitting a FindType or StoreName will search all stores and common fields.
#>
[Parameter(Position=2)][Security.Cryptography.X509Certificates.StoreName] $StoreName,
<#
Whether to search the certificates of the CurrentUser or the LocalMachine.
Uses LocalMachine by default.
#>
[Parameter(Position=3)][Security.Cryptography.X509Certificates.StoreLocation] $StoreLocation = 'LocalMachine',
# Whether to further filter search results by checking the effective and expiration dates.
[Alias('Current')][switch] $Valid,
# Whether to further filter search results by excluding certificates marked as archived.
[switch] $NotArchived,
# Whether to throw an error if a certificate is not found.
[switch] $Require
)
$cert =
if(!($StoreName -and $FindType))
{
Write-Verbose "Find '$FindValue'"
$now = Get-Date
Get-ChildItem Cert:\CurrentUser,Cert:\LocalMachine |
ForEach-Object {Get-ChildItem "Cert:\$($_.Location)\$($_.Name)"} |
Where-Object {!$NotArchived -or !$_.Archived} |
Where-Object {$_.Subject,$_.Issuer,$_.Thumbprint |Where-Object {$_ -like "*$FindValue*"}} |
Where-Object {!$Valid -or ($now -ge $_.NotBefore -and $now -le $_.NotAfter)}
}
else
{
if(('FindByTimeValid','FindByTimeNotYetValid','FindByTimeExpired' -contains $FindType) -and ($FindValue -is [string]))
{ [datetime] $FindValue = $FindValue }
Write-Verbose "$FindType '$FindValue' ($($FindValue.GetType().Name)) in $StoreLocation\$StoreName"
$store = New-Object Security.Cryptography.X509Certificates.X509Store $StoreName,$StoreLocation
[void] $store.Open('OpenExistingOnly')
$found = $store.Certificates.Find($FindType,$FindValue,$Valid)
[void] $store.Close()
$store = $null
$found |Where-Object {!$NotArchived -or !$_.Archived}
}
if($Require -and !$cert) {throw "Could not find certificate $FindType $FindValue in $StoreLocation $StoreName"}
$cert