cls Import-Module ACMESharp # User controlled variables $DomainList = @("domain1.com", "domain2.com", "mail.domain1.com", "mail.domain2.com", "www.domain1.com", "www.domain2.com") $WorkDirectory="c:\\ACME" $FTPSite="ftp://ftp.domain1.com/.well-known/acme-challenge/" $FTPSiteCert="ftp://ftp.domain1.com/Certs/" $FTPUser="FTPAccess" $FTPPass="FTPChallengePass" $CertPass="FTPCertPass" # Script controlled variables $SANList=@() $AltIdRefs=@() $RuntimeError=0 ForEach ($Domain in $DomainList) { if ($RuntimeError -ne 0) {break} do { $TimeStamp = (Get-Date -Format s) -replace '-' -replace 'T' -replace ':' $Alias=($Domain.ToString() -replace "\.")+$TimeStamp # Create new ACMEIdentifier for the domain if ((Test-Path ($WorkDirectory+"\\1-Identifiers\\"+$Domain)) -eq $FALSE) { New-Item -ItemType directory -Path ($WorkDirectory+"\\1-Identifiers\\"+$Domain) } New-ACMEIdentifier -Dns $Domain -Alias $Alias > ($WorkDirectory+"\\1-Identifiers\\"+$Domain+"\\"+$TimeStamp+".txt") Start-Sleep 10 # Request new challenge for the domain if ((Test-Path ($WorkDirectory+"\\2-Challenges\\"+$Domain)) -eq $FALSE) { New-Item -ItemType directory -Path ($WorkDirectory+"\\2-Challenges\\"+$Domain) } $result = Complete-ACMEChallenge $Alias -ChallengeType http-01 -Handler manual Start-Sleep 10 # Create HTTP response file for challenge $Challenges = [Collections.Generic.List[Object]]($result.Challenges.ToArray()) $ChallengeObj=($Challenges[($Challenges.FindIndex( {$args[0].Type -eq "http-01"}))]) $ChallengeObj.Challenge.Answer.KeyAuthorization |Out-File -Encoding ascii ($WorkDirectory+"\\2-Challenges\\"+$Domain+"\\"+$ChallengeObj.Token) # Upload HTTP response file to webserver $ftp = [System.Net.FtpWebRequest]::Create($FTPSite+$ChallengeObj.Token) $ftp = [System.Net.FtpWebRequest]$ftp $ftp.Method = [System.Net.WebRequestMethods+Ftp]::UploadFile $ftp.Credentials = new-object System.Net.NetworkCredential($FTPUser,$FTPPass) $ftp.UseBinary = $true $ftp.UsePassive = $true $content = [System.IO.File]::ReadAllBytes($WorkDirectory+"\\2-Challenges\\"+$Domain+"\\"+$ChallengeObj.Token) $ftp.ContentLength = $content.Length $rs = $ftp.GetRequestStream() $rs.Write($content, 0, $content.Length) $rs.Close() $rs.Dispose() Start-Sleep 10 # Submit the challenge for approval Submit-ACMEChallenge $Alias -ChallengeType http-01 # Wait for status update on challenge $Cycles=0 # Check Status each minute do { if ($Cycles -eq 5) {break} start-Sleep 60 $AllStatus=Update-ACMEIdentifier $Alias -ChallengeType http-01 $Status = [Collections.Generic.List[Object]]($AllStatus.Challenges.ToArray()) $StatusObj=($Status[($Status.FindIndex( {$args[0].Token -eq $ChallengeObj.Token}))]) } while ($StatusObj.Status -eq "pending") # If status is still pending, then setup new challenge } while ($StatusObj.Status -eq "pending") # if status is invalid then stop challenges if ($StatusObj.Status -eq "invalid") { $RuntimeError=1 break } # Add alias to array of approved domains $SANList+=$Alias if ($SANList.Length -ne 0) { $AltIdRefs+=$Alias } } # if no errors then get certificate if ($RuntimeError -eq 0) { $CertName="Exch"+$TimeStamp $TimeStamp = (Get-Date -Format s) -replace '-' -replace 'T' -replace ':' New-ACMECertificate $SANList[0] -Generate -AlternativeIdentifierRefs $AltIdRefs -Alias $CertName start-Sleep 10 Submit-ACMECertificate $CertName do { start-Sleep 10 $CertResult = Update-ACMECertificate $CertName } while ($CertResult.IssuerSerialNumber -eq "") #Export issuer certificate # Get-ACMECertificate $CertName -ExportIssuerPEM $WorkDirectory"\\3-Certificates\\Issuer-"$CertName".crt.pem" -ExportIssuerDER $WorkDirectory"\\3-Certificates\\Issuer-"$CertName".crt" # Export private key in PEM-format Get-ACMECertificate $CertName -ExportKeyPEM $WorkDirectory"\\3-Certificates\\"$CertName".key.pem" # Export certificate signing request(CSR) in PEM-format # Get-ACMECertificate $CertName -ExportCsrPEM $WorkDirectory"\\3-Certificates\\"$CertName".csr.pem" # Export Certificate in PEM-format Get-ACMECertificate $CertName -ExportCertificatePEM $WorkDirectory"\\3-Certificates\\"$CertName".crt.pem" # Export PKCS#12 (PFX) Archive Get-ACMECertificate $CertName -ExportPkcs12 $WorkDirectory"\\3-Certificates\\"$CertName".pfx" -CertificatePassword $CertPass # Add exchange management powershell module and setup certificate for exchange services. Add-PSSnapin Microsoft.Exchange.Management.PowerShell.SnapIn start-Sleep 10 Import-ExchangeCertificate -Filename $WorkDirectory"\\3-Certificates\\"$CertName".pfx" -Password (ConvertTo-SecureString -String $CertPass -AsPlainText -Force)|Enable-ExchangeCertificate -Services "IIS,IMAP,POP,SMTP" -Force # Add web management powershell module and setup certificate for iis services (Not tested yet) # Import-Module -Name WebAdministration # Import-PfxCertificate -FilePath $WorkDirectory"\\3-Certificates\\"$CertName".pfx" Cert:\LocalMachine\my -Password (ConvertTo-SecureString -String $CertPass -AsPlainText -Force) # Set-ItemProperty -Path "IIS:\Sites\Default Web Site" -Name ftpServer.security.sslCertHash -Value $CertResult.Thumbprint # Upload certificate file to Edge $ftpCert = [System.Net.FtpWebRequest]::Create($FTPSiteCert+"Cert.crt.pem") $ftpCert = [System.Net.FtpWebRequest]$ftpCert $ftpCert.Method = [System.Net.WebRequestMethods+Ftp]::UploadFile $ftpCert.Credentials = new-object System.Net.NetworkCredential($FTPUser,$FTPPass) $ftpCert.UseBinary = $true $ftpCert.UsePassive = $true $content = [System.IO.File]::ReadAllBytes($WorkDirectory+"\\3-Certificates\\"+$CertName+".crt.pem") $ftpCert.ContentLength = $content.Length $rsCert = $ftpCert.GetRequestStream() $rsCert.Write($content, 0, $content.Length) $rsCert.Close() $rsCert.Dispose() Start-Sleep 10 # Upload HTTP private key file to Frontserver $ftpKey = [System.Net.FtpWebRequest]::Create($FTPSiteCert+"Cert.key.pem") $ftpKey = [System.Net.FtpWebRequest]$ftpKey $ftpKey.Method = [System.Net.WebRequestMethods+Ftp]::UploadFile $ftpKey.Credentials = new-object System.Net.NetworkCredential($FTPUser,$FTPPass) $ftpKey.UseBinary = $true $ftpKey.UsePassive = $true $content = [System.IO.File]::ReadAllBytes($WorkDirectory+"\\3-Certificates\\"+$CertName+".key.pem") $ftpKey.ContentLength = $content.Length $rsKey = $ftpKey.GetRequestStream() $rsKey.Write($content, 0, $content.Length) $rsKey.Close() $rsKey.Dispose() Start-Sleep 10 }