ServiceCertStore.psm1
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 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 |
## Define default display set of properties for our custom service cert object down below ## Ref: https://learn-powershell.net/2013/08/03/quick-hits-set-the-default-property-display-in-powershell-on-custom-objects/ $svcCertDefaultDisplaySet = 'Thumbprint','Subject' $svcCertDefaultDisplayPropertySet = New-Object System.Management.Automation.PSPropertySet("DefaultDisplayPropertySet",[string[]]$svcCertDefaultDisplaySet) $svcCertPSStandardMembers = [System.Management.Automation.PSMemberInfo[]]@($svcCertDefaultDisplayPropertySet) <# .DESCRIPTION Returns a reference to an open service-specific certificate store. The caller is responsible for closing and disposing of the returned store reference. #> function Get-ServiceCertificateStore { [CmdletBinding()] [OutputType([System.Security.Cryptography.X509Certificates.X509Store])] param( [Parameter(Mandatory, Position = 0)] [string]$ServiceName, [Parameter(Position = 1)] [System.Security.Cryptography.X509Certificates.StoreName]$StoreName="My" ) return [Zyborg.Security.Cryptography.ServiceCertStore]::OpenStore($ServiceName, $StoreName) } <# .DESCRIPTION Returns zero or more certificates that are found in a service-specific certificate store. If you don't specifify any qualifier parameters, then all certificates in the named store for the named service will be returned. You can filter this resultset by specifying one or more qualifier parameters that must be matched on. #> function Get-ServiceCertificates { [CmdletBinding()] param( [Parameter(Mandatory, Position = 0)] [string]$ServiceName, [Parameter(Position = 1)] [System.Security.Cryptography.X509Certificates.StoreName]$StoreName="My", ## One or more qualifiers to filter the resultset [string[]]$Thumbprint, [string[]]$Subject ) $store = Get-ServiceCertificateStore $ServiceName $StoreName try { foreach ($c in $store.Certificates) { if ($Thumbprint -and -not ($c.$Thumbprint -in $Thumbprint)) { continue } if ($Subject -and -not ($c.Subject -in $Subject)) { continue } ## Create a lightweight version of the cert object so ## we can dispose of the realy thing before returning $svcCert = [pscustomobject]@{ EnhancedKeyUsageList = $c.EnhancedKeyUsageList DnsNameList = $c.DnsNameList SendAsTrustedIssuer = $c.SendAsTrustedIssuer Archived = $c.Archived Extensions = $c.Extensions FriendlyName = $c.FriendlyName IssuerName = $c.IssuerName NotAfter = $c.NotAfter NotBefore = $c.NotBefore HasPrivateKey = $c.HasPrivateKey PrivateKey = $c.PrivateKey PublicKey = $c.PublicKey RawData = $c.RawData SerialNumber = $c.SerialNumber SubjectName = $c.SubjectName SignatureAlgorithm = $c.SignatureAlgorithm Thumbprint = $c.Thumbprint Version = $c.Version Handle = $c.Handle Issuer = $c.Issuer Subject = $c.Subject } $c.Dispose() $svcCert | Add-Member MemberSet PSStandardMembers $svcCertPSStandardMembers Write-Output $svcCert } } finally { $store.Close() $store.Dispose() } } <# .DESCRIPTION Imports a new certificate identified by a file path or a `X509Certificate2` object instances into a service-specific certificate store. #> function Import-ServiceCertificate { [CmdletBinding(DefaultParameterSetName="FileImport")] param( [Parameter(Mandatory, Position = 0)] [string]$ServiceName, [Parameter(Mandatory, ParameterSetName="FileImport", Position = 1)] [string]$Path, [Parameter(ParameterSetName="FileImport")] [securestring]$Password, [Parameter(Mandatory, ParameterSetName="CertImport", Position = 1)] [System.Security.Cryptography.X509Certificates.X509Certificate2]$Certificate, [Parameter()] [System.Security.Cryptography.X509Certificates.StoreName]$StoreName="My" ) if ($Path) { $resolvedPath = Resolve-Path $Path if ($Password) { $cert = [System.Security.Cryptography.X509Certificates.X509Certificate2]::new( $resolvedPath.Path, $Password) } else { $cert = [System.Security.Cryptography.X509Certificates.X509Certificate2]::new( $resolvedPath.Path) } } else { $cert = $Certificate } try { if (-not $cert.Thumbprint) { Write-Error "Could not resolve valid certificate thumbprint" return } $store = Get-ServiceCertificateStore $ServiceName $StoreName try { $store.Add($cert) return $true } finally { $store.Close() $store.Dispose() } } finally { $cert.Dispose() } } <# .DESCRIPTION Removes a certificate identified by its Thumbprint from a service-specific certificate store. #> function Remove-ServiceCertificate { param( [Parameter(Mandatory, Position = 0)] [string]$ServiceName, [Parameter(Mandatory, Position = 1)] [string]$Thumbprint, [Parameter()] [System.Security.Cryptography.X509Certificates.StoreName]$StoreName="My" ) $store = Get-ServiceCertificateStore $ServiceName $StoreName try { foreach ($c in $store.Certificates) { if ($c.Thumbprint -eq $Thumbprint) { $store.Remove($c) return $true } } } finally { $store.Close() $store.Dispose() } return $false } |