# Subject alternative names

**URL:** <https://community.letsencrypt.org/t/subject-alternative-names/122606>\
**Category:** Help\
**Created:** [May 13, 2020, 10:39am UTC](https://community.letsencrypt.org/t/subject-alternative-names/122606 "2020-05-13T10:39:40Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![gamliel](https://sea3.discourse-cdn.com/letsencrypt/user_avatar/community.letsencrypt.org/gamliel/32/39394_2.png) [@gamliel](https://community.letsencrypt.org/u/gamliel)\
**Post date:** [May 13, 2020, 10:39am UTC](https://community.letsencrypt.org/t/subject-alternative-names/122606/1 "2020-05-13T10:39:41Z")

</div>

Please fill out the fields below so we can help you better. Note: you must provide your domain name to get help. Domain names for issued certificates are all made public in Certificate Transparency logs (e.g. [https://crt.sh/?q=example.com](https://crt.sh/?q=example.com)), so withholding your domain name here does not increase secrecy, but only makes it harder for us to provide help.

My domain is:easyfx.eu

I ran this command:

It produced this output:

My web server is (include version):

The operating system my web server runs on is (include version):

My hosting provider, if applicable, is:

I can login to a root shell on my machine (yes or no, or I don’t know):

I’m using a control panel to manage my site (no, or provide the name and version of the control panel):

The version of my client is (e.g. output of `certbot --version` or `certbot-auto --version` if you’re using Certbot):

Hi,  
i have automation running on azure the first request is from certbot that includes alternative names  
but when acme-challenge run in renews without the alternative names.

attached the renewal acme process

# Create a state object and save it to the harddrive

$state = New-ACMEState -Path $env:TEMP

$serviceName = ‘LetsEncrypt’

# Fetch the service directory and save it in the state

Get-ACMEServiceDirectory $state -ServiceName $serviceName -PassThru;

# Get the first anti-replay nonce

New-ACMENonce $state;

# Create an account key. The state will make sure it’s stored.

New-ACMEAccountKey $state -PassThru;

# Register the account key with the acme service. The account key will automatically be read from the state

New-ACMEAccount $state -EmailAddresses $EmailAddress -AcceptTOS;

# Load an state object to have service directory and account keys available

$state = Get-ACMEState -Path $env:TEMP;

# It might be neccessary to acquire a new nonce, so we’ll just do it for the sake of the example.

New-ACMENonce $state -PassThru;

# Create the identifier for the DNS name

$identifier = New-ACMEIdentifier $domain;

# Create the order object at the ACME service.

$order = New-ACMEOrder $state -Identifiers $identifier;

# Fetch the authorizations for that order

$authZ = Get-ACMEAuthorization -State $state -Order $order;

# Select a challenge to fullfill

$challenge = Get-ACMEChallenge $state $authZ “http-01”;

# Inspect the challenge data

$challenge.Data;

# Create the file requested by the challenge

$fileName = $env:TMP + ‘’ + $challenge.Token;

Set-Content -Path $fileName -Value $challenge.Data.Content -NoNewline;

$blobName = “.well-known/acme-challenge/” + $challenge.Token

$storageAccount = Get-AzureRmStorageAccount -ResourceGroupName $STResourceGroupName -Name $storageName

$ctx = $storageAccount.Context

Set-AzureStorageBlobContent -File $fileName -Container “public” -Context $ctx -Blob $blobName

# Signal the ACME server that the challenge is ready

$challenge | Complete-ACMEChallenge $state;

# Wait a little bit and update the order, until we see the states

while($order.Status -notin (“ready”,“invalid”)) {

Start-Sleep -Seconds 10;

$order | Update-ACMEOrder $state -PassThru;

}

# We should have a valid order now and should be able to complete it

# Therefore we need a certificate key

$certKey = New-ACMECertificateKey -Path “$env:TEMP$domain.key.xml”;

# Complete the order - this will issue a certificate singing request

Complete-ACMEOrder $state -Order $order -CertificateKey $certKey;

# Now we wait until the ACME service provides the certificate url

while(-not $order.CertificateUrl) {

Start-Sleep -Seconds 15

$order | Update-Order $state -PassThru

}

# As soon as the url shows up we can create the PFX

$password = ConvertTo-SecureString -String “12345678” -Force -AsPlainText

Export-ACMECertificate $state -Order $order -CertificateKey $certKey -Path “$env:TEMP$domain.pfx” -Password $password;

$tmpPfx = Get-PfxData -FilePath “$env:TEMP$domain.pfx” -Password $password

Export-PfxCertificate -PFXData $tmpPfx -FilePath “$env:TEMP\fullchain.pfx” -Password $password -ChainOption BuildChain

# Delete blob to check DNS

Remove-AzureStorageBlob -Container “public” -Context $ctx -Blob $blobName

### RENEW APPLICATION GATEWAY CERTIFICATE

$appgw = Get-AzureRmApplicationGateway -ResourceGroupName $AGResourceGroupName -Name $AGName

Set-AzApplicationGatewaySSLCertificate -Name $AGOldCertName -ApplicationGateway $appgw -CertificateFile “$env:TEMP\fullchain.pfx” -Password $password

Set-AzapplicationGateway -ApplicationGateway $appgw

Thanks

---

<div class="post-metadata">

**Author:** ![\_az](https://avatars.discourse-cdn.com/v4/letter/_/22d042/32.png) [@\_az](https://community.letsencrypt.org/u/_az)\
**Post date:** [May 13, 2020, 11:01am UTC](https://community.letsencrypt.org/t/subject-alternative-names/122606/2 "2020-05-13T11:01:14Z")

</div>

> [@gamliel](#):
>
> ```
> # Create the identifier for the DNS name
> $identifier = New-ACMEIdentifier $domain;
> # Create the order object at the ACME service.
> $order = New-ACMEOrder $state -Identifiers $identifier;
> 
> ```

Here, you are only passing in a single domain name to `New-ACMEOrder`. You can pass an array of domains as the `-Identifiers` argument, and each of these identifiers will be a SAN on the certificate. There is an example of SAN usage here: [https://github.com/PKISharp/ACME-PS/blob/master/samples/CreateOrderM.ps1](https://github.com/PKISharp/ACME-PS/blob/master/samples/CreateOrderM.ps1)

Keep in mind that this means that the order will contain multiple authorizations, and you will need to loop over them and solve them. There is an example of looping over authorizations here: [https://github.com/PKISharp/ACME-PS/blob/master/samples/FullfillChallenge.ps1](https://github.com/PKISharp/ACME-PS/blob/master/samples/FullfillChallenge.ps1)

---

<div class="post-metadata">

**Author:** ![gamliel](https://sea3.discourse-cdn.com/letsencrypt/user_avatar/community.letsencrypt.org/gamliel/32/39394_2.png) [@gamliel](https://community.letsencrypt.org/u/gamliel)\
**Post date:** [May 13, 2020, 11:05am UTC](https://community.letsencrypt.org/t/subject-alternative-names/122606/3 "2020-05-13T11:05:42Z")

</div>

wow king again thanks appreciate your help  
ill do some test and update

---

<div class="post-metadata">

**Author:** ![gamliel](https://sea3.discourse-cdn.com/letsencrypt/user_avatar/community.letsencrypt.org/gamliel/32/39394_2.png) [@gamliel](https://community.letsencrypt.org/u/gamliel)\
**Post date:** [May 13, 2020, 4:37pm UTC](https://community.letsencrypt.org/t/subject-alternative-names/122606/4 "2020-05-13T16:37:46Z")

</div>

tried this way but get errors  
$domain = $DnsName

$EmailAddress = $ContactEmails

$STResourceGroupName = $letsencryptResourceGroupName

$storageName = $letsencryptStorageAccountName

$AGResourceGroupName = $wafresourcegroupname

$AGName = $wafname

$AGOldCertName = $DnsName

Enable-AzureRmAlias

Import-Module Az.Storage

Import-Module PKI

## Azure Login

# If Runbook for Azure Automation

$connection = Get-AutomationConnection -Name AzureRunAsConnection

connect-AzAccount -ServicePrincipal -Tenant $connection.TenantID -ApplicationID $connection.ApplicationID -CertificateThumbprint $connection.CertificateThumbprint

# Create a state object and save it to the harddrive

$state = New-ACMEState -Path $env:TEMP

$serviceName = ‘LetsEncrypt’

$acmeStateDir = New-ACMEState -Path $env:TEMP;

$dnsIdentifiers = @(“easyfx.eu”,“www.easyfx.eu”,“clientzone.easyfx.eu”);

# Fetch the service directory and save it in the state

Get-ACMEServiceDirectory $state -ServiceName $serviceName -PassThru;

# Get the first anti-replay nonce

New-ACMENonce $state;

# Create an account key. The state will make sure it’s stored.

New-ACMEAccountKey $state -PassThru;

# Register the account key with the acme service. The account key will automatically be read from the state

New-ACMEAccount $state -EmailAddresses $EmailAddress -AcceptTOS;

# Load an state object to have service directory and account keys available

$state = Get-ACMEState -Path $env:TEMP;

# It might be neccessary to acquire a new nonce, so we’ll just do it for the sake of the example.

New-ACMENonce $state -PassThru;

# Create the identifier for the DNS name

$identifier = New-ACMEIdentifier $dnsIdentifiers;

# Create the order object at the ACME service.

$order = New-ACMEOrder -State $acmeStateDir -Identifiers $dnsIdentifiers;

# Fetch the authorizations for that order

$authZ = Get-ACMEAuthorization -State $state -Order $order;

# Select a challenge to fullfill

$challenge = Get-ACMEChallenge $state $authZ “http-01”;

# Inspect the challenge data

$challenge.Data;

# Create the file requested by the challenge

$fileName = $env:TMP + ‘’ + $challenge.Token;

Set-Content -Path $fileName -Value $challenge.Data.Content -NoNewline;

$blobName = “.well-known/acme-challenge/” + $challenge.Token

$storageAccount = Get-AzureRmStorageAccount -ResourceGroupName $STResourceGroupName -Name $storageName

$ctx = $storageAccount.Context

Set-AzureStorageBlobContent -File $fileName -Container “public” -Context $ctx -Blob $blobName

# Signal the ACME server that the challenge is ready

$challenge | Complete-ACMEChallenge $state;

# Wait a little bit and update the order, until we see the states

while($order.Status -notin (“ready”,“invalid”)) {

Start-Sleep -Seconds 10;

$order | Update-ACMEOrder $state -PassThru;

}

# We should have a valid order now and should be able to complete it

# Therefore we need a certificate key

$certKey = New-ACMECertificateKey -Path “$env:TEMP$domain.key.xml”;

# Complete the order - this will issue a certificate singing request

Complete-ACMEOrder $state -Order $order -CertificateKey $certKey;

# Now we wait until the ACME service provides the certificate url

while(-not $order.CertificateUrl) {

Start-Sleep -Seconds 15

$order | Update-Order $state -PassThru

}

# As soon as the url shows up we can create the PFX

$password = ConvertTo-SecureString -String “12345678” -Force -AsPlainText

Export-ACMECertificate $state -Order $order -CertificateKey $certKey -Path “$env:TEMP$domain.pfx” -Password $password;

$tmpPfx = Get-PfxData -FilePath “$env:TEMP$domain.pfx” -Password $password

Export-PfxCertificate -PFXData $tmpPfx -FilePath “$env:TEMP\fullchain.pfx” -Password $password -ChainOption BuildChain

# Delete blob to check DNS

Remove-AzureStorageBlob -Container “public” -Context $ctx -Blob $blobName

### RENEW APPLICATION GATEWAY CERTIFICATE

$appgw = Get-AzureRmApplicationGateway -ResourceGroupName $AGResourceGroupName -Name $AGName

Set-AzApplicationGatewaySSLCertificate -Name $AGOldCertName -ApplicationGateway $appgw -CertificateFile “$env:TEMP\fullchain.pfx” -Password $password

Set-AzapplicationGateway -ApplicationGateway $appgw

---

<div class="post-metadata">

**Author:** ![gamliel](https://sea3.discourse-cdn.com/letsencrypt/user_avatar/community.letsencrypt.org/gamliel/32/39394_2.png) [@gamliel](https://community.letsencrypt.org/u/gamliel)\
**Post date:** [May 13, 2020, 4:38pm UTC](https://community.letsencrypt.org/t/subject-alternative-names/122606/5 "2020-05-13T16:38:18Z")

</div>

- $identifier = New-ACMEIdentifier $dnsIdentifiers;
- 

```auto
                           ~~~~~~~~~~~~~~~

```

```auto

  * CategoryInfo : InvalidData: (:) [New-ACMEIdentifier], ParameterBindingArgumentTransformationException
  * FullyQualifiedErrorId : ParameterArgumentTransformationError,New-ACMEIdentifier

Get-ACMEChallenge : Cannot process argument transformation on parameter 'Authorization'. Cannot convert the
"System.Object[]" value of type "System.Object[]" to type "AcmeAuthorization".
At line:183 char:39

* $challenge = Get-ACMEChallenge $state $authZ "http-01";
```

---

<div class="post-metadata">

**Author:** ![\_az](https://avatars.discourse-cdn.com/v4/letter/_/22d042/32.png) [@\_az](https://community.letsencrypt.org/u/_az)\
**Post date:** [May 14, 2020, 1:00am UTC](https://community.letsencrypt.org/t/subject-alternative-names/122606/6 "2020-05-14T01:00:10Z")

</div>

As hinted, multiple domains means there will be multiple authorizations - one for each domain. You need to loop over them individually, as in the example code.

It may be better to use the ACME-PS samples as a starting point, rather than trying to retrofit your existing PS script.

---

<div class="post-metadata">

**Author:** ![gamliel](https://sea3.discourse-cdn.com/letsencrypt/user_avatar/community.letsencrypt.org/gamliel/32/39394_2.png) [@gamliel](https://community.letsencrypt.org/u/gamliel)\
**Post date:** [May 14, 2020, 2:10pm UTC](https://community.letsencrypt.org/t/subject-alternative-names/122606/7 "2020-05-14T14:10:52Z")

</div>

thanks i created some script but now on the domain  
[fxpackage.com](http://fxpackage.com) i have this error  
Failed  
Server returned Problem (Status: 403).Â´nOrder’s status (“invalid”) is not acceptable for finalization (Server returned Problem (Status: 403).Â´nOrder’s status (“invalid”) is not acceptable for finalization)

---

<div class="post-metadata">

**Author:** ![system](https://global.discourse-cdn.com/letsencrypt/original/3X/c/a/ca6c06ea1ea201324bba7048c6841ce60236468d.png) [@system](https://community.letsencrypt.org/u/system)\
**Post date:** [June 13, 2020, 2:10pm UTC](https://community.letsencrypt.org/t/subject-alternative-names/122606/8 "2020-06-13T14:10:55Z")

</div>

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.
