Skip To Content

Create a domain certificate

ArcGIS Enterprise uses HTTPS, which requires that a certificate be configured with your portal. Beginning in 2017, the Chrome internet browser only trusts domain certificates that contain a subject alternative name (SAN) parameter. This parameter cannot be configured by the IIS Manager application alone, meaning certificates produced from that workflow are not trusted by Chrome.

In most cases, your IT administrator will provide you with the necessary domain certificate. The below script creates a certificate that contains a SAN and exports it from IIS Manager in a format that can then be imported into your portal.

Save and run the certificate script

To create a domain certificate, your domain must already have a certificate authority, and your machine must have IIS Manager installed. The Windows PowerShell ISE environment is preferable for this workflow, as it provides both a script window and a command prompt window.

If a certificate for the hostname already exists on your machine, the script will prompt you on whether you want to overwrite that existing certificate.

  1. Open the Windows PowerShell ISE application on your machine using the Run as administrator option, and create a script.
  2. Copy and paste the below text into the script window of the application.
  3. Save the script as a .ps1 file, such as certificateScript.ps1.
  4. In the command prompt panel of the ISE application, change directories to where your script was saved, and run the following script: .\certificateScript.ps1

Certificate script to be run in PowerShell

function New-CertificateRequest {
    param ( [string]$hostname )
 
    $CATemplate = "WebServer"
    $CertificateINI = "cert.ini"
    $CertificateREQ = "cert.req"
    $CertificateRSP = "cert.rsp"
    $CertificateCER = "cert.cer"
    $Subject = 'Subject="CN=' + $hostname + '"'
    $FriendlyName = 'FriendlyName=' + $hostname
    $SAN = '_continue_ = "dns=' + $hostname + '&"'
 
    ### INI file generation
    new-item -type file $CertificateINI -force
    add-content $CertificateINI '[Version]'
    add-content $CertificateINI 'Signature="$Windows NT$"'
    add-content $CertificateINI ''
    add-content $CertificateINI '[NewRequest]'
    add-content $CertificateINI $Subject
    add-content $CertificateINI 'Exportable=TRUE'
    add-content $CertificateINI 'KeyLength=2048'
    add-content $CertificateINI 'KeySpec=1'
    add-content $CertificateINI 'KeyUsage=0xA0'
    add-content $CertificateINI 'MachineKeySet=True'
    add-content $CertificateINI 'ProviderName="Microsoft RSA SChannel Cryptographic Provider"'
    add-content $CertificateINI 'ProviderType=12'
    add-content $CertificateINI 'SMIME=FALSE'
    add-content $CertificateINI 'RequestType=PKCS10'
    add-content $CertificateINI $FriendlyName
    add-content $CertificateINI '[Strings]'
    add-content $CertificateINI 'szOID_ENHANCED_KEY_USAGE = "2.5.29.37"'
    add-content $CertificateINI 'szOID_PKIX_KP_SERVER_AUTH = "1.3.6.1.5.5.7.3.1"'
    add-content $CertificateINI 'szOID_PKIX_KP_CLIENT_AUTH = "1.3.6.1.5.5.7.3.2"'
    add-content $CertificateINI 'szOID_SUBJECT_ALT_NAME2 = "2.5.29.17"'
    add-content $CertificateINI '[Extensions]'
    add-content $CertificateINI '2.5.29.17 = "{text}"'
    add-content $CertificateINI $SAN

 
    ### Certificate request generation
    if (test-path $CertificateREQ) {del $CertificateREQ}
    certreq -new $CertificateINI $CertificateREQ
 
    ### Online certificate request and import
    if ($OnlineCA) {
        if (test-path $CertificateCER) {del $CertificateCER}
        if (test-path $CertificateRSP) {del $CertificateRSP}
        certreq -submit -attrib "CertificateTemplate:$CATemplate" -config $OnlineCA $CertificateREQ $CertificateCER
        certreq -accept $CertificateCER
    }
    
    ### Delete certificate request files
    if (test-path $CertificateINI) {del $CertificateINI}
    if (test-path $CertificateREQ) {del $CertificateREQ}
    if (test-path $CertificateRSP) {del $CertificateRSP}
    if (test-path $CertificateCER) {del $CertificateCER}
}

## Main
if ($args.length -ne 0) {$hostname = $args[0]}
else {$hostname = "$env:computername.$env:userdnsdomain".ToLower()}

# Check if a CA exists in the domain and if IIS is installed
if (@(certutil -dump | select-string "Config:")) {
    $OnlineCA = (certutil -dump | select-string "Config:").Line.replace("``",'"').replace("'",'"').split('"')[1]
} else {
    Write-Host "Unable to determine certificate authority (CA) for this domain"
    Exit
}
if (-not @(Get-Service W3SVC -ErrorAction Ignore)) {
    Write-Host "IIS is not installed on this machine"
    Exit
}

# Check if a certificate already exists and prompt user to overwrite
if (@(Get-ChildItem cert:\LocalMachine\My | where-object { $_.FriendlyName -eq "$hostname" }).count -ne 0) {
    Write-Host "A certificate for $hostname already exists"
    $reply = Read-Host -Prompt "Overwrite existing certificate? (y/n)"
    if ( $reply -notmatch "[yY]" ) { Exit }
    Get-ChildItem cert:\LocalMachine\My | where-object { $_.FriendlyName -eq "$hostname" } | Remove-Item
}
New-CertificateRequest -hostname $hostname > $null
Write-Host "`nCreated a new certificate for $hostname"

# Create https binding if necessary and add new cert to https binding
import-module WebAdministration
if (@(Get-WebBinding -name "Default Web Site" | Where-Object {$_.protocol -eq "https"}).count -eq 0) {
    New-WebBinding -name "Default Web Site" -Protocol https -Port 443
    Write-Host 'Created https binding for "Default Web Site"'
}
if (@(netsh http show sslcert ipport="0.0.0.0:443" | select-string -pattern "IP:port").count -ne 0) {
    netsh http delete sslcert ipport="0.0.0.0:443" > $null
}
$cert = (Get-ChildItem cert:\LocalMachine\My | where-object { $_.FriendlyName -eq "$hostname" } | Select-Object -First 1).Thumbprint
$guid = [guid]::NewGuid().ToString("B")
netsh http add sslcert ipport="0.0.0.0:443" certhash=$cert certstorename=MY appid="$guid" > $null
Write-Host "Updated https binding to use this certificate"

# Export certificate to .pfx (Windows 2012 and higher)
$scriptPath = split-path -parent $MyInvocation.MyCommand.Definition
if ([Environment]::OSVersion.Version -ge (new-object 'Version' 6,2)) {
    $pfxname = $hostname.Split(".")[0]
    if ($pfxname -eq '*') {$pfxname = "wildcard"}
    $pfxname = $pfxname + ".pfx"
    Remove-Item $scriptPath\$pfxname -ErrorAction Ignore
    $pfxpwd = ConvertTo-SecureString -String "certificate" -Force -AsPlainText
    $cert = (Get-ChildItem cert:\LocalMachine\My | where-object { $_.FriendlyName -eq "$hostname" } | Select-Object -First 1).Thumbprint
    Get-ChildItem -Path cert:\localMachine\My\$cert | Export-PfxCertificate -FilePath $scriptPath\$pfxname -Password $pfxpwd -ChainOption EndEntityCertOnly > $null
    Write-Host "Exported certificate in PFX format with password 'certificate' to"
    Write-Host "    $scriptPath\$pfxname"
}

# Export domain CA root certificate to domainRoot.cer
Remove-Item $scriptPath\domainRoot.cer -ErrorAction Ignore
certutil -config $OnlineCA '-ca.cert' $scriptPath\domainRoot.cer > $null
Write-Host "Exported domain root certificate to"
Write-Host "    $scriptPath\domainRoot.cer"
Note:

If you receive a security exception error message when attempting to run the script, the execution policy needs to be adjusted. To make a temporary change to allow the script to execute, run the following command:

Set-ExecutionPolicy RemoteSigned -scope Process

Import the new certificate into an existing deployment

If your ArcGIS Enterprise deployment has already been set up, follow the steps below to import the new certificate into your ArcGIS Enterprise portal and your hosting server, and to make it the default web certificate for both components.

These steps outline how to import both certificate files exported by the script: the domain root certificate in .cer format and the server certificate in .pfx format. The locations of both should be in the same folder where you saved the script; they are also provided in the command prompt output when the script is executed.

  1. Sign in to your ArcGIS Portal Administrator Directory at https://sample.domain.com:7443/arcgis/portaladmin.
  2. Browse to Security > SSL Certificates and click Import Root or Intermediate Certificate.
  3. Provide an alias for the certificate and the file path to the domainRoot.cer file exported by the above script. Select the Do not restart the portal after import option (the operation in step 7 will restart the portal), and click Import.
  4. Browse back to SSL Certificates and click Import Existing Server Certificate.
  5. Type the certificate password certificate and a certificate alias different than the alias you provided for the root certificate, and then browse to the .pfx file on your machine. Click Import.
  6. Return to the SSL Certificates page and click Update.
  7. Replace the value for Web server SSL certificate with the alias of the .pfx certificate you imported in step 5. Click Update. The portal will restart, which takes up to a few minutes.
  8. Sign in to your ArcGIS Server Administrator Directory at https://sample.domain.com:6443/arcgis/admin.
  9. Browse to machines > <machine name> > sslcertificates and click importRootOrIntermediate.
  10. Provide an alias as in step 3 and browse to the location of the domainRoot.cer file. Click import.
  11. Browse back to the machine's page and click importExistingServerCertificate.
  12. Again, type the certificate password and the location of the .pfx certificate on your machine. Click Submit.
  13. Return to the machine's page and click edit.
  14. Replace the value for Web server SSL certificate with the alias of the new domain certificate. Click Save Edits. The server machine will restart, which takes up to a few minutes.

When you have completed the workflow, the new certificate for your ArcGIS Enterprise portal and hosting server will be trusted by all web browsers.