Skip to content

Conversation

@lusassl-msft
Copy link
Contributor

@lusassl-msft lusassl-msft commented Jun 6, 2025

Description:
With the release of the dedicated Exchange hybrid application feature (https://learn.microsoft.com/en-us/Exchange/hybrid-deployment/deploy-dedicated-hybrid-app), customers must create an application in Microsoft Entra ID which is used by Exchange Server running in hybrid mode. As part of the application creation process, the public key of the current and new next Auth Certificate are uploaded to the application in Entra ID. The certificate is used for JWT assertion-based authentication.

Some customers have a policy enforced within their tenant, which prevents them from uploading a certificates with a lifetime longer than 365 days as part of the keyCredentialConfiguration. The New-ExchangeCertificate, which is used to generate the self-signed certificate, used as Auth Certificate, issues self-signed certificates with a lifetime of 5 years by default. It doesn't allow to specify a different lifetime for self-signed certificates yet. This is something we plan to introduce in future. As a workaround we decided to update the MonitorExchangeAuthCertificate.ps1 script so that it allows customers specify the lifetime of the self-signed certificate used as Auth Certificate.

Fix:
Introduce a new function New-ExchangeSelfSignedCertificate that allows specifying a customer lifetime for the self-signed certificate. It generates a self-signed certificate by using the expected cryptographic service provider (CSP) with extensions which are expected for the Auth Certificate.

Validation:
Lab / Validation by test team is pending

@lusassl-msft lusassl-msft requested a review from a team as a code owner June 6, 2025 15:25
@lusassl-msft lusassl-msft added Enhancement New feature or request Do not merge Do not merge yet as work is still in progress or waiting for other PR to be merged first Test Team Need to get the test involved and aware of this. labels Jun 6, 2025
@lusassl-msft
Copy link
Contributor Author

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@lusassl-msft
Copy link
Contributor Author

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@lusassl-msft
Copy link
Contributor Author

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@lusassl-msft
Copy link
Contributor Author

lusassl-msft commented Jun 13, 2025

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@lusassl-msft
Copy link
Contributor Author

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@lusassl-msft
Copy link
Contributor Author

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR introduces support for custom Auth Certificate lifetimes in the MonitorExchangeAuthCertificate script to address customer requirements with tenant policies that restrict certificate lifetimes to 365 days or less.

  • A new New-ExchangeSelfSignedCertificate function that allows specifying custom certificate lifetimes
  • Enhanced script parameters to support custom certificate lifetimes and enforce new certificate creation
  • Documentation updates reflecting the new functionality

Reviewed Changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
docs/Admin/MonitorExchangeAuthCertificate.md Added documentation for new parameters EnforceNewAuthCertificateCreation and CustomCertificateLifetimeInDays
Shared/CertificateFunctions/New-ExchangeSelfSignedCertificate.ps1 New function implementing custom self-signed certificate generation with configurable lifetime
Admin/MonitorExchangeAuthCertificate/MonitorExchangeAuthCertificate.ps1 Main script updates to support new parameters and certificate creation modes
Admin/MonitorExchangeAuthCertificate/DataCollection/Get-ExchangeAuthCertificateStatus.ps1 Enhanced status detection logic to support enforced certificate creation
Admin/MonitorExchangeAuthCertificate/ConfigurationAction/New-ExchangeAuthCertificate.ps1 Updated certificate creation logic to use custom function when lifetime is specified
.build/cspell-words.txt Added new technical terms to spell check dictionary

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Comment on lines +278 to +286
$certificateThumbprint = $certificate.Thumbprint


if ($PSCmdlet.ShouldProcess("Setting certificate thumbprint")) {
$certificateThumbprint = $certificate.Thumbprint
} else {
# Mock certificate thumbprint
$certificateThumbprint = "A1B2C3D4E5F60718293A4B5C6D7E8F9012345678"
}
Copy link

Copilot AI Sep 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The certificate thumbprint is assigned twice (lines 278 and 282). The first assignment on line 278 is redundant since it's immediately overwritten by the conditional logic.

Copilot uses AI. Check for mistakes.
$newAuthCertificate = New-ExchangeSelfSignedCertificate @newCustomAuthCertificateParams
} else {
Write-Verbose "Creating a default self-signed certificate with a lifetime of 5 years"
$newAuthCertificate = New-ExchangeCertificate @newAuthCertificateParams
Copy link

Copilot AI Sep 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The New-ExchangeSelfSignedCertificate function returns a PSCustomObject with Subject and Thumbprint properties, while New-ExchangeCertificate likely returns a different object structure. This inconsistency may cause issues in subsequent code that expects a specific object format.

Suggested change
$newAuthCertificate = New-ExchangeCertificate @newAuthCertificateParams
$certObj = New-ExchangeCertificate @newAuthCertificateParams
$newAuthCertificate = [PSCustomObject]@{
Thumbprint = $certObj.Thumbprint
Subject = $certObj.Subject
}

Copilot uses AI. Check for mistakes.
The new Auth Certificate, which is eventually created, will be created with a lifetime of 365 days (1 year).
.EXAMPLE
.\MonitorExchangeAuthCertificate.ps1 -EnforceNewAuthCertificateCreation -CustomCertificateLifetimeInDays 365 -Confirm:$false
Runs the script in Auth Certificate enforcement mode.A new Auth Certificate is created and staged as new next Auth Certificate.
Copy link

Copilot AI Sep 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing space after the period in 'mode.A new Auth Certificate'. Should be 'mode. A new Auth Certificate'.

Suggested change
Runs the script in Auth Certificate enforcement mode.A new Auth Certificate is created and staged as new next Auth Certificate.
Runs the script in Auth Certificate enforcement mode. A new Auth Certificate is created and staged as new next Auth Certificate.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Do not merge Do not merge yet as work is still in progress or waiting for other PR to be merged first Enhancement New feature or request Test Team Need to get the test involved and aware of this.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants