How to download the SSL certificate from a website using PowerShell?

I want to download the SSL certificate from, say https://www.outlook.com, using PowerShell. Is it possible? Could someone help me?


To share more knowledge :-)

$webRequest = [Net.WebRequest]::Create("https://www.outlook.com")
try { $webRequest.GetResponse() } catch {}
$cert = $webRequest.ServicePoint.Certificate
$bytes = $cert.Export([Security.Cryptography.X509Certificates.X509ContentType]::Cert)
set-content -value $bytes -encoding byte -path "$pwd\Outlook.Com.cer"

My co-worker Michael J. Lyons shared this with me.


You should be able to get the public key by using the ServicePoint property on the HttpWebRequest object. This necessary information will be populated once we have made a http request to the site in question.

If the request is made to a site which has an untrusted certificate the GetResponse method will throw an exception, However, the ServicePoint will still contain the Certificate so we want to ensure we ignore WebException if the status is a trust failure.

So something like the following should work:

function Get-PublicKey
{
    [OutputType([byte[]])]
    PARAM (
        [Uri]$Uri
    )

    if (-Not ($uri.Scheme -eq "https"))
    {
        Write-Error "You can only get keys for https addresses"
        return
    }

    $request = [System.Net.HttpWebRequest]::Create($uri)

    try
    {
        #Make the request but ignore (dispose it) the response, since we only care about the service point
        $request.GetResponse().Dispose()
    }
    catch [System.Net.WebException]
    {
        if ($_.Exception.Status -eq [System.Net.WebExceptionStatus]::TrustFailure)
        {
            #We ignore trust failures, since we only want the certificate, and the service point is still populated at this point
        }
        else
        {
            #Let other exceptions bubble up, or write-error the exception and return from this method
            throw
        }
    }

    #The ServicePoint object should now contain the Certificate for the site.
    $servicePoint = $request.ServicePoint
    $key = $servicePoint.Certificate.GetPublicKey()
    Write-Output $key
}

Get-PublicKey -Uri "https://www.bing.com"
Get-PublicKey -Uri "https://www.facebook.com"

If you want to call the method many times and some might have the same address, you might want to improve the function by using the ServicePointManager.FindServicePoint(System.Uri) method, since it will return a cached version if a request has already been made to that site. So you could check if the service point has been populated with information. If it hasn't, make the web request. If it has, just use the already existing information, saving yourself an http request.