Publish S/MIME Certificates to the Exchange Online GAL with PowerShell

In environments with internal PKI and Exchange Online, publishing S/MIME certificates centrally can save a lot of manual work. This PowerShell script exports public user S/MIME certificates from Active Directory, stores them as .cer files, and then writes them to Exchange Online mailbox attributes so they are available through the Global Address List (GAL). S/MIME in Exchange Online is used for message signing and encryption, and publishing the public certificate helps other users find the recipient’s encryption certificate more easily.learn.microsoft+2

One practical reason for this approach is that users often should not be given the permissions required to publish their own certificate data to Exchange Online mailbox attributes. Microsoft community discussions and support answers note that updating those attributes can require elevated Exchange permissions, which makes a central administrative process the safer option.

How the script works

The script runs in two phases. In the first phase, it queries the internal Windows Certification Authority with certutil, filters issued certificates for the required template, checks whether they are still valid, and exports the matching public certificates from Active Directory to .cer files. Because the certificate list is read from the CA database, the script should run on the internal Windows CA server, or at least on a system that can query that CA directly with the necessary permissions.

In the second phase, the script connects to Exchange Online using app-only certificate authentication. It reads the exported .cer files, converts them into the format expected by Exchange Online, and assigns them to the mailbox with Set-Mailbox by writing the UserSMimeCertificate and UserCertificate values. That makes the public certificate available for GAL-based lookup in Exchange Online.

What you need to change

Before using the script in your own environment, adjust the environment-specific variables and connection settings.

VariablePurpose
VariablePurpose
CertPathFolder used to temporarily store the exported .cer files.
LogPathPath of the transcript log file.
CertThumbThumbprint of the certificate used for Exchange Online app-only authentication. learn.microsoft
AppIDEntra ID application ID used to connect to Exchange Online. learn.microsoft
OrganizationYour Microsoft 365 tenant name, for example contoso.onmicrosoft.comlearn.microsoft
Certificate template filterReplace *TGUserCryptGPO* with the template name used by your internal CA.

The required PowerShell modules must also be installed, especially ADObjectCertificate and ExchangeOnlineManagement. In addition, the executing account and app registration need the necessary permissions in Active Directory, on the CA, and in Exchange Online. Certificate-based Exchange Online connections also require the authentication certificate to be installed on the machine where the script runs.

S/MIME and the GAL

S/MIME uses public key cryptography. For encrypted email, the sender needs access to the recipient’s public certificate, while the private key remains with the certificate owner. Publishing the public S/MIME certificate to the GAL makes it easier for internal recipients to find the correct certificate when they want to encrypt mail.

This script only works with the public certificate data. It does not export or upload any private key material, which is exactly how this process should work. In other words, the script helps distribute the public encryption certificate in Exchange Online while the user keeps control of the private key locally.

Why this is useful

This approach is especially useful in hybrid or PKI-based environments where certificates are issued internally but Exchange Online is used for mailboxes and address book access. Instead of relying on each user to publish a certificate manually, the process can be centralized, standardized, and automated. That reduces user effort and ensures a more consistent S/MIME rollout across the organization.

GitHub download

Download the script here: GitHub repository

Schreibe einen Kommentar