At my office we have a certificate renewal process that happens every other year. This year, we have a plan to document the location of all of the certificates that are installed on the servers to help the next time the renewal happens. So I have worked out a quick and simply one liner that will get all of the certificates installed on the server in the LOCALMACHINE\My certificate store.
Get-ChildItem -Path Cert:\localmachine\My -Recurse | Select Subject, Friendlyname, SerialNumber, Issuer, NotAfter, EnhancedKeyUsageList | Export-csv E:\SSL\AllCerts-$env:COMPUTERNAME.csv
This script, as I said above is simple, and it doesn’t really meet all of the needs that I have. I would rather it show the certificates that are bound to the IIS websites. Having this information would help, as it would show which certificates are actually in use as opposed to the certificates that are installed in the LOCALMACHINE\My certificate store.
Import-module webadministration $report = @() $sites = Get-Website | ? { $_.State -eq "Started" } | % { $_.Name } foreach ($site in $sites){ Write-host $site.ToUpper() -ForegroundColor Yellow $certs = Get-ChildItem IIS:\SslBindings | ? { $site -contains $_.Sites.Value } | % { $_.Thumbprint } Foreach ($cert in $certs){ $line = Get-ChildItem Cert:\LocalMachine\My | Where {$_.Thumbprint -eq $Cert} | Select @{N="SiteName";E={$site}},DnsNameList, @{N="Subject Alternative Name";E={($_.extensions | where {$_.Oid.friendlyname -eq "Subject Alternative Name"}).format(1)}}, NotAfter, SerialNumber, Issuer $report += $line } } $report | Export-Csv E:\SSL\$env:COMPUTERNAME.csv -NoTypeInformation -UseCulture
This script will output into a CSV file that is easily readable, and could be used as the document for the following year. The best part of the script is that fact that it can get the subject alternative name. We have a few certificates in the environment that use it, so its hard to remember which ones have it.
Now that I have a method of gathering the required information, I just need to run it on the remote servers. Invoke-Command is going to be the MVP here. Save the script above as Get-Bound-Certs.ps1. Get a list of the servers that you need to gather the information from, and save it as Servers.txt
$ServerNames = Get-content C:\scripts\logs\Servers.txt Foreach ($ServerName in $ServerNames){ Invoke-Command -ComputerName $ServerName -FilePath C:\Scripts\Certificates\Get-bound-Certs.ps1 }
-Stuart