The last couple of weeks I have been working with several Microsoft Exchange Server environments. I encountered lots of expired certificates. Organizations wanted help with that.
One of the questions that kept coming back was:
Do I press Yes to change the default certificate, when I enabled the certificate for SMTP?
The official answer is to press No. The recommend practice is to leave it like it is. However, it begs another question:
How can I see the current default SMTP certificate?
I'll answer this latter question in this blog post.
What is the default SMTP certificate used for?
When you install Microsoft Exchange Server on a Windows Server installation, it creates a self-signed certificate with a validity period of 5 years. This certificate is assigned as the initial default SMTP certificate. This certificate is used for the mutual TLS connections between the Microsoft Exchange Servers within an Exchange Organization. This certificate is also presented to external mail systems when mutual TLS is required.
Normally, Microsoft Exchange Server admins:
- Configure a dedicated certificate for this connector, or;
- Configure the fully-qualified domain name (FQDN) on the connector to match the certificate.
How do I find the current default SMTP certificate?
One would assume that you would be able to see the current certificate with native tooling provided by Microsoft.
Let's test this assumption: Open the Microsoft Exchange Management shell. Connect to the Microsoft Exchange Server environment. Execute the Get-ExchangeServer Windows PowerShell cmdlet. Examine the output. See, the information is not there.
But we're close…
Where can I find it then?
The Get-ExchangeServer Windows PowerShell cmdlet retrieves the information that is configured in the configuration container of Active Directory. In this configuration container, the Exchange Server environment configuration is stored for the entire Active Directory forest.
Specifically, Get-ExchangeServer retrieves all Active Directory objects from the follow location:
CN=Servers,CN=Exchange Administrative Group (FYDIBOHF23SPDLT),CN=Administrative Groups,CN=Exchange Organization Name,CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=domain,DC=tld
Note:
The Exchange Organization Name portion of the above location is the name used with the initial installation of a Microsoft Exchange Server in the Active Directory environment.
Each object that is retrieved contains multiple attributes. One of these attributes is msExchServerInternalTLSCert. This attribute contains the actual certificate used by the environment. If you look it up trough ADSI Edit (adsiedit.msc), then you'll find a string of number (hex, octal, decimal) values.
Not very human readable… And definitely not useful to determine the actual certificate.
PowerShell to the rescue!
We now know the Active Directory object and attribute to look for. Let's bring it all together and solve the riddle using Windows PowerShell.
Getting ready
In order to run this script you need to have:
- Active Directory PowerShell module on the machine
- The account used, must have at least the View-Only Configuration Management role assigned to it in the Exchange Server environment
- This script can be run from the PowerShell ISE console
- Before running, a target Exchange Server must be specified
Running PowerShell
Run the following PowerShell script:
#Specify a name of one of the Exchange Servers
$TargetExchangeServer = "Your Exchange Server"
$ExistingSessions = Get-PSSession
if($ExistingSessions.ConfigurationName -notcontains "Microsoft.Exchange"){
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri "http://$TargetExchangeServer/PowerShell/" -Authentication Kerberos
Import-PSSession $Session
}
else{
Write-Host "Use existing session" -ForegroundColor Green
}
#Get all Exchange Servers in the environment
$ExchangeServers = (Get-ExchangeServer |Where-Object {$_.ServerRole -like "mailbox"} )| Select-Object Name,DistinguishedName
$Results = @()
#Process Information
ForEach($Server in $ExchangeServers){
$TransportCert = (Get-ADObject -Identity $Server.DistinguishedName -Properties *).msExchServerInternalTLSCert
$Cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2
$CertBlob = [System.Convert]::ToBase64String($TransportCert)
$Cert.Import([Convert]::FromBase64String($CertBlob))
$server | Add-Member -MemberType NoteProperty -Name DefaultTLSCertSubject -Value $Cert.Subject
$server | Add-Member -MemberType NoteProperty -Name DefaultTLSCertFriendlyName -Value $Cert.FriendlyName
$server | Add-Member -MemberType NoteProperty -Name DefaultTLSCertThumbprint -Value $Cert.Thumbprint
$server | Add-Member -MemberType NoteProperty -Name DefaultTLSCertExpireDate -Value $Cert.NotAfter
$Results += $Server
}
#Show result
$Results | Out-GridView
Interpreting the result
The script outputs a Windows PowerShell Grid View window. An example of the result is shown here:
Concluding
I hope this article gives you more insight where the information of the default SMTP certificate is stored and how to retrieve it. This information can be valuable, when you try to gain insights into the certificates used by the Microsoft Exchange Servers.