diff --git a/.github/workflows/DNS.yml b/.github/workflows/DNS.yml
index 615e5d8b..a13cb51c 100644
--- a/.github/workflows/DNS.yml
+++ b/.github/workflows/DNS.yml
@@ -332,7 +332,7 @@ jobs:
       with:
         envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG http_proxy https_proxy TokenName1 TokenName2 TokenName3 TokenName4 TokenName5 ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}'
         prepare: |
-          pkg_add curl socat
+          pkg_add curl socat libnghttp2
         usesh: true
         copyback: false
         run: |
@@ -384,7 +384,7 @@ jobs:
       with:
         envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG http_proxy https_proxy TokenName1 TokenName2 TokenName3 TokenName4 TokenName5 ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}'
         prepare: |
-          pkg install -y curl socat
+          pkg install -y curl socat libnghttp2
         usesh: true
         copyback: false
         run: |
diff --git a/README.md b/README.md
index 73ff3321..717ecf5f 100644
--- a/README.md
+++ b/README.md
@@ -506,10 +506,6 @@ Support this project with your organization. Your logo will show up here with a
 <a href="https://opencollective.com/acmesh/organization/9/website"><img src="https://opencollective.com/acmesh/organization/9/avatar.svg"></a>
 
 
-#### Sponsors
-
-[![quantumca-acmesh-logo](https://user-images.githubusercontent.com/8305679/183255712-634ee1db-bb61-4c03-bca0-bacce99e078c.svg)](https://www.quantumca.com.cn/?__utm_source=acmesh-donation)
-
 
 # 19. License & Others
 
diff --git a/acme.sh b/acme.sh
index 75efde4c..92faeb5e 100755
--- a/acme.sh
+++ b/acme.sh
@@ -931,7 +931,7 @@ fi
 
 _egrep_o() {
   if [ "$__USE_EGREP" ]; then
-    egrep -o "$1"
+    egrep -o -- "$1"
   else
     sed -n 's/.*\('"$1"'\).*/\1/p'
   fi
@@ -1561,7 +1561,7 @@ createDomainKey() {
 createCSR() {
   _info "Creating csr"
   if [ -z "$1" ]; then
-    _usage "Usage: $PROJECT_ENTRY --create-csr --domain <domain.tld> [--domain <domain2.tld> ...]"
+    _usage "Usage: $PROJECT_ENTRY --create-csr --domain <domain.tld> [--domain <domain2.tld> ...] [--ecc]"
     return
   fi
 
@@ -3130,7 +3130,7 @@ _setNginx() {
         _err "nginx command is not found."
         return 1
       fi
-      NGINX_CONF="$(nginx -V 2>&1 | _egrep_o "--conf-path=[^ ]* " | tr -d " ")"
+      NGINX_CONF="$(nginx -V 2>&1 | _egrep_o "\-\-conf-path=[^ ]* " | tr -d " ")"
       _debug NGINX_CONF "$NGINX_CONF"
       NGINX_CONF="$(echo "$NGINX_CONF" | cut -d = -f 2)"
       _debug NGINX_CONF "$NGINX_CONF"
@@ -6925,7 +6925,7 @@ Parameters:
 
   These parameters are to install the cert to nginx/apache or any other server after issue/renew a cert:
 
-  --cert-file <file>                Path to copy the cert file to after issue/renew..
+  --cert-file <file>                Path to copy the cert file to after issue/renew.
   --key-file <file>                 Path to copy the key file to after issue/renew.
   --ca-file <file>                  Path to copy the intermediate cert file to after issue/renew.
   --fullchain-file <file>           Path to copy the fullchain cert file to after issue/renew.
@@ -6955,7 +6955,8 @@ Parameters:
   --no-profile                      Only valid for '--install' command, which means: do not install aliases to user profile.
   --no-color                        Do not output color text.
   --force-color                     Force output of color text. Useful for non-interactive use with the aha tool for HTML E-Mails.
-  --ecc                             Specifies to use the ECC cert. Valid for '--install-cert', '--renew', '--revoke', '--to-pkcs12' and '--create-csr'
+  --ecc                             Specifies use of the ECC cert. Only valid for '--install-cert', '--renew', '--remove ', '--revoke',
+                                      '--deploy', '--to-pkcs8', '--to-pkcs12' and '--create-csr'.
   --csr <file>                      Specifies the input csr.
   --pre-hook <command>              Command to be run before obtaining any certificates.
   --post-hook <command>             Command to be run after attempting to obtain/renew certificates. Runs regardless of whether obtain/renew succeeded or failed.
diff --git a/deploy/panos.sh b/deploy/panos.sh
index ef622ded..89458e5f 100644
--- a/deploy/panos.sh
+++ b/deploy/panos.sh
@@ -7,11 +7,15 @@
 #
 # Firewall admin with superuser and IP address is required.
 #
-# export PANOS_USER=""  # required
-# export PANOS_PASS=""  # required
-# export PANOS_HOST=""  # required
+# REQURED:
+#     export PANOS_HOST=""
+#     export PANOS_USER=""    #User *MUST* have Commit and Import Permissions in XML API for Admin Role
+#     export PANOS_PASS=""
+#
+# The script will automatically generate a new API key if
+# no key is found, or if a saved key has expired or is invalid.
 
-# This function is to parse the XML
+# This function is to parse the XML response from the firewall
 parse_response() {
   type=$2
   if [ "$type" = 'keygen' ]; then
@@ -23,25 +27,46 @@ parse_response() {
       message="PAN-OS Key could not be set."
     fi
   else
-    status=$(echo "$1" | sed 's/^.*"\([a-z]*\)".*/\1/g')
-    message=$(echo "$1" | sed 's/^.*<result>\(.*\)<\/result.*/\1/g')
+    status=$(echo "$1" | tr -d '\n' | sed 's/^.*"\([a-z]*\)".*/\1/g')
+    message=$(echo "$1" | tr -d '\n' | sed 's/.*\(<result>\|<msg>\|<line>\)\([^<]*\).*/\2/g')
+    _debug "Firewall message:  $message"
+    if [ "$type" = 'keytest' ] && [ "$status" != "success" ]; then
+      _debug "****  API Key has EXPIRED or is INVALID ****"
+      unset _panos_key
+    fi
   fi
   return 0
 }
 
+#This function is used to deploy to the firewall
 deployer() {
   content=""
-  type=$1 # Types are keygen, cert, key, commit
-  _debug "**** Deploying $type *****"
+  type=$1 # Types are keytest, keygen, cert, key, commit
   panos_url="https://$_panos_host/api/"
+
+  #Test API Key by performing a lookup
+  if [ "$type" = 'keytest' ]; then
+    _debug "**** Testing saved API Key ****"
+    _H1="Content-Type: application/x-www-form-urlencoded"
+    # Get Version Info to test key
+    content="type=version&key=$_panos_key"
+    ## Exclude all scopes for the empty commit
+    #_exclude_scope="<policy-and-objects>exclude</policy-and-objects><device-and-network>exclude</device-and-network><shared-object>exclude</shared-object>"
+    #content="type=commit&action=partial&key=$_panos_key&cmd=<commit><partial>$_exclude_scope<admin><member>acmekeytest</member></admin></partial></commit>"
+  fi
+
+  # Generate API Key
   if [ "$type" = 'keygen' ]; then
+    _debug "**** Generating new API Key ****"
     _H1="Content-Type: application/x-www-form-urlencoded"
     content="type=keygen&user=$_panos_user&password=$_panos_pass"
     # content="$content${nl}--$delim${nl}Content-Disposition: form-data; type=\"keygen\"; user=\"$_panos_user\"; password=\"$_panos_pass\"${nl}Content-Type: application/octet-stream${nl}${nl}"
   fi
 
+  # Deploy Cert or Key
   if [ "$type" = 'cert' ] || [ "$type" = 'key' ]; then
-    #Generate DEIM
+    _debug "**** Deploying $type ****"
+    #Generate DELIM
     delim="-----MultipartDelimiter$(date "+%s%N")"
     nl="\015\012"
     #Set Header
@@ -61,7 +86,7 @@ deployer() {
       content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"key\"\r\n\r\n$_panos_key"
       content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"format\"\r\n\r\npem"
       content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"passphrase\"\r\n\r\n123456"
-      content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"file\"; filename=\"$(basename "$_ckey")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_ckey")"
+      content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"file\"; filename=\"$(basename "$_cdomain.key")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_ckey")"
     fi
     #Close multipart
     content="$content${nl}--$delim--${nl}${nl}"
@@ -69,16 +94,25 @@ deployer() {
     content=$(printf %b "$content")
   fi
 
+  # Commit changes
   if [ "$type" = 'commit' ]; then
+    _debug "**** Committing changes ****"
     export _H1="Content-Type: application/x-www-form-urlencoded"
-    cmd=$(printf "%s" "<commit><partial><$_panos_user></$_panos_user></partial></commit>" | _url_encode)
-    content="type=commit&key=$_panos_key&cmd=$cmd"
+    #Check for force commit - will commit ALL uncommited changes to the firewall. Use with caution!
+    if [ "$FORCE" ]; then
+      _debug "Force switch detected.  Committing ALL changes to the firewall."
+      cmd=$(printf "%s" "<commit><partial><force><admin><member>$_panos_user</member></admin></force></partial></commit>" | _url_encode)
+    else
+      _exclude_scope="<policy-and-objects>exclude</policy-and-objects><device-and-network>exclude</device-and-network>"
+      cmd=$(printf "%s" "<commit><partial>$_exclude_scope<admin><member>$_panos_user</member></admin></partial></commit>" | _url_encode)
+    fi
+    content="type=commit&action=partial&key=$_panos_key&cmd=$cmd"
   fi
+
   response=$(_post "$content" "$panos_url" "" "POST")
   parse_response "$response" "$type"
   # Saving response to variables
   response_status=$status
-  #DEBUG
   _debug response_status "$response_status"
   if [ "$response_status" = "success" ]; then
     _debug "Successfully deployed $type"
@@ -92,43 +126,85 @@ deployer() {
 
 # This is the main function that will call the other functions to deploy everything.
 panos_deploy() {
-  _cdomain="$1"
+  _cdomain=$(echo "$1" | sed 's/*/WILDCARD_/g') #Wildcard Safe Filename
   _ckey="$2"
   _cfullchain="$5"
-  # PANOS ENV VAR check
-  if [ -z "$PANOS_USER" ] || [ -z "$PANOS_PASS" ] || [ -z "$PANOS_HOST" ]; then
-    _debug "No ENV variables found lets check for saved variables"
-    _getdeployconf PANOS_USER
-    _getdeployconf PANOS_PASS
-    _getdeployconf PANOS_HOST
-    _panos_user=$PANOS_USER
-    _panos_pass=$PANOS_PASS
-    _panos_host=$PANOS_HOST
-    if [ -z "$_panos_user" ] && [ -z "$_panos_pass" ] && [ -z "$_panos_host" ]; then
-      _err "No host, user and pass found.. If this is the first time deploying please set PANOS_HOST, PANOS_USER and PANOS_PASS in environment variables. Delete them after you have succesfully deployed certs."
-      return 1
-    else
-      _debug "Using saved env variables."
-    fi
+
+  # VALID FILE CHECK
+  if [ ! -f "$_ckey" ] || [ ! -f "$_cfullchain" ]; then
+    _err "Unable to find a valid key and/or cert.  If this is an ECDSA/ECC cert, use the --ecc flag when deploying."
+    return 1
+  fi
+
+  # PANOS_HOST
+  if [ "$PANOS_HOST" ]; then
+    _debug "Detected ENV variable PANOS_HOST. Saving to file."
+    _savedeployconf PANOS_HOST "$PANOS_HOST" 1
   else
-    _debug "Detected ENV variables to be saved to the deploy conf."
-    # Encrypt and save user
+    _debug "Attempting to load variable PANOS_HOST from file."
+    _getdeployconf PANOS_HOST
+  fi
+
+  # PANOS USER
+  if [ "$PANOS_USER" ]; then
+    _debug "Detected ENV variable PANOS_USER. Saving to file."
     _savedeployconf PANOS_USER "$PANOS_USER" 1
+  else
+    _debug "Attempting to load variable PANOS_USER from file."
+    _getdeployconf PANOS_USER
+  fi
+
+  # PANOS_PASS
+  if [ "$PANOS_PASS" ]; then
+    _debug "Detected ENV variable PANOS_PASS. Saving to file."
     _savedeployconf PANOS_PASS "$PANOS_PASS" 1
-    _savedeployconf PANOS_HOST "$PANOS_HOST" 1
-    _panos_user="$PANOS_USER"
-    _panos_pass="$PANOS_PASS"
-    _panos_host="$PANOS_HOST"
+  else
+    _debug "Attempting to load variable PANOS_PASS from file."
+    _getdeployconf PANOS_PASS
   fi
-  _debug "Let's use username and pass to generate token."
-  if [ -z "$_panos_user" ] || [ -z "$_panos_pass" ] || [ -z "$_panos_host" ]; then
-    _err "Please pass username and password and host as env variables PANOS_USER, PANOS_PASS and PANOS_HOST"
+
+  # PANOS_KEY
+  _getdeployconf PANOS_KEY
+  if [ "$PANOS_KEY" ]; then
+    _debug "Detected saved key."
+    _panos_key=$PANOS_KEY
+  else
+    _debug "No key detected"
+    unset _panos_key
+  fi
+
+  #Store variables
+  _panos_host=$PANOS_HOST
+  _panos_user=$PANOS_USER
+  _panos_pass=$PANOS_PASS
+
+  #Test API Key if found.  If the key is invalid, the variable _panos_key will be unset.
+  if [ "$_panos_host" ] && [ "$_panos_key" ]; then
+    _debug "**** Testing API KEY ****"
+    deployer keytest
+  fi
+
+  # Check for valid variables
+  if [ -z "$_panos_host" ]; then
+    _err "No host found. If this is your first time deploying, please set PANOS_HOST in ENV variables. You can delete it after you have successfully deployed the certs."
+    return 1
+  elif [ -z "$_panos_user" ]; then
+    _err "No user found. If this is your first time deploying, please set PANOS_USER in ENV variables. You can delete it after you have successfully deployed the certs."
+    return 1
+  elif [ -z "$_panos_pass" ]; then
+    _err "No password found. If this is your first time deploying, please set PANOS_PASS in ENV variables. You can delete it after you have successfully deployed the certs."
     return 1
   else
-    _debug "Getting PANOS KEY"
-    deployer keygen
+    # Generate a new API key if no valid API key is found
+    if [ -z "$_panos_key" ]; then
+      _debug "**** Generating new PANOS API KEY ****"
+      deployer keygen
+      _savedeployconf PANOS_KEY "$_panos_key" 1
+    fi
+
+    # Confirm that a valid key was generated
     if [ -z "$_panos_key" ]; then
-      _err "Missing apikey."
+      _err "Unable to generate an API key.  The user and pass may be invalid or not authorized to generate a new key.  Please check the PANOS_USER and PANOS_PASS credentials and try again"
       return 1
     else
       deployer cert
diff --git a/dnsapi/dns_dnsexit.sh b/dnsapi/dns_dnsexit.sh
new file mode 100644
index 00000000..62d7d757
--- /dev/null
+++ b/dnsapi/dns_dnsexit.sh
@@ -0,0 +1,185 @@
+#!/usr/bin/env sh
+
+#use dns-01 at DNSExit.com
+
+#Author: Samuel Jimenez
+#Report Bugs here: https://github.com/acmesh-official/acme.sh
+
+#DNSEXIT_API_KEY=ABCDEFGHIJ0123456789abcdefghij
+#DNSEXIT_AUTH_USER=login@email.address
+#DNSEXIT_AUTH_PASS=aStrongPassword
+DNSEXIT_API_URL="https://api.dnsexit.com/dns/"
+DNSEXIT_HOSTS_URL="https://update.dnsexit.com/ipupdate/hosts.jsp"
+
+########  Public functions #####################
+#Usage: dns_dnsexit_add   _acme-challenge.*.domain.com   "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
+dns_dnsexit_add() {
+  fulldomain=$1
+  txtvalue=$2
+  _info "Using DNSExit.com"
+  _debug fulldomain "$fulldomain"
+  _debug txtvalue "$txtvalue"
+
+  _debug 'Load account auth'
+  if ! get_account_info; then
+    return 1
+  fi
+
+  _debug 'First detect the root zone'
+  if ! _get_root "$fulldomain"; then
+    return 1
+  fi
+  _debug _sub_domain "$_sub_domain"
+  _debug _domain "$_domain"
+
+  if ! _dnsexit_rest "{\"domain\":\"$_domain\",\"add\":{\"type\":\"TXT\",\"name\":\"$_sub_domain\",\"content\":\"$txtvalue\",\"ttl\":0,\"overwrite\":false}}"; then
+    _err "$response"
+    return 1
+  fi
+
+  _debug2 _response "$response"
+  return 0
+}
+
+#Usage: fulldomain txtvalue
+#Remove the txt record after validation.
+dns_dnsexit_rm() {
+  fulldomain=$1
+  txtvalue=$2
+  _info "Using DNSExit.com"
+  _debug fulldomain "$fulldomain"
+  _debug txtvalue "$txtvalue"
+
+  _debug 'Load account auth'
+  if ! get_account_info; then
+    return 1
+  fi
+
+  _debug 'First detect the root zone'
+  if ! _get_root "$fulldomain"; then
+    _err "$response"
+    return 1
+  fi
+  _debug _sub_domain "$_sub_domain"
+  _debug _domain "$_domain"
+
+  if ! _dnsexit_rest "{\"domain\":\"$_domain\",\"delete\":{\"type\":\"TXT\",\"name\":\"$_sub_domain\",\"content\":\"$txtvalue\"}}"; then
+    _err "$response"
+    return 1
+  fi
+
+  _debug2 _response "$response"
+  return 0
+}
+
+####################  Private functions below ##################################
+#_acme-challenge.www.domain.com
+#returns
+# _sub_domain=_acme-challenge.www
+# _domain=domain.com
+_get_root() {
+  domain=$1
+  i=1
+  while true; do
+    _domain=$(printf "%s" "$domain" | cut -d . -f $i-100)
+    _debug h "$_domain"
+    if [ -z "$_domain" ]; then
+      return 1
+    fi
+
+    _debug login "$DNSEXIT_AUTH_USER"
+    _debug password "$DNSEXIT_AUTH_PASS"
+    _debug domain "$_domain"
+
+    _dnsexit_http "login=$DNSEXIT_AUTH_USER&password=$DNSEXIT_AUTH_PASS&domain=$_domain"
+
+    if _contains "$response" "0=$_domain"; then
+      _sub_domain="$(echo "$fulldomain" | sed "s/\\.$_domain\$//")"
+      return 0
+    else
+      _debug "Go to next level of $_domain"
+    fi
+    i=$(_math "$i" + 1)
+  done
+
+  return 1
+}
+
+_dnsexit_rest() {
+  m=POST
+  ep=""
+  data="$1"
+  _debug _dnsexit_rest "$ep"
+  _debug data "$data"
+
+  api_key_trimmed=$(echo "$DNSEXIT_API_KEY" | tr -d '"')
+
+  export _H1="apikey: $api_key_trimmed"
+  export _H2='Content-Type: application/json'
+
+  if [ "$m" != "GET" ]; then
+    _debug data "$data"
+    response="$(_post "$data" "$DNSEXIT_API_URL/$ep" "" "$m")"
+  else
+    response="$(_get "$DNSEXIT_API_URL/$ep")"
+  fi
+
+  if [ "$?" != "0" ]; then
+    _err "Error $ep"
+    return 1
+  fi
+
+  _debug2 response "$response"
+  return 0
+}
+
+_dnsexit_http() {
+  m=GET
+  param="$1"
+  _debug param "$param"
+  _debug get "$DNSEXIT_HOSTS_URL?$param"
+
+  response="$(_get "$DNSEXIT_HOSTS_URL?$param")"
+
+  _debug response "$response"
+
+  if [ "$?" != "0" ]; then
+    _err "Error $param"
+    return 1
+  fi
+
+  _debug2 response "$response"
+  return 0
+}
+
+get_account_info() {
+
+  DNSEXIT_API_KEY="${DNSEXIT_API_KEY:-$(_readaccountconf_mutable DNSEXIT_API_KEY)}"
+  if test -z "$DNSEXIT_API_KEY"; then
+    DNSEXIT_API_KEY=''
+    _err 'DNSEXIT_API_KEY was not exported'
+    return 1
+  fi
+
+  _saveaccountconf_mutable DNSEXIT_API_KEY "$DNSEXIT_API_KEY"
+
+  DNSEXIT_AUTH_USER="${DNSEXIT_AUTH_USER:-$(_readaccountconf_mutable DNSEXIT_AUTH_USER)}"
+  if test -z "$DNSEXIT_AUTH_USER"; then
+    DNSEXIT_AUTH_USER=""
+    _err 'DNSEXIT_AUTH_USER was not exported'
+    return 1
+  fi
+
+  _saveaccountconf_mutable DNSEXIT_AUTH_USER "$DNSEXIT_AUTH_USER"
+
+  DNSEXIT_AUTH_PASS="${DNSEXIT_AUTH_PASS:-$(_readaccountconf_mutable DNSEXIT_AUTH_PASS)}"
+  if test -z "$DNSEXIT_AUTH_PASS"; then
+    DNSEXIT_AUTH_PASS=""
+    _err 'DNSEXIT_AUTH_PASS was not exported'
+    return 1
+  fi
+
+  _saveaccountconf_mutable DNSEXIT_AUTH_PASS "$DNSEXIT_AUTH_PASS"
+
+  return 0
+}
diff --git a/dnsapi/dns_inwx.sh b/dnsapi/dns_inwx.sh
index ba789da9..e483c0e8 100755
--- a/dnsapi/dns_inwx.sh
+++ b/dnsapi/dns_inwx.sh
@@ -194,7 +194,7 @@ _inwx_login() {
 
   response="$(_post "$xml_content" "$INWX_Api" "" "POST")"
 
-  INWX_Cookie=$(printf "Cookie: %s" "$(grep "domrobot=" "$HTTP_HEADER" | grep "^Set-Cookie:" | _tail_n 1 | _egrep_o 'domrobot=[^;]*;' | tr -d ';')")
+  INWX_Cookie=$(printf "Cookie: %s" "$(grep "domrobot=" "$HTTP_HEADER" | grep -i "^Set-Cookie:" | _tail_n 1 | _egrep_o 'domrobot=[^;]*;' | tr -d ';')")
   _H1=$INWX_Cookie
   export _H1
   export INWX_Cookie
diff --git a/dnsapi/dns_pleskxml.sh b/dnsapi/dns_pleskxml.sh
index 799c374c..81973e07 100644
--- a/dnsapi/dns_pleskxml.sh
+++ b/dnsapi/dns_pleskxml.sh
@@ -46,6 +46,10 @@ pleskxml_tplt_get_domains="<packet><webspace><get><filter/><dataset><gen_info/><
 # Also used to test credentials and URI.
 # No params.
 
+pleskxml_tplt_get_additional_domains="<packet><site><get><filter/><dataset><gen_info/></dataset></get></site></packet>"
+# Get a list of additional domains that PLESK can manage, so we can check root domain + host for acme.sh
+# No params.
+
 pleskxml_tplt_get_dns_records="<packet><dns><get_rec><filter><site-id>%s</site-id></filter></get_rec></dns></packet>"
 # Get all DNS records for a Plesk domain ID.
 # PARAM = Plesk domain id to query
@@ -375,16 +379,44 @@ _pleskxml_get_root_domain() {
     return 1
   fi
 
-  # Generate a crude list of domains known to this Plesk account.
+  # Generate a crude list of domains known to this Plesk account based on subscriptions.
   # We convert <ascii-name> tags to <name> so it'll flag on a hit with either <name> or <ascii-name> fields,
   # for non-Western character sets.
   # Output will be one line per known domain, containing 2 <name> tages and a single <id> tag
   # We don't actually need to check for type, name, *and* id, but it guarantees only usable lines are returned.
 
   output="$(_api_response_split "$pleskxml_prettyprint_result" 'result' '<status>ok</status>' | sed 's/<ascii-name>/<name>/g;s/<\/ascii-name>/<\/name>/g' | grep '<name>' | grep '<id>')"
+  debug_output="$(printf "%s" "$output" | sed -n 's:.*<name>\(.*\)</name>.*:\1:p')"
+
+  _debug 'Domains managed by Plesk server are:'
+  _debug "$debug_output"
+
+  _debug "Querying Plesk server for list of additional managed domains..."
+
+  _call_api "$pleskxml_tplt_get_additional_domains"
+  if [ "$pleskxml_retcode" -ne 0 ]; then
+    return 1
+  fi
+
+  # Generate a crude list of additional domains known to this Plesk account based on sites.
+  # We convert <ascii-name> tags to <name> so it'll flag on a hit with either <name> or <ascii-name> fields,
+  # for non-Western character sets.
+  # Output will be one line per known domain, containing 2 <name> tages and a single <id> tag
+  # We don't actually need to check for type, name, *and* id, but it guarantees only usable lines are returned.
+
+  output_additional="$(_api_response_split "$pleskxml_prettyprint_result" 'result' '<status>ok</status>' | sed 's/<ascii-name>/<name>/g;s/<\/ascii-name>/<\/name>/g' | grep '<name>' | grep '<id>')"
+  debug_additional="$(printf "%s" "$output_additional" | sed -n 's:.*<name>\(.*\)</name>.*:\1:p')"
+
+  _debug 'Additional domains managed by Plesk server are:'
+  _debug "$debug_additional"
+
+  # Concate the two outputs together.
+
+  output="$(printf "%s" "$output $NEWLINE $output_additional")"
+  debug_output="$(printf "%s" "$output" | sed -n 's:.*<name>\(.*\)</name>.*:\1:p')"
 
-  _debug 'Domains managed by Plesk server are (ignore the hacked output):'
-  _debug "$output"
+  _debug 'Domains (including additional) managed by Plesk server are:'
+  _debug "$debug_output"
 
   # loop and test if domain, or any parent domain, is managed by Plesk
   # Loop until we don't have any '.' in the string we're testing as a candidate Plesk-managed domain