I’m sorry, i miss that part in the video. Thank you for the explanation.
Sorry for the trouble and thanks again for this piece of software, really!
Have a nice day
I’m sorry, i miss that part in the video. Thank you for the explanation.
Sorry for the trouble and thanks again for this piece of software, really!
Have a nice day
No problem. I am glad you find the video helpful.
Dean
I’ve attempted to use this method for Exchange 2010, it looked like your script would support it as an option if I’m reading it correctly.
I’m getting the following error when trying to run the script that was provided:
Ampersand not allowed. The & operator is reserved for future use; use “&” to pass ampersand as a string.
At C:\tools\ACME-Exchange.ps1:11 char:163
Complete-ACMEChallenge $FQDN -ChallengeType http-01 -Handler iis -HandlerParameters @{ WebSiteRef = 'Default Web
Site’ } | select Identifier, status, Expires *>& <<<< 1 >> $acmelog
+ CategoryInfo : ParserError: ( [], ParseException
+ FullyQualifiedErrorId : AmpersandNotAllowed
I’m no PowerShell genius or anything, I thought maybe I have a wrong PowerShell version or something, but everything immediately looks right. However, I could be missing something.
What version of PowerShell are you running on the server - you can check it by pasting the following in PowerShell:
$PSVersionTable.PSVersion
I have followed the instructions set out in this thread to obtain a certificate for (my real domain name is replaced with “mydomain”) remote.mydomain.com and autodiscover.mydomain.com on Exchange 2013. Including the amendments to be made for (only) one SAN in the .ps1 file and the Get/Set-ClientAccessServer in the .txt file. I am stuck in the validation procedure with these errors:
Submit-ACMECertificate : Error creating new cert :: Authorizations for these names not found or expired: autodiscover.mydomain.com, remote.mydomain.com
At C:\acme\ACME-Exchange-mydomain.ps1:68 char:1
+ CategoryInfo : PermissionDenied: (ACMESharp.Vault.Model.CertificateInfo:CertificateInfo) [Submit-ACMECe
rtificate], AcmeWebException
+ FullyQualifiedErrorId : urn:acme:error:unauthorized (403),ACMESharp.POSH.SubmitCertificate
Update-ACMECertificate : Certificate has not been submitted yet; cannot update status
At C:\acme\ACME-Exchange-mydomain.ps1:70 char:14
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Update-ACMECertificate : Certificate has not been submitted yet; cannot update status
At C:\acme\ACME-Exchange-mydomain.ps1:76 char:1
+ CategoryInfo : NotSpecified: (:) [Update-ACMECertificate], Exception
+ FullyQualifiedErrorId : System.Exception,ACMESharp.POSH.UpdateCertificate
Get-ACMECertificate : Cannot export PKCS12; private hasn’t been imported or generated
At C:\acme\ACME-Exchange-mydomain.ps1:80 char:1
+ CategoryInfo : NotSpecified: (:) [Get-ACMECertificate], InvalidOperationException
+ FullyQualifiedErrorId : System.InvalidOperationException,ACMESharp.POSH.GetCertificate
Import-ExchangeCertificate : The imported certificate file for server EXCHANGE2013 failed to access for the following r
eason: Could not find file ‘c:\Certificates\remote.mydomain.com_2017-02-26–16-03.pfx’.
At C:\acme\ACME-Exchange-mydomain.ps1:94 char:1
+ CategoryInfo : InvalidOperation: (:) [Import-ExchangeCertificate], InvalidOperationException
+ FullyQualifiedErrorId : [Server=EXCHANGE2013,RequestId=178cdd5f-ced0-4be8-b0d0-d2bf723c52d8,TimeStamp=26-2-2017
15:03:44] [FailureCategory=Cmdlet-InvalidOperationException] B7005C98,Microsoft.Exchange.Management.SystemConfigur
ationTasks.ImportExchangeCertificate
Attempting stop…
Internet services successfully stopped
Attempting start…
Internet services successfully restarted
Remove-Item : Cannot find path ‘C:\Certificates\remote.mydomain.com_2017-02-26–16-03.pfx’ because it does not exist.
At C:\acme\ACME-Exchange-mydomain.ps1:99 char:1
+ CategoryInfo : ObjectNotFound: (C:\Certificates...2-26--16-03.pfx:String) [Remove-Item], ItemNotFoundEx
ception
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.RemoveItemCommand
Can someone help me out on this? I am coming from StartSSL and my current certificate is about to expire.
Cheers, Dela
Hi Dela,
The first line of the output you've posted says:
You didn't get past the validation process of the domain names that you specified. To get more information, check the generated acme_[timestamp].log under c:\certificates. Do you get "invalid" status for the names? If that's the case, you need to find out why the domain name validation is failing. Try getting the generated validation strings (under C:\inetpub\wwwroot.well-known\acme-challenge) from another computer on the local network first - like "http://exchangeintservername/.well-known/acme-challenge/challenge_file_name". Then try from external machine - it could be the firewall not allowing port 80.
Another reason for the "invalid" status could be the case when you are using a load balancer and multiple Exchange CAS; the files might be generated on one CAS, and the request forwarded to another - you need to configure port 80 to go to just one of the Exchange CAS behind the load balancer.
Last week, I had a very weird failure for validation of the FQDN in the cert - some of the names validated successfully and some failed - because the exchange server was delaying the challenge response. The LE timeout seems to be 5 sec, and for some reason the correct challenge response was provided by the Web Server with delay more than LE timeout. Here is the thread about this issue:
Inconsistent LE responses http-01 invalid/valid - wireshark captures
I am still trying to figure out why the Exchange front-end web site is delaying intermittently the response which consists of a single text file containing a single line - the challenge.
Again, check the logs for more info.
Hi Netometer,
Many thanks for your time to respond. As I had returned my Exchange server to its state prior to trying to obtain the LetsEncrypt certificates I did not have the log files anymore. So I tried again obtaining the certificates to produce new log files. This time the process went smoothly and successful! I did exactly the same as my earlier four or five times trying yesterday. I will install the automatic renewal procedure tomorrow and will see how that will go. Hope to stay out of any further of your help, but we’ll see.
Thanks again, Dela
Hi Netometer,
I'm running Exchange 2010 Rollup 15 on Windows Server 2008 R2.
Using your script I've been successfully able to generate and download the certificate. Thank you so much for this.
I'm having a problem with the command to import the certificate and enable it for Exchange:
Import-ExchangeCertificate -FileName $SAN_pfxfile -FriendlyName $SANcert_alias | Enable-ExchangeCertificate -Services "SMTP, IMAP, POP, IIS" -force
Firstly the -FileName is not recognised in Ex2010, so I've had to change the command to this:
Import-ExchangeCertificate -FileData ([Byte]$(Get-Content -Path $SAN_pfxfile -Encoding Byte -readCount 0)) -FriendlyName $SANcert_alias | Enable-ExchangeCertificate -Services "SMTP, IMAP, POP, IIS" -force
Which imports the certificate, but can not enable it, I get the following:
Enable-ExchangeCertificate : The certificate with thumbprint 7E66D71175E706AF48A80A6B7EA69C14D9567857 was found
but is not valid for use with Exchange Server (reason: PrivateKeyMissing).
At line:1 char:186
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Checking in the Certificates MMC, I can see the LetsEncrypt certificate, but I can see that the Private Key for the certificate has not been imported along with the LE cert.
If I manually add the Certificate to the Certificates MMC, then the Private key is imported and I can enable the certificate with exchange.
Any ideas how I can use the PowerShell script to correctly import the certificate?
Once this is resolved, I can automate the renewals.
Many thanks in advance,
Jon
Hi Jon,
I’ve been struggling with this script on Exchange 2010 as well, but I have made a little progress. The error you are getting about PrivateKeyMissing is because Exchange requires a password on the cert. To set the password add -CertificatePassword to the Get-ACMECertificate command in the script:
Get-ACMECertificate $SANcert_alias -ExportPkcs12 $SAN_pfxfile -CertificatePassword ‘Your_Password’
Then you will need to use that password when using ImportExchangeCerificate:
Import-ExchangeCertificate -FileData ([Byte[]]$(Get-Content -Path $SAN_pfxfile
-Encoding byte -ReadCount 0)) -Password (ConvertTo-SecureString -String ‘Your_Password’ -AsPlainText -Force)
However, I am not a PowerShell expert and this is where I get stuck. The Import-ExchangeCertificate command outputs the thumbprint of the cert which is then required to enable the cert. We need to run this command:
Enable-ExchangeCertificate -Thumbprint FFDD1D5747341E61DA6E7A2E29C47BEE5BEDE02 -Services POP,IMAP,IIS,SMTP
How do you feed the thumbprint from the output of the Import-ExchangeCertificate command into the Enable-ExchangeCertificate command??
If I can figure that out, then the complete script should run under Exchange 2010.
Pat
Superb work Pat, thank you so much
I’ve got it to import and enable the Exchange certificate with the following:
Get-ACMECertificate $SANcert_alias -ExportPkcs12 $SAN_pfxfile -CertificatePassword 'My Password'
Import-ExchangeCertificate -FileData ([Byte[]]$(Get-Content -Path $SAN_pfxfile -Encoding Byte -readCount 0)) -FriendlyName $SANcert_alias -Password (ConvertTo-SecureString -String 'My Password' -Force –AsPlainText) | Enable-ExchangeCertificate -Services "SMTP, IMAP, POP, IIS" -force
You need to pipe (its the | character) the output to the Enable-ExchangeCertificate on the same line as the Import-ExchangeCertificate, this way you don’t need the -Thumbprint option.
Jon
Well done Jon, thanks! Two heads are better than one!
Pat
Hi Netometer, here I am again … The auto renewal via task scheduler as such seems to work, but the new certificate does not appear in ECP or in my browser. It still shows my first/old certificate. The log in the Certificate folder shows no odd information and includes the IssuerSerialNumber. Do you have any idea?
EDIT/UPDATE: it appears that taskcheduler is not causing the problem. It is the Powershell script. It seems not to work well after having obtained a certificate for the first time. This is what I see in the Powershell terminal (run as administrator, on Exchange 2013):
PS C:\acme> .\ACME-Exchange-mydomain.ps1
Directory: C:\inetpub\wwwroot
Mode LastWriteTime Length Name
d---- 1-3-2017 15:44 .well-known
Applied configuration changes to section “system.webServer/security/access” for “MACHINE/WEBROOT/APPHOST/Default Web Sit
e/.well-known” at configuration commit path “MACHINE/WEBROOT/APPHOST”
Creating a new identifier for remote.mydomain.com …
New-ACMEIdentifier : An item with the same key has already been added.
At C:\acme\ACME-Exchange-mydomain.ps1:8 char:2
New-ACMEIdentifier -Dns $FQDN -Alias $FQDN | select status, Expires
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Completing the challenge for the new identifier for remote.mydomain.com …
Submitting the new identifier for remote.mydomain.com …
Submit-ACMEChallenge : challenge has not been decoded
At C:\acme\ACME-Exchange-mydomain.ps1:14 char:2
Submit-ACMEChallenge $FQDN -ChallengeType http-01 | select Identifier, status, ...
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Waiting for a valid authorization … Current status is valid
Creating a new identifier for autodiscover.mydomain.com …
New-ACMEIdentifier : An item with the same key has already been added.
At C:\acme\ACME-Exchange-mydomain.ps1:8 char:2
New-ACMEIdentifier -Dns $FQDN -Alias $FQDN | select status, Expires
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Completing the challenge for the new identifier for autodiscover.mydomain.com …
Submitting the new identifier for autodiscover.mydomain.com …
Submit-ACMEChallenge : challenge has not been decoded
At C:\acme\ACME-Exchange-mydomain.ps1:14 char:2
Submit-ACMEChallenge $FQDN -ChallengeType http-01 | select Identifier, status, ...
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Waiting for a valid authorization … Current status is valid
Get-ACMECertificate : asset file does not exist
At C:\acme\ACME-Exchange-mydomain.ps1:80 char:1
+ CategoryInfo : NotSpecified: (:) [Get-ACMECertificate], FileNotFoundException
+ FullyQualifiedErrorId : System.IO.FileNotFoundException,ACMESharp.POSH.GetCertificate
Import-ExchangeCertificate : The imported certificate file for server EXCHANGE2013 failed to access for the following r
eason: Could not find file ‘c:\Certificates\remote.mydomain.com_2017-03-01–15-44.pfx’.
At C:\acme\ACME-Exchange-mydomain.ps1:94 char:1
+ CategoryInfo : InvalidOperation: (:) [Import-ExchangeCertificate], InvalidOperationException
+ FullyQualifiedErrorId : [Server=EXCHANGE2013,RequestId=09680899-7f8d-4bdd-ae1c-c0d352081e12,TimeStamp=1-3-2017 1
4:45:22] [FailureCategory=Cmdlet-InvalidOperationException] B6C1CE14,Microsoft.Exchange.Management.SystemConfigura
tionTasks.ImportExchangeCertificate
Attempting stop…
Internet services successfully stopped
Attempting start…
Internet services successfully restarted
Remove-Item : Cannot find path ‘C:\Certificates\remote.mydomain.com_2017-03-01–15-44.pfx’ because it does not exist.
At C:\acme\ACME-Exchange-mydomain.ps1:99 char:1
+ CategoryInfo : ObjectNotFound: (C:\Certificates...3-01--15-44.pfx:String) [Remove-Item], ItemNotFoundEx
ception
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.RemoveItemCommand
Am I doing something wrong here? Hope you can help me out.
Cheers, Dela
Dela,
I see the following line in your output:
That might happen if line #100 in the script is commented out. Lines #98-100 should look like this:
Delete manually the "sysVault" and try again with the script the way it was provided - lines 98-100 uncommented; that's the way it should be run by the task scheduler for the renewals as well.
Regards,
Dean
Thanks again Netometer, for paying attention to this.
The lines 98-100 in my .ps1 file are exactly the same. I manually deleted the sysvault folder and ran taskscheduler again. No changes in the outcome; still the same certificate. I deleted the sysvault folder once again and ran the .ps1 file manually. Initially it looked good, but then I got the error message “Too many certificates already issued for exact set of domains”. I do not know whether my first retry - with taskscheduler - was also blocked by the same error. I will retry again tomorrow and will report here.
By the way, my sysvault folder only contained the files 00-VAULT and .acme.vault. This is as it should be, correct?
Oh, that could be it.
"Too many certificates already issued for exact set of domains" means you've reached the Let's Encrypt certificates limit - most probably, duplicate certificates (5 certificates per week):
A certificate is considered a duplicate of an earlier certificate if they contain the exact same set of hostnames, ignoring capitalization and ordering of hostnames
For anyone that is interested, I have modified the script to email the ACME log. I inserted it just before the IISRESET command. I am assuming that the SMTP server will not require authorisation and I have only tested this on Exchange 2010 with an anonymous connector:
#Rem E-Mail the Report - You will need to modify $smtpServer along with the relevant E-Mail addresses
#---------------------------------
$smtpServer = “192.168.1.1”
$att = new-object Net.Mail.Attachment($acmelog)
$msg = new-object Net.Mail.MailMessage
$smtp = new-object Net.Mail.SmtpClient($smtpServer)
$msg.From = "LetsEncrypt@yoursite.com"
$msg.To.Add("recipient@yoursite.com")
$msg.Subject = “LetEncrypt Certificate Renewal”
$msg.Body = “Attached is the LetsEncrypt Cert Renewal Report”
$msg.Attachments.Add($att)
$smtp.Send($msg)
$att.Dispose()
Pat
Hi.
I have just followed your excellent screencast on how to install Let’s Encrypt sertificates with the ACME Sharp Powershell script.
I first ran the script, but got errors, probably since I had forgotten to create the proper firewall rules.
But when I rerun the script, I get errors like these:
Creating a new identifier for post.mydoman.net …
New-ACMEIdentifier : An item with the same key has already been added.
At C:\Tools\ACME-Exchange\ACME-Exchange.ps1:8 char:2
New-ACMEIdentifier -Dns $FQDN -Alias $FQDN | select status, Expir ...
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
And the script seems to fail.
How do I clean up this so I can try again?
This is on a Server 2016 with Exchange 2016
Edit: I figured it out. I read your other posts, and found out I had to delete the C:\ProgramData\ACMESharp\sysVault manually.
Dare I suggest a small change in the script to make sure this directory gets deleted when the script at some point fails?
Thank you so much for an excellent script and excellent videos that goes with it!
Thank you, Dal.
Actually, the script should clear the registrations in the vault even if they are unsuccessful - the last three lines do the cleaning up. Probably, you’ve hit CTRL-C and interrupted the script.
Anyway, you made a very good point - if there is a registration issue, the script should stop and do the cleaning. Moreover, I am planning to add a check for port 80 using the external ViewDNS API. If port 80 is not open on the firewall and the server is not accessible from the Internet, the script will stop the certificate request process, do the cleaning, and exit.
Glad to hear that it worked for you.
Regards,
Dean
Hi Netometer, it seems that I am facing the same as Dal. Without deleting the sysVault folder manually I keep getting the “An item with the same key has already been added” error. Upon a close re-watch of your third screencast, I see a difference in line 100 of the script. In the script I downloaded line 100 is identical to what you show above, including the two files that are excluded from deletion. In the screencast these two files are not excluded. Does this have something to do with what I am experiencing?
Hope to hear from you.
Cheers, Dela
Hi Dela,
I’ll try to reproduce this issue.
If I understand correctly, when the script fails, it does not cleanup the the ACME Vault automatically, and you have to run the last three lines manually or manually delete the ACME Vault under c:\Program Data?
Dean