Every Exchange organisation depends on two kinds of certificate that expire on very different schedules: the public SAN certificate that clients see, and the self-signed Microsoft Exchange Server Auth Certificate behind OAuth. Let the first lapse and clients see warnings or fail to connect; let the second lapse and sign-in to Outlook on the web and the Exchange admin center breaks, along with hybrid features. In this post I'll renew both with the Exchange Management Shell and show what to check afterwards.
Prerequisites: know your certificates#
| Certificate | Lifetime | Used for |
|---|---|---|
Third-party SAN certificate (for example mail.contoso.com, autodiscover.contoso.com) | Set by the CA, and getting shorter | IIS on the Default Web Site, usually SMTP, sometimes POP/IMAP |
| Microsoft Exchange Server Auth Certificate (self-signed, organisation-wide) | 5 years | OAuth server-to-server authentication, hybrid, several security features |
| Microsoft Exchange (self-signed, per server) | 5 years | Exchange Back End website, internal SMTP |
You need Organization Management rights, an elevated Exchange Management Shell on a Mailbox server, and the CA's intermediate certificates. Start with an inventory of every server:
foreach ($s in Get-ExchangeServer | Where-Object { $_.ServerRole -notlike '*Edge*' }) {
Get-ExchangeCertificate -Server $s.Name |
Select-Object @{n='Server';e={$s.Name}}, FriendlyName, Thumbprint, Services, NotAfter
}
(Get-AuthConfig).CurrentCertificateThumbprint | Get-ExchangeCertificate | Format-List Subject, Thumbprint, NotAfterPart 1: renew the SAN certificate#
1. Create the renewal request#
Run this on the server that will complete the request. Piping the old certificate copies its subject and names:
$req = Get-ExchangeCertificate -Thumbprint <OldThumbprint> | New-ExchangeCertificate -GenerateRequest -PrivateKeyExportable $true
[System.IO.File]::WriteAllBytes('C:\Certs\mail-renewal.req', [System.Text.Encoding]::Unicode.GetBytes($req))To change names, create a fresh request with -SubjectName, -DomainName, -FriendlyName and -KeySize 2048 instead.
2. Complete it and copy it to the other servers#
Import-ExchangeCertificate -Server EX01 -FileData ([System.IO.File]::ReadAllBytes('C:\Certs\mail-renewed.cer'))
$pfx = Export-ExchangeCertificate -Server EX01 -Thumbprint <NewThumbprint> -BinaryEncoded -Password (Get-Credential).Password
[System.IO.File]::WriteAllBytes('C:\Certs\mail-renewed.pfx', $pfx.FileData)
Import-ExchangeCertificate -Server EX02 -FileData ([System.IO.File]::ReadAllBytes('C:\Certs\mail-renewed.pfx')) -Password (Get-Credential).Password -PrivateKeyExportable $trueOnly the password in the credential prompt matters; the user name is ignored.
3. Enable it on each server#
Enable-ExchangeCertificate -Server EX01 -Thumbprint <NewThumbprint> -Services IIS,SMTPAnswer No when asked to overwrite the default SMTP certificate, so internal transport keeps the self-signed one. Add POP,IMAP if you use them. Leave the Exchange Back End site alone. If a load balancer uses SSL bridging, it must present the same certificate as Exchange; Microsoft's process is to disable Extended Protection, swap the certificate on Exchange and the load balancer, then re-enable it (see Extended Protection on Exchange Server).
4. Check what each server presents#
Connect to a server's own IP address so the load balancer doesn't hide a mistake:
$tcp = [System.Net.Sockets.TcpClient]::new('10.0.0.11', 443)
$ssl = [System.Net.Security.SslStream]::new($tcp.GetStream(), $false, { $true })
$ssl.AuthenticateAsClient('mail.contoso.com')
$ssl.RemoteCertificate.GetCertHashString()
$ssl.Dispose(); $tcp.Dispose()Good looks like: the new thumbprint from every server and the load balancer. Only then run Remove-ExchangeCertificate -Server EX01 -Thumbprint <OldThumbprint> on each server.
Part 2: rotate the Auth certificate#
Option A: let Microsoft's script do it#
MonitorExchangeAuthCertificate.ps1 checks the Auth configuration and performs the rotation steps, including replacing a certificate that has already expired. It must run on a Mailbox server, not a tools-only machine:
.\MonitorExchangeAuthCertificate.ps1
.\MonitorExchangeAuthCertificate.ps1 -ValidateAndRenewAuthCertificate $true -Confirm:$falseThe first line only reports. If the script detects hybrid, it won't renew unless you add -IgnoreHybridConfig $true, and then you must rerun the Hybrid Configuration Wizard. -IgnoreUnreachableServers $true skips offline servers, and -ConfigureScriptToRunViaScheduledTask sets up automatic monitoring. Logs go to <ExchangeInstallPath>\Logging\AuthCertificateMonitoring.
Option B: stage it manually#
$newAuth = New-ExchangeCertificate -KeySize 2048 -PrivateKeyExportable $true -SubjectName "cn=Microsoft Exchange Server Auth Certificate" -FriendlyName "Microsoft Exchange Server Auth Certificate" -DomainName @()
Set-AuthConfig -NewCertificateThumbprint $newAuth.Thumbprint -NewCertificateEffectiveDate (Get-Date).AddHours(49)Answer N to the default SMTP certificate prompt. Allow at least 48 hours, more in large organisations, so the certificate servicelet in MSExchangeServiceHost can copy the new certificate to every server. The AuthAdmin servicelet runs when that service starts and every 12 hours afterwards; once the effective date passes, it makes the new certificate current. Then recycle the application pools that cache it:
Restart-WebAppPool MSExchangeOWAAppPool
Restart-WebAppPool MSExchangeECPAppPoolWatch out: If the Auth Certificate has already expired or is missing, there's no time to stage. Use the script, or Microsoft's support article Can't sign in to Outlook on the web or EAC if Exchange Server OAuth certificate is expired, which activates a new certificate immediately.
Hybrid follow-up#
- Microsoft strongly recommends rerunning the Hybrid Configuration Wizard after the active Auth Certificate changes, so Exchange Online trusts the new one. If you use the dedicated Exchange hybrid application, make sure the new certificate reaches it too; my hybrid free/busy article covers that.
- Hybrid connectors find the SAN certificate by issuer and subject (
TlsCertificateName), not thumbprint. If either changed, rerun the wizard so the connectors match.
Test-OAuthConnectivity -Service EWS -TargetUri https://outlook.office365.com/ews/exchange.asmx -Mailbox onprem.user -Verbose | Format-ListVerify#
Get-AuthConfig | Format-List *Thumbprint*, *EffectiveDate*shows the new thumbprint as current, and the inventory loop finds it on every server.- The Application log has event
2014fromMSExchange AuthAdmin, saying the current signing certificate was updated. Servicelet logs are in<ExchangeInstallPath>\Logging\AuthAdminLogs. - Outlook on the web and the Exchange admin center sign in,
Test-OAuthConnectivityreturnsSuccess, and hybrid free/busy works both ways. - Outlook connects without certificate warnings.
Tips and gotchas#
- Shorter lifetimes. Public certificate lifetimes keep shrinking under CA/Browser Forum rules, so script the SAN renewal and schedule the inventory with a
NotAfterfilter. - Different AD sites. If the new Auth Certificate is missing in another site, export it and import it on one server there; replication within the site does the rest.
- Child domains. If Exchange servers sit in a child domain and the system mailbox is in the root domain, run
Set-OrganizationConfig -EnableAuthAdminReadSession:$trueor the AuthAdmin servicelet can't start. - Remove last. Keep the old SAN certificate until the load balancer, reverse proxy and hybrid checks pass.

