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 solely by the IIS Manager application, 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 script below creates a certificate that contains a SAN and exports it from IIS Manager in a format that can 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 IIS Manager must be installed on your machine. The Windows PowerShell ISE environment is recommended for this workflow, as it provides both a script window and a command prompt window.

If a certificate for the hostname exists on your machine, the script prompts 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 the text below 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 the script was saved, and run the .\certificateScript.ps1 script.

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:")[-1].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"

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 as a .cer file and the server certificate as a .pfx file. 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 script above. 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 certificate as the certificate password, type a certificate alias different than the alias you provided for the root certificate, and 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 restarts, which may take 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 you did 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. Type certificate as the password and type 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 restarts, which may take a few minutes.

The new certificate for your ArcGIS Enterprise portal and hosting server will now be trusted by all web browsers.