Request: Set-ExchangeCertificate
nemchik opened this issue · 7 comments
I would really love to see a Set-ExchangeCertificate
to handle Microsoft Exchange.
I had contributed to https://github.com/PKISharp/win-acme/blob/master/dist/Scripts/ImportExchange.ps1 and used it but I think the way you're doing things here is significantly cleaner than what's being done in the scripts in the win-acme repo (and these deploy scripts can be used with win-acme anyway)
I'd be happy to accept a PR for something like this. But I have zero experience with anything Exchange related. I wouldn't even know where to begin setting up a test environment for it. Briefly scanning the script from the other project makes it look like it might not be that hard to port it though. It looks like most of the complication comes with trying to support the different versions of Exchange and the Exchange management cmdlets that exist.
I also feel somewhat bad that I still haven't gotten around to releasing this module officially yet.
Yeah detecting which exchange snapin to use was something I contributed here win-acme/win-acme@c0697e9 which was later adapted to https://github.com/PKISharp/win-acme/blob/6273fc8b2df7aa2bb56fb4f4010176f77ec0bc83/dist/Scripts/ImportExchange.ps1#L116-L127
In this script a snapin is used instead of a module, and it would only be available on an exchange server. I can mock up a PR.
Just a quick update here is my progress so far. https://github.com/nemchik/Posh-ACME.Deploy/commit/2162ef527dde86740816a4a679855f28deb718f9
I have not had an opportunity to test this. My biggest concern is https://github.com/nemchik/Posh-ACME.Deploy/commit/2162ef527dde86740816a4a679855f28deb718f9#diff-97ec899ab3a5b73269f9e375409a554aR42 can return multiple thumbprints which later might be an issue for https://github.com/nemchik/Posh-ACME.Deploy/commit/2162ef527dde86740816a4a679855f28deb718f9#diff-97ec899ab3a5b73269f9e375409a554aR53
p.s. I've made a few additional adjustments on the branch https://github.com/nemchik/Posh-ACME.Deploy/commits/exchange to clean up a few small things. As you can tell I mostly duplicated your Set-RDGWCertificate
.
The docs for Get-ExchangeCertificate indicate it basically returns a collection of all certs installed on the system whether they're actually used by Exchange or not. That seems like an odd design choice by MS, but whatever.
You could probably use the Services
property that gets returned to filter the results based on the input $ExchangeServices
variable. Though that might be a little tricky if different certs are associated with different services. I'm guessing the property is returned as a string array.
It looks like the Services
parameter for Enable-ExchangeCertificate is also expecting a string array that happens to work with a comma delimited string because PowerShell converts it. So it might make sense to change that input/default value on the function to something like
[string[]]$ExchangeServices='IIS','SMTP',
Then you can change the old cert query section to something like this which should get you the unique set of thumbprints that are only associated with the services you care about.
$oldThumbs = foreach ($service in $ExchangeServices) {
(Get-ExchangeCertificate | Where-Object { $service -in $_.Services }).Thumbprint
} | Sort-Object -Unique
Here is a commit to match your recommendations (with small tweaks) https://github.com/nemchik/Posh-ACME.Deploy/commit/aad0fe444fa1c829c0cf2b35818df3925f9f3bfe
I have not tested that Enable-ExchangeCertificate
will accept an array of strings. The documentation says to just separate by commas, which makes me think it's meant to accept a string.
I may end up making a DC and Exchange server in Azure to test these things.
It's unfortunate the doc doesn't give the exact object type it's expecting and they do say separate by commas, but they don't surround the argument in the example with quotes. So it likely works the same way the Domain parameter works in Posh-ACME's New-PACertificate
.
Essentially if there are no quotes around the argument, it treats it like an array of strings rather than a single comma delimited string. Check how it handles the different outputs:
Write-Host POP,IMAP,SMTP,IIS
Write-Host 'POP','IMAP','SMTP','IIS'
Write-Host 'POP,IMAP,SMTP,IIS'
Example 1 and 2 treated the same. 2 is just more explicit that the array members are strings. Example 3 is just a single string, so the output includes the original commas.