@@ -3,112 +3,148 @@ $DebugPreference = "Continue"
33$VerbosePreference = " Continue"
44$InformationPreference = " Continue"
55
6- function Get-KFCertificates
7- {
6+ function Get-KFCertificates {
87 param (
98 [string ]$StoreName = " My" # Default store name is "My" (Personal)
109 )
1110
12- # Get all certificates from the specified store
13- $certificates = Get-ChildItem - Path " Cert:\LocalMachine\$StoreName "
11+ # Define the store path using the provided StoreName parameter
12+ $storePath = " Cert:\LocalMachine\$StoreName "
1413
15- # Initialize an array to store the results
14+ # Check if the store path exists to ensure the store is valid
15+ if (-not (Test-Path $storePath )) {
16+ # Write an error message and exit the function if the store path is invalid
17+ Write-Error " The certificate store path '$storePath ' does not exist. Please provide a valid store name."
18+ return
19+ }
20+
21+ # Retrieve all certificates from the specified store
22+ $certificates = Get-ChildItem - Path $storePath
23+
24+ # Initialize an empty array to store certificate information objects
1625 $certInfoList = @ ()
1726
1827 foreach ($cert in $certificates ) {
19- # Create a custom object to store the certificate information
20- $certInfo = [PSCustomObject ]@ {
21- StoreName = $StoreName
22- Certificate = $cert.Subject
23- ExpiryDate = $cert.NotAfter
24- Issuer = $cert.Issuer
25- Thumbprint = $cert.Thumbprint
26- HasPrivateKey = $cert.HasPrivateKey
27- SAN = Get-KFSAN $cert
28- ProviderName = Get-CertificateCSP $cert
29- Base64Data = [System.Convert ]::ToBase64String($cert.RawData )
28+ try {
29+ # Create a custom object to store details about the current certificate
30+ $certInfo = [PSCustomObject ]@ {
31+ StoreName = $StoreName # Name of the certificate store
32+ Certificate = $cert.Subject # Subject of the certificate
33+ ExpiryDate = $cert.NotAfter # Expiration date of the certificate
34+ Issuer = $cert.Issuer # Issuer of the certificate
35+ Thumbprint = $cert.Thumbprint # Unique thumbprint of the certificate
36+ HasPrivateKey = $cert.HasPrivateKey # Indicates if the certificate has a private key
37+ SAN = Get-KFSAN $cert # Subject Alternative Names (if available)
38+ ProviderName = Get-CertificateCSP $cert # Provider of the certificate
39+ Base64Data = [System.Convert ]::ToBase64String($cert.RawData ) # Encoded raw certificate data
40+ }
41+
42+ # Add the certificate information object to the results array
43+ $certInfoList += $certInfo
44+ } catch {
45+ # Write a warning message if there is an error processing the current certificate
46+ Write-Warning " An error occurred while processing the certificate: $_ "
3047 }
31-
32- # Add the certificate information to the array
33- $certInfoList += $certInfo
3448 }
3549
36- # Output the results
50+ # Output the results in JSON format if certificates were found
3751 if ($certInfoList ) {
38- $certInfoList | ConvertTo-Json
52+ $certInfoList | ConvertTo-Json - Depth 10
53+ } else {
54+ # Write a warning if no certificates were found in the specified store
55+ Write-Warning " No certificates were found in the store '$StoreName '."
3956 }
4057}
4158
42- function Get-KFIISBoundCertificates
43- {
44- # Import the WebAdministration module
59+ function Get-KFIISBoundCertificates {
60+ # Import the IISAdministration module
4561 Import-Module IISAdministration
46- # Import-Module WebAdministration
4762
4863 # Get all websites
49- # $websites = Get-Website
5064 $websites = Get-IISSite
5165
52- Write-Information " There were ${websites} .count found"
66+ # Write the count of websites found
67+ Write-Information " There were $ ( $websites.Count ) websites found."
5368
5469 # Initialize an array to store the results
5570 $certificates = @ ()
5671
72+ # Initialize a counter for the total number of bindings with certificates
73+ $totalBoundCertificates = 0
74+
5775 foreach ($site in $websites ) {
5876 # Get the site name
5977 $siteName = $site.name
60-
78+
6179 # Get the bindings for the site
62- # $bindings = Get-WebBinding -Name $siteName
6380 $bindings = Get-IISSiteBinding - Name $siteName
64-
81+
82+ # Initialize a counter for bindings with certificates for the current site
83+ $siteBoundCertificateCount = 0
84+
6585 foreach ($binding in $bindings ) {
6686 # Check if the binding has an SSL certificate
67- if ($binding.protocol -eq ' https' ) {
87+ if ($binding.protocol -eq ' https' -and $binding .RawAttributes.certificateHash ) {
6888 # Get the certificate hash
69- # $certHash = $binding.certificateHash
7089 $certHash = $binding.RawAttributes.certificateHash
71-
90+
7291 # Get the certificate store
7392 $StoreName = $binding.certificateStoreName
74-
75- # Get the certificate details from the certificate store
76- $cert = Get-ChildItem - Path " Cert:\LocalMachine\$StoreName \$certHash "
77-
78- $certBase64 = [Convert ]::ToBase64String($cert.RawData )
79-
80- # Create a custom object to store the results
81- $certInfo = [PSCustomObject ]@ {
82- SiteName = $siteName
83- Binding = $binding.bindingInformation
84- IPAddress = ($binding.bindingInformation -split " :" )[0 ]
85- Port = ($binding.bindingInformation -split " :" )[1 ]
86- Hostname = ($binding.bindingInformation -split " :" )[2 ]
87- Protocol = $binding.protocol
88- SNI = $binding.sslFlags -eq 1
89- ProviderName = Get-CertificateCSP $cert
90- SAN = Get-KFSAN $cert
91- Certificate = $cert.Subject
92- ExpiryDate = $cert.NotAfter
93- Issuer = $cert.Issuer
94- Thumbprint = $cert.Thumbprint
95- HasPrivateKey = $cert.HasPrivateKey
96- CertificateBase64 = $certBase64
93+
94+ try {
95+ # Get the certificate details from the certificate store
96+ $cert = Get-ChildItem - Path " Cert:\LocalMachine\$StoreName \$certHash "
97+
98+ # Convert certificate data to Base64
99+ $certBase64 = [Convert ]::ToBase64String($cert.RawData )
100+
101+ # Create a custom object to store the results
102+ $certInfo = [PSCustomObject ]@ {
103+ SiteName = $siteName
104+ Binding = $binding.bindingInformation
105+ IPAddress = ($binding.bindingInformation -split " :" )[0 ]
106+ Port = ($binding.bindingInformation -split " :" )[1 ]
107+ Hostname = ($binding.bindingInformation -split " :" )[2 ]
108+ Protocol = $binding.protocol
109+ SNI = $binding.sslFlags -eq 1
110+ ProviderName = Get-CertificateCSP $cert
111+ SAN = Get-KFSAN $cert
112+ Certificate = $cert.Subject
113+ ExpiryDate = $cert.NotAfter
114+ Issuer = $cert.Issuer
115+ Thumbprint = $cert.Thumbprint
116+ HasPrivateKey = $cert.HasPrivateKey
117+ CertificateBase64 = $certBase64
118+ }
119+
120+ # Add the certificate information to the array
121+ $certificates += $certInfo
122+
123+ # Increment the counters
124+ $siteBoundCertificateCount ++
125+ $totalBoundCertificates ++
126+ } catch {
127+ Write-Warning " Could not retrieve certificate details for hash $certHash in store $StoreName ."
97128 }
98-
99- # Add the certificate information to the array
100- $certificates += $certInfo
101129 }
102130 }
131+
132+ # Write the count of bindings with certificates for the current site
133+ Write-Information " Website: $siteName has $siteBoundCertificateCount bindings with certificates."
103134 }
104135
105- # Output the results
106- if ($certificates ) {
136+ # Write the total count of bindings with certificates
137+ Write-Information " A total of $totalBoundCertificates bindings with valid certificates were found."
138+
139+ # Output the results in JSON format or indicate no certificates found
140+ if ($totalBoundCertificates -gt 0 ) {
107141 $certificates | ConvertTo-Json
142+ } else {
143+ Write-Information " No valid certificates were found bound to websites."
108144 }
109-
110145}
111146
147+
112148function Add-KFCertificateToStore
113149{
114150 param (
@@ -172,7 +208,7 @@ function Add-KFCertificateToStore
172208 # Retrieve the certificate thumbprint from the store
173209 $cert = Get-ChildItem - Path " Cert:\LocalMachine\$StoreName " | Sort-Object - Property NotAfter - Descending | Select-Object - First 1
174210 if ($cert ) {
175- $thumbprint = $cert.Thumbprint
211+ $output = $cert.Thumbprint
176212 Write-Output " Certificate imported successfully. Thumbprint: $thumbprint "
177213 }
178214 else {
@@ -191,7 +227,7 @@ function Add-KFCertificateToStore
191227 }
192228
193229 # Output the final result
194- $output
230+ return $output
195231
196232 } else {
197233 $bytes = [System.Convert ]::FromBase64String($Base64Cert )
@@ -227,6 +263,9 @@ function Remove-KFCertificateFromStore
227263 [switch ]$IsAlias
228264 )
229265
266+ # Initialize a variable to track success
267+ $isSuccessful = $false
268+
230269 try {
231270 # Open the certificate store
232271 $store = New-Object System.Security.Cryptography.X509Certificates.X509Store($StorePath , [System.Security.Cryptography.X509Certificates.StoreLocation ]::LocalMachine)
@@ -244,17 +283,31 @@ function Remove-KFCertificateFromStore
244283 Write-Information " Attempting to remove certificate from store '$StorePath ' with the thumbprint: $Thumbprint "
245284 $store.Remove ($cert )
246285 Write-Information " Certificate removed successfully from store '$StorePath '"
286+
287+ # Mark success
288+ $isSuccessful = $true
247289 } else {
248- Write-Error " Certificate not found in $StorePath ."
290+ throw [ System.Exception ]::new( " Certificate not found in $StorePath ." )
249291 }
250292
251293 # Close the store
252294 $store.Close ()
253295 } catch {
296+ # Log and rethrow the exception
254297 Write-Error " An error occurred: $_ "
298+ throw $_
299+ } finally {
300+ # Ensure the store is closed
301+ if ($store ) {
302+ $store.Close ()
303+ }
255304 }
305+
306+ # Return the success status
307+ return $isSuccessful
256308}
257309
310+
258311function New-KFIISSiteBinding
259312{
260313 param (
0 commit comments