You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@solr.apache.org by ep...@apache.org on 2023/07/06 17:22:46 UTC

[solr] branch main updated: SOLR-16829: Delegate arg parsing and help usage to java. (Round 1) (#1670)

This is an automated email from the ASF dual-hosted git repository.

epugh pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/solr.git


The following commit(s) were added to refs/heads/main by this push:
     new fb6e879a078 SOLR-16829: Delegate arg parsing and help usage to java.  (Round 1) (#1670)
fb6e879a078 is described below

commit fb6e879a07803f5237908f264a4d1570e3bce8d6
Author: Eric Pugh <ep...@opensourceconnections.com>
AuthorDate: Thu Jul 6 13:22:39 2023 -0400

    SOLR-16829: Delegate arg parsing and help usage to java.  (Round 1) (#1670)
    
    Delegate arg parsing and help usage from bin/solr and bin/solr.cmd to java layer for create, create_core, create_collection, delete, healthcheck and status commands.
    * Update the various Ref Guide pages
    * Fix a lot of odd issues with command option choices that existed.
    * expand the scope of the bats tests.
---
 solr/CHANGES.txt                                   |   2 +
 solr/bin/solr                                      | 490 +--------------------
 solr/bin/solr.cmd                                  | 442 +------------------
 .../src/java/org/apache/solr/cli/AssertTool.java   |  10 +-
 .../src/java/org/apache/solr/cli/AuthTool.java     |   8 -
 .../src/java/org/apache/solr/cli/ConfigTool.java   |  86 ++--
 .../org/apache/solr/cli/CreateCollectionTool.java  | 138 +++++-
 .../java/org/apache/solr/cli/CreateCoreTool.java   | 130 +++---
 .../src/java/org/apache/solr/cli/CreateTool.java   |   5 +-
 .../src/java/org/apache/solr/cli/DeleteTool.java   |   4 +-
 .../java/org/apache/solr/cli/HealthcheckTool.java  |   8 +-
 .../core/src/java/org/apache/solr/cli/SolrCLI.java | 197 +++------
 .../src/java/org/apache/solr/cli/StatusTool.java   |  26 +-
 .../org/apache/solr/cli/HealthcheckToolTest.java   |   4 +-
 .../apache/solr/cloud/SolrCloudExampleTest.java    |   5 +-
 .../solr/security/BasicAuthIntegrationTest.java    |   4 +-
 .../test/{test_status.bats => test_config.bats}    |  36 +-
 solr/packaging/test/test_create_collection.bats    |  30 +-
 solr/packaging/test/test_help.bats                 |  31 +-
 solr/packaging/test/test_status.bats               |  18 +-
 .../pages/solr-control-script-reference.adoc       |  74 +---
 21 files changed, 463 insertions(+), 1285 deletions(-)

diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index 50985af23bd..a1605154082 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -50,6 +50,8 @@ Other Changes
 
 * SOLR-16798: Remove the bin/solr -f pattern in favour of bin/solr start -f explicit command. (Bence Szabo via Eric Pugh)
 
+* SOLR-16829: Delegate arg parsing and help usage from bin/solr and bin/solr.cmd to java layer for create, create_core, create_collection, delete, healthcheck and status commands. (Eric Pugh, Will White, Mikhail Khludnev)  
+
 ==================  9.3.0 ==================
 
 Upgrade Notes
diff --git a/solr/bin/solr b/solr/bin/solr
index 16adbe9c987..b5f06d1ecf5 100644
--- a/solr/bin/solr
+++ b/solr/bin/solr
@@ -38,7 +38,7 @@
 # Note: This is particularly handy for running multiple instances on a
 # single installation, or for quick tests.
 #
-# Finally, developers and enthusiasts who frequently run from an SVN
+# Finally, developers and enthusiasts who frequently run from an Git
 # checkout, and do not want to locally modify bin/solr.in.sh, can put
 # a customized include file at ~/.solr.in.sh.
 #
@@ -435,130 +435,6 @@ function print_usage() {
     echo ""
     echo "  NOTE: To see if any Solr servers are running, do: solr status"
     echo ""
-  elif [ "$CMD" == "healthcheck" ]; then
-    echo ""
-    echo "Usage: solr healthcheck [-c collection] [-z zkHost] [-V]"
-    echo ""
-    echo "Can be run from remote (non-Solr) hosts, as long as a proper ZooKeeper connection is provided"
-    echo ""
-    echo "  -c <collection>         Collection to run healthcheck against."
-    echo ""
-    echo "  -z or -zkHost <zkHost>  Zookeeper connection string; unnecessary if ZK_HOST is defined in solr.in.sh;"
-    echo "                            otherwise, default is localhost:9983"
-    echo ""
-    echo "  -V/-verbose             Enable more verbose output for this script."
-    echo ""
-  elif [ "$CMD" == "status" ]; then
-    echo ""
-    echo "Usage: solr status"
-    echo ""
-    echo "  This command will show the status of all running Solr servers."
-    echo "  It can only detect those Solr servers running on the current host."
-    echo ""
-  elif [ "$CMD" == "create" ]; then
-    echo ""
-    echo "Usage: solr create [-c name] [-d confdir] [-n configName] [-shards #] [-replicationFactor #] [-p port] [-V]"
-    echo ""
-    echo "  Create a core or collection depending on whether Solr is running in standalone (core) or SolrCloud"
-    echo "  mode (collection). In other words, this action detects which mode Solr is running in, and then takes"
-    echo "  the appropriate action (either create_core or create_collection). For detailed usage instructions, do:"
-    echo ""
-    echo "    bin/solr create_core -help"
-    echo ""
-    echo "       or"
-    echo ""
-    echo "    bin/solr create_collection -help"
-    echo ""
-  elif [ "$CMD" == "delete" ]; then
-    echo ""
-    echo "Usage: solr delete [-c name] [-deleteConfig true|false] [-p port] [-V]"
-    echo ""
-    echo "  Deletes a core or collection depending on whether Solr is running in standalone (core) or SolrCloud"
-    echo "  mode (collection). If you're deleting a collection in SolrCloud mode, the default behavior is to also"
-    echo "  delete the configuration directory from Zookeeper so long as it is not being used by another collection."
-    echo "  You can override this behavior by passing -deleteConfig false when running this command."
-    echo ""
-    echo "  Can be run on remote (non-Solr) hosts, as long as a valid SOLR_HOST is provided in solr.in.sh"
-    echo ""
-    echo "  -c <name>               Name of the core / collection to delete"
-    echo ""
-    echo "  -deleteConfig <boolean> Delete the configuration directory from Zookeeper; default is true"
-    echo ""
-    echo "  -p or -port <port>      Port of a local Solr instance where you want to delete the core/collection"
-    echo "                            If not specified, the script will search the local system for a running"
-    echo "                            Solr instance and will use the port of the first server it finds."
-    echo ""
-    echo "  -V/-verbose             Enable more verbose output for this script."
-    echo ""
-  elif [ "$CMD" == "create_core" ]; then
-    echo ""
-    echo "Usage: solr create_core [-c core] [-d confdir] [-p port] [-V]"
-    echo ""
-    echo "When a configSet is used, this can be run from remote (non-Solr) hosts.  If pointing at a non-configSet directory, this"
-    echo "must be run from the host that you wish to create the core on"
-    echo ""
-    echo "  -c <core>           Name of core to create"
-    echo ""
-    echo "  -d <confdir>        Configuration directory to copy when creating the new core, built-in options are:"
-    echo ""
-    echo "      _default: Minimal configuration, which supports enabling/disabling field-guessing support"
-    echo "      sample_techproducts_configs: Example configuration with many optional features enabled to"
-    echo "         demonstrate the full power of Solr"
-    echo ""
-    echo "      If not specified, default is: _default"
-    echo ""
-    echo "      Alternatively, you can pass the path to your own configuration directory instead of using"
-    echo "      one of the built-in configurations, such as: bin/solr create_core -c mycore -d /tmp/myconfig"
-    echo ""
-    echo "  -p or -port <port>  Port of a local Solr instance where you want to create the new core"
-    echo "                        If not specified, the script will search the local system for a running"
-    echo "                        Solr instance and will use the port of the first server it finds."
-    echo ""
-    echo "  -force              If attempting to start Solr as the root user, the script will exit with a warning that running Solr as "root" can cause problems."
-    echo "                        It is possible to override this warning with the `-force` parameter."
-    echo ""
-    echo "  -V/-verbose   Enable more verbose output for this script"
-    echo ""
-  elif [ "$CMD" == "create_collection" ]; then
-    echo ""
-    echo "Usage: solr create_collection [-c collection] [-d confdir] [-n configName] [-shards #] [-replicationFactor #] [-p port] [-V]"
-    echo ""
-    echo "Can be run from remote (non-Solr) hosts, as long as a valid SOLR_HOST is provided in solr.in.sh"
-    echo "  -c <collection>               Name of collection to create"
-    echo ""
-    echo "  -d <confdir>                  Configuration directory to copy when creating the new collection, built-in options are:"
-    echo ""
-    echo "        _default: Minimal configuration, which supports enabling/disabling field-guessing support"
-    echo "          sample_techproducts_configs: Example configuration with many optional features enabled to"
-    echo "          demonstrate the full power of Solr"
-    echo ""
-    echo "        If not specified, default is: _default"
-    echo ""
-    echo "        Alternatively, you can pass the path to your own configuration directory instead of using"
-    echo "        one of the built-in configurations, such as: bin/solr create_collection -c mycoll -d /tmp/myconfig"
-    echo ""
-    echo "        By default the script will upload the specified confdir directory into Zookeeper using the same"
-    echo "        name as the collection (-c) option. Alternatively, if you want to reuse an existing directory"
-    echo "        or create a confdir in Zookeeper that can be shared by multiple collections, use the -n option"
-    echo ""
-    echo "  -n <configName>                 Name the configuration directory in Zookeeper; by default, the configuration"
-    echo "                                    will be uploaded to Zookeeper using the collection name (-c), but if you want"
-    echo "                                    to use an existing directory or override the name of the configuration in"
-    echo "                                    Zookeeper, then use the -c option."
-    echo ""
-    echo "  -shards <#>                     Number of shards to split the collection into; default is 1"
-    echo ""
-    echo "  -replicationFactor or -rf <#>   Number of copies of each document in the collection, default is 1 (no replication)"
-    echo ""
-    echo "  -p or -port <port>              Port of a local Solr instance where you want to create the new collection"
-    echo "                                    If not specified, the script will search the local system for a running"
-    echo "                                    Solr instance and will use the port of the first server it finds."
-    echo ""
-    echo "  -force                          If attempting to start Solr as the root user, the script will exit with a warning that running Solr as "root" can cause problems."
-    echo "                                    It is possible to override this warning with the `-force` parameter."
-    echo ""
-    echo "  -V/-verbose                     Enable more verbose output for this script."
-    echo ""
   elif [ "$CMD" == "zk" ]; then
     print_short_zk_usage ""
     echo "         Can be run on remote (non-Solr) hosts, as long as valid ZK_HOST information is provided"
@@ -784,7 +660,7 @@ function get_status() {
         port=$(jetty_port "$ID")
         if [ "$port" != "" ]; then
           echo -e "\nSolr process $ID running on port $port"
-          run_tool status -solr "$SOLR_URL_SCHEME://$SOLR_TOOL_HOST:$port/solr"
+          run_tool status -solrUrl "$SOLR_URL_SCHEME://$SOLR_TOOL_HOST:$port/solr" "$@"
           echo ""
         else
           echo -e "\nSolr process $ID from $PIDF not found."
@@ -802,12 +678,13 @@ function get_status() {
           if [ "$port" != "" ]; then
             echo ""
             echo "Solr process $ID running on port $port"
-            run_tool status -solr "$SOLR_URL_SCHEME://$SOLR_TOOL_HOST:$port/solr"
+            run_tool status -solrUrl "$SOLR_URL_SCHEME://$SOLR_TOOL_HOST:$port/solr" "$@"
             echo ""
           fi
       done
     else
       echo -e "\nNo Solr nodes are running.\n"
+      run_tool status "$@"
     fi
   fi
 
@@ -937,8 +814,8 @@ function stop_solr() {
 
 if [ $# -eq 1 ]; then
   case $1 in
-    -help|-h)
-        print_usage ""
+    -help|-h)    
+        run_tool ""    
         exit
     ;;
     -version|-v|version)
@@ -953,35 +830,14 @@ if [ $# -gt 0 ]; then
   shift
 else
   # no args - just show usage and exit
-  print_usage ""
+  run_tool "$@"
   exit
 fi
 
+# status tool
 if [ "$SCRIPT_CMD" == "status" ]; then
-  if [ $# -gt 0 ]; then
-    while true; do
-      case "$1" in
-          -help|-h)
-              print_usage "$SCRIPT_CMD"
-              exit 0
-          ;;
-          --)
-              shift
-              break
-          ;;
-          *)
-              if [ "$1" != "" ]; then
-                print_usage "$SCRIPT_CMD" "Unrecognized or misplaced argument: $1!"
-                exit 1
-              else
-                break # out-of-args, stop looping
-              fi
-          ;;
-      esac
-    done
-  fi
   get_status
-  exit
+  exit $?
 fi
 
 # assert tool
@@ -990,339 +846,27 @@ if [ "$SCRIPT_CMD" == "assert" ]; then
   exit $?
 fi
 
-# run a healthcheck and exit if requested
+# healthcheck tool
 if [ "$SCRIPT_CMD" == "healthcheck" ]; then
-
-  VERBOSE=""
-
-  if [ $# -gt 0 ]; then
-    while true; do
-      case "$1" in
-          -c|-collection)
-              if [[ -z "$2" || "${2:0:1}" == "-" ]]; then
-                print_usage "$SCRIPT_CMD" "Collection name is required when using the $1 option!"
-                exit 1
-              fi
-              HEALTHCHECK_COLLECTION="$2"
-              shift 2
-          ;;
-          -z|-zkhost|-zkHost)
-              if [[ -z "$2" || "${2:0:1}" == "-" ]]; then
-                print_usage "$SCRIPT_CMD" "ZooKeeper connection string is required when using the $1 option!"
-                exit 1
-              fi
-              ZK_HOST="$2"
-              shift 2
-          ;;
-          -help|-h)
-              print_usage "$SCRIPT_CMD"
-              exit 0
-          ;;
-          -V|-verbose)
-              VERBOSE="-verbose"
-              shift
-          ;;
-          --)
-              shift
-              break
-          ;;
-          *)
-              if [ "$1" != "" ]; then
-                print_usage "$SCRIPT_CMD" "Unrecognized or misplaced argument: $1!"
-                exit 1
-              else
-                break # out-of-args, stop looping
-              fi
-          ;;
-      esac
-    done
-  fi
-
-  if [ -z "$ZK_HOST" ]; then
-    ZK_HOST=localhost:9983
-  fi
-
-  if [ -z "$HEALTHCHECK_COLLECTION" ]; then
-    echo "collection parameter is required!"
-    print_usage "healthcheck"
-    exit 1
-  fi
-
-  run_tool healthcheck -zkHost "$ZK_HOST" -collection "$HEALTHCHECK_COLLECTION" $VERBOSE
-
+  run_tool healthcheck "$@"
   exit $?
 fi
 
-if [[ "$SCRIPT_CMD" == "config" ]]; then
-  CONFIG_PARAMS=()
-
-  if [ $# -gt 0 ]; then
-    while true; do
-      case "$1" in
-          -z|-zkhost|-zkHost)
-              if [[ -z "$2" || "${2:0:1}" == "-" ]]; then
-                print_usage "$SCRIPT_CMD" "ZooKeeper connection string is required when using the $1 option!"
-                exit 1
-              fi
-              ZK_HOST="$2"
-              shift 2
-          ;;
-          -s|-scheme)
-              if [[ -z "$2" || "${2:0:1}" == "-" ]]; then
-                print_usage "$SCRIPT_CMD" "URL scheme is required when using the $1 option!"
-                exit 1
-              fi
-              SOLR_URL_SCHEME="$2"
-              shift 2
-          ;;
-          *)  # Pass through all other params
-              if [ "$1" != "" ]; then
-                CONFIG_PARAMS+=($1)
-                shift
-              else
-                break
-              fi
-          ;;
-      esac
-    done
-  fi
-  if [[ -n "$ZK_HOST" ]]; then
-    CONFIG_PARAMS+=("-z" "$ZK_HOST")
-  fi
-  if [[ -n "$SOLR_URL_SCHEME" ]]; then
-    CONFIG_PARAMS+=("-scheme" "$SOLR_URL_SCHEME")
-  fi
-  run_tool config "${CONFIG_PARAMS[@]}"
+# config tool
+if [ "$SCRIPT_CMD" == "config" ]; then
+  run_tool config "$@"
   exit $?
 fi
 
 # create a core or collection
 if [[ "$SCRIPT_CMD" == "create" || "$SCRIPT_CMD" == "create_core" || "$SCRIPT_CMD" == "create_collection" ]]; then
-
-  CREATE_NUM_SHARDS=1
-  CREATE_REPFACT=1
-  FORCE=false
-  VERBOSE=""
-
-  if [ $# -gt 0 ]; then
-    while true; do
-      case "${1:-}" in
-          -c|-core|-collection)
-              if [[ -z "$2" || "${2:0:1}" == "-" ]]; then
-                print_usage "$SCRIPT_CMD" "name is required when using the $1 option!"
-                exit 1
-              fi
-              CREATE_NAME="$2"
-              shift 2
-          ;;
-          -n|-confname)
-              if [[ -z "$2" || "${2:0:1}" == "-" ]]; then
-                print_usage "$SCRIPT_CMD" "Configuration name is required when using the $1 option!"
-                exit 1
-              fi
-              CREATE_CONFNAME="$2"
-              shift 2
-          ;;
-          -d|-confdir)
-              if [[ -z "$2" || "${2:0:1}" == "-" ]]; then
-                print_usage "$SCRIPT_CMD" "Configuration directory is required when using the $1 option!"
-                exit 1
-              fi
-              CREATE_CONFDIR="$2"
-              shift 2
-          ;;
-          -s|-shards)
-              if [[ -z "$2" || "${2:0:1}" == "-" ]]; then
-                print_usage "$SCRIPT_CMD" "Shard count is required when using the $1 option!"
-                exit 1
-              fi
-              CREATE_NUM_SHARDS="$2"
-              shift 2
-          ;;
-          -rf|-replicationFactor)
-              if [[ -z "$2" || "${2:0:1}" == "-" ]]; then
-                print_usage "$SCRIPT_CMD" "Replication factor is required when using the $1 option!"
-                exit 1
-              fi
-              CREATE_REPFACT="$2"
-              shift 2
-          ;;
-          -p|-port)
-              if [[ -z "$2" || "${2:0:1}" == "-" ]]; then
-                print_usage "$SCRIPT_CMD" "Solr port is required when using the $1 option!"
-                exit 1
-              fi
-              CREATE_PORT="$2"
-              shift 2
-          ;;
-          -V|-verbose)
-              VERBOSE="-verbose"
-              shift
-          ;;
-          -force)
-              FORCE=true
-              shift
-          ;;
-          -help|-h)
-              print_usage "$SCRIPT_CMD"
-              exit 0
-          ;;
-          --)
-              shift
-              break
-          ;;
-          *)
-              if [ -n "${1:-}" ]; then
-                print_usage "$SCRIPT_CMD" "Unrecognized or misplaced argument: $1!"
-                exit 1
-              else
-                break # out-of-args, stop looping
-              fi
-          ;;
-      esac
-    done
-  fi
-
-  : "${CREATE_CONFDIR:=_default}"
-
-  # validate the confdir arg (if provided)
-  if [[ ! -d "$SOLR_TIP/server/solr/configsets/$CREATE_CONFDIR" && ! -d "$CREATE_CONFDIR" ]]; then
-    echo -e "\nSpecified configuration directory $CREATE_CONFDIR not found!\n"
-    exit 1
-  fi
-
-  if [ -z "${CREATE_NAME:-}" ]; then
-    echo "Name (-c) argument is required!"
-    print_usage "$SCRIPT_CMD"
-    exit 1
-  fi
-
-  if [ -z "${CREATE_PORT:-}" ]; then
-    for ID in $(ps auxww | grep java | grep start\.jar | awk '{print $2}' | sort -r)
-      do
-        port=$(jetty_port "$ID")
-        if [ "$port" != "" ]; then
-          CREATE_PORT=$port
-          break
-        fi
-    done
-  fi
-
-  if [ -z "${CREATE_PORT:-}" ]; then
-    echo "Failed to determine the port of a local Solr instance, cannot create $CREATE_NAME!"
-    exit 1
-  fi
-
-  if [[ "$CREATE_CONFDIR" == "_default" ]] && [[ "${CREATE_CONFNAME:-_default}" == "_default" ]]; then
-    echo "WARNING: Using _default configset with data driven schema functionality. NOT RECOMMENDED for production use."
-    echo "         To turn off: bin/solr config -c $CREATE_NAME -p $CREATE_PORT -action set-user-property -property update.autoCreateFields -value false"
-  fi
-
-  if [[ $EUID -eq 0 ]] && [[ "$FORCE" == "false" ]] ; then
-    echo "WARNING: Creating cores as the root user can cause Solr to fail and is not advisable. Exiting."
-    echo "         If you started Solr as root (not advisable either), force core creation by adding argument -force"
-    exit 1
-  fi
-  if [ "$SCRIPT_CMD" == "create_core" ]; then
-    run_tool create_core -name "$CREATE_NAME" -solrUrl "$SOLR_URL_SCHEME://$SOLR_TOOL_HOST:$CREATE_PORT/solr" \
-      -confdir "$CREATE_CONFDIR" -configsetsDir "$SOLR_TIP/server/solr/configsets" \
-      $VERBOSE
-    exit $?
-  else
-    # should we be passing confname if it is unset?
-    run_tool "$SCRIPT_CMD" -name "$CREATE_NAME" -solrUrl "$SOLR_URL_SCHEME://$SOLR_TOOL_HOST:$CREATE_PORT/solr" \
-      -shards "$CREATE_NUM_SHARDS" -replicationFactor "$CREATE_REPFACT" \
-      -confname "${CREATE_CONFNAME:-}" -confdir "$CREATE_CONFDIR" \
-      -configsetsDir "$SOLR_TIP/server/solr/configsets" \
-      $VERBOSE
-    exit $?
-  fi
+  run_tool $SCRIPT_CMD $@
+  exit $?
 fi
 
 # delete a core or collection
 if [[ "$SCRIPT_CMD" == "delete" ]]; then
-
-  VERBOSE=""
-
-  if [ $# -gt 0 ]; then
-    while true; do
-      case "${1:-}" in
-          -c|-core|-collection)
-              if [[ -z "$2" || "${2:0:1}" == "-" ]]; then
-                print_usage "$SCRIPT_CMD" "name is required when using the $1 option!"
-                exit 1
-              fi
-              DELETE_NAME="$2"
-              shift 2
-          ;;
-          -p|-port)
-              if [[ -z "$2" || "${2:0:1}" == "-" ]]; then
-                print_usage "$SCRIPT_CMD" "Solr port is required when using the $1 option!"
-                exit 1
-              fi
-              DELETE_PORT="$2"
-              shift 2
-          ;;
-          -deleteConfig)
-              if [[ -z "$2" || "${2:0:1}" == "-" ]]; then
-                print_usage "$SCRIPT_CMD" "true|false is required when using the $1 option!"
-                exit 1
-              fi
-              DELETE_CONFIG="$2"
-              shift 2
-          ;;
-          -V|-verbose)
-              VERBOSE="-verbose"
-              shift
-          ;;
-          -help|-h)
-              print_usage "$SCRIPT_CMD"
-              exit 0
-          ;;
-          --)
-              shift
-              break
-          ;;
-          *)
-              if [ -n "${1:-}" ]; then
-                print_usage "$SCRIPT_CMD" "Unrecognized or misplaced argument: $1!"
-                exit 1
-              else
-                break # out-of-args, stop looping
-              fi
-          ;;
-      esac
-    done
-  fi
-
-  if [ -z "$DELETE_NAME" ]; then
-    echo "Name (-c) argument is required!"
-    print_usage "$SCRIPT_CMD"
-    exit 1
-  fi
-
-  # If not defined, use the collection name for the name of the configuration in Zookeeper
-  : "${DELETE_CONFIG:=true}"
-
-  if [ -z "${DELETE_PORT:-}" ]; then
-    for ID in $(ps auxww | grep java | grep start\.jar | awk '{print $2}' | sort -r)
-      do
-        port=$(jetty_port "$ID")
-        if [ "$port" != "" ]; then
-          DELETE_PORT=$port
-          break
-        fi
-    done
-  fi
-
-  if [ -z "${DELETE_PORT:-}" ]; then
-    echo "Failed to determine the port of a local Solr instance, cannot delete $DELETE_NAME!"
-    exit 1
-  fi
-
-  run_tool delete -name "$DELETE_NAME" -deleteConfig "$DELETE_CONFIG" \
-    -solrUrl "$SOLR_URL_SCHEME://$SOLR_TOOL_HOST:$DELETE_PORT/solr" \
-    $VERBOSE
+  run_tool $SCRIPT_CMD $@
   exit $?
 fi
 
diff --git a/solr/bin/solr.cmd b/solr/bin/solr.cmd
index e7fe9a898f2..5f83a2c95db 100755
--- a/solr/bin/solr.cmd
+++ b/solr/bin/solr.cmd
@@ -241,32 +241,11 @@ REM Only allow the command to be the first argument, assume start if not supplie
 IF "%1"=="start" goto set_script_cmd
 IF "%1"=="stop" goto set_script_cmd
 IF "%1"=="restart" goto set_script_cmd
-IF "%1"=="healthcheck" (
-  REM healthcheck uses different arg parsing strategy
-  set SCRIPT_CMD=healthcheck
-  SHIFT
-  goto parse_healthcheck_args
-)
-IF "%1"=="create" (
-  set SCRIPT_CMD=create
-  SHIFT
-  goto parse_create_args
-)
-IF "%1"=="create_core" (
-  set SCRIPT_CMD=create_core
-  SHIFT
-  goto parse_create_args
-)
-IF "%1"=="create_collection" (
-  set SCRIPT_CMD=create_collection
-  SHIFT
-  goto parse_create_args
-)
-IF "%1"=="delete" (
-  set SCRIPT_CMD=delete
-  SHIFT
-  goto parse_delete_args
-)
+IF "%1"=="healthcheck" goto run_solrcli
+IF "%1"=="create" goto run_solrcli
+IF "%1"=="create_core" goto run_solrcli
+IF "%1"=="create_collection" goto run_solrcli
+IF "%1"=="delete" goto run_solrcli
 IF "%1"=="zk" (
   set SCRIPT_CMD=zk
   SHIFT
@@ -278,13 +257,7 @@ IF "%1"=="auth" (
   SHIFT
   goto run_auth
 )
-IF "%1"=="config" (
-  REM config uses different arg parsing strategy
-  set SCRIPT_CMD=config
-  SHIFT
-  set CONFIG_ARGS=
-  goto parse_config_args
-)
+IF "%1"=="config" goto run_solrcli
 
 goto parse_args
 
@@ -299,14 +272,14 @@ IF "%FIRST_ARG%"=="/?" goto script_usage
 IF "%SCRIPT_CMD%"=="start" goto start_usage
 IF "%SCRIPT_CMD%"=="restart" goto start_usage
 IF "%SCRIPT_CMD%"=="stop" goto stop_usage
-IF "%SCRIPT_CMD%"=="healthcheck" goto healthcheck_usage
-IF "%SCRIPT_CMD%"=="create" goto create_usage
-IF "%SCRIPT_CMD%"=="create_core" goto create_core_usage
-IF "%SCRIPT_CMD%"=="create_collection" goto create_collection_usage
-IF "%SCRIPT_CMD%"=="delete" goto delete_usage
+IF "%SCRIPT_CMD%"=="healthcheck" goto run_solrcli
+IF "%SCRIPT_CMD%"=="create" goto run_solrcli
+IF "%SCRIPT_CMD%"=="create_core" goto run_solrcli
+IF "%SCRIPT_CMD%"=="create_collection" goto run_solrcli
+IF "%SCRIPT_CMD%"=="delete" goto run_solrcli
 IF  "%SCRIPT_CMD%"=="zk" goto zk_usage
 IF "%SCRIPT_CMD%"=="auth" goto auth_usage
-IF "%SCRIPT_CMD%"=="status" goto status_usage
+IF "%SCRIPT_CMD%"=="status" goto run_solrcli
 goto done
 
 :script_usage
@@ -343,9 +316,9 @@ goto done
 @echo   -h host       Specify the hostname for this Solr instance
 @echo.
 @echo   -p port       Specify the port to start the Solr HTTP listener on; default is 8983
-@echo "                  The specified port (SOLR_PORT) will also be used to determine the stop port"
-@echo "                  STOP_PORT=(\$SOLR_PORT-1000) and JMX RMI listen port RMI_PORT=(\$SOLR_PORT+10000). "
-@echo "                  For instance, if you set -p 8985, then the STOP_PORT=7985 and RMI_PORT=18985"
+@echo                   The specified port (SOLR_PORT) will also be used to determine the stop port
+@echo                   STOP_PORT=(%%SOLR_PORT%%-1000) and JMX RMI listen port RMI_PORT=(%%SOLR_PORT%%+10000).
+@echo                   For instance, if you set -p 8985, then the STOP_PORT=7985 and RMI_PORT=18985
 @echo.
 @echo   -d dir        Specify the Solr server directory; defaults to server
 @echo.
@@ -392,14 +365,6 @@ goto done
 @echo.
 goto done
 
-:status_usage
-@echo.
-@echo Usage: solr status
-@echo.
-@echo   NOTE: This command will show the status of all running Solr servers
-@echo.
-goto done
-
 :stop_usage
 @echo.
 @echo Usage: solr stop [-k key] [-p port] [-V]
@@ -416,128 +381,6 @@ goto done
 @echo.
 goto done
 
-:healthcheck_usage
-@echo.
-@echo Usage: solr healthcheck [-c collection] [-z zkHost] [-V]
-@echo.
-@echo Can be run from remote (non-Solr^) hosts, as long as a proper ZooKeeper connection is provided
-@echo.
-@echo   -c collection  Collection to run healthcheck against.
-@echo.
-@echo   -z zkHost      Zookeeper connection string; unnecessary if ZK_HOST is defined in solr.in.cmd;
-@echo                    otherwise, default is localhost:9983
-@echo.
-@echo   -V             Enable more verbose output
-@echo.
-goto done
-
-:create_usage
-echo.
-echo Usage: solr create [-c name] [-d confdir] [-n confname] [-shards #] [-replicationFactor #] [-p port] [-V]
-echo.
-echo   Create a core or collection depending on whether Solr is running in standalone (core) or SolrCloud
-echo   mode (collection). In other words, this action detects which mode Solr is running in, and then takes
-echo   the appropriate action (either create_core or create_collection). For detailed usage instructions, do:
-echo.
-echo     bin\solr create_core -help
-echo.
-echo        or
-echo.
-echo     bin\solr create_collection -help
-echo.
-goto done
-
-:delete_usage
-echo.
-echo Usage: solr delete [-c name] [-deleteConfig true^|false] [-p port] [-V]
-echo.
-echo  Deletes a core or collection depending on whether Solr is running in standalone (core) or SolrCloud
-echo  mode (collection). If you're deleting a collection in SolrCloud mode, the default behavior is to also
-echo  delete the configuration directory from Zookeeper so long as it is not being used by another collection.
-echo  You can override this behavior by passing -deleteConfig false when running this command.
-echo.
-echo  Can be run on remote (non-Solr^) hosts, as long as a valid SOLR_HOST is provided in solr.in.cmd
-echo.
-echo   -c name     Name of core to delete
-echo.
-echo   -deleteConfig boolean Delete the configuration directory from Zookeeper; default is true
-echo.
-echo   -p port     Port of a local Solr instance where you want to delete the core/collection
-echo                 If not specified, the script will search the local system for a running
-echo                 Solr instance and will use the port of the first server it finds.
-echo.
-echo   -V            Enables more verbose output.
-echo.
-goto done
-
-:create_core_usage
-echo.
-echo Usage: solr create_core [-c ^<core^>] [-d confdir] [-p port] [-V]
-echo.
-echo When a configSet is used, this can be run from any host.  If pointing at a non-configSet directory, this
-echo must be run from the host that you wish to create the core on.
-echo.
-echo   -c ^<core^>     Name of core to create
-echo.
-echo   -d confdir  Configuration directory to copy when creating the new core, built-in options are:
-echo.
-echo       _default: Minimal configuration, which supports enabling/disabling field-guessing support
-echo       sample_techproducts_configs: Example configuration with many optional features enabled to
-echo          demonstrate the full power of Solr
-echo.
-echo       If not specified, default is: _default
-echo.
-echo       Alternatively, you can pass the path to your own configuration directory instead of using
-echo       one of the built-in configurations, such as: bin\solr create_core -c mycore -d c:/tmp/myconfig
-echo.
-echo   -p port     Port of a local Solr instance where you want to create the new core
-echo                 If not specified, the script will search the local system for a running
-echo                 Solr instance and will use the port of the first server it finds.
-echo.
-echo   -V            Enable more verbose output.
-echo.
-goto done
-
-:create_collection_usage
-echo.
-echo Usage: solr create_collection [-c collection] [-d confdir] [-n confname] [-shards #] [-replicationFactor #] [-p port] [-V]
-echo.
-echo Can be run from remote (non-Solr^) hosts, as long as a valid SOLR_HOST is provided in solr.in.cmd.
-echo.
-echo   -c ^<collection^>         Name of collection to create
-echo.
-echo   -d ^<confdir^>            Configuration directory to copy when creating the new collection, built-in options are:
-echo.
-echo       _default: Minimal configuration, which supports enabling/disabling field-guessing support
-echo       sample_techproducts_configs: Example configuration with many optional features enabled to
-echo          demonstrate the full power of Solr
-echo.
-echo       If not specified, default is: _default
-echo.
-echo       Alternatively, you can pass the path to your own configuration directory instead of using
-echo       one of the built-in configurations, such as: bin\solr create_collection -c mycoll -d c:/tmp/myconfig
-echo.
-echo       By default the script will upload the specified confdir directory into Zookeeper using the same
-echo         name as the collection (-c) option. Alternatively, if you want to reuse an existing directory
-echo         or create a confdir in Zookeeper that can be shared by multiple collections, use the -n option
-echo.
-echo   -n configName         Name the configuration directory in Zookeeper; by default, the configuration
-echo                             will be uploaded to Zookeeper using the collection name (-c), but if you want
-echo                             to use an existing directory or override the name of the configuration in
-echo                              Zookeeper, then use the -c option.
-echo.
-echo   -shards #             Number of shards to split the collection into; default is 1
-echo.
-echo   -replicationFactor #  Number of copies of each document in the collection, default is 1 (no replication)
-echo.
-echo   -p port               Port of a local Solr instance where you want to create the new collection
-echo                           If not specified, the script will search the local system for a running
-echo                           Solr instance and will use the port of the first server it finds.
-echo.
-echo   -V                    Enable more verbose output.
-echo.
-goto done
-
 :zk_usage
 set ZK_FULL=true
 goto zk_short_usage
@@ -1442,7 +1285,7 @@ IF "%FG%"=="1" (
   "%JAVA%" %SOLR_SSL_OPTS% %AUTHC_OPTS% %SOLR_ZK_CREDS_AND_ACLS% -Dsolr.install.dir="%SOLR_TIP%" -Dsolr.default.confdir="%DEFAULT_CONFDIR%"^
     -Dlog4j.configurationFile="file:///%DEFAULT_SERVER_DIR%\resources\log4j2-console.xml" ^
     -classpath "%DEFAULT_SERVER_DIR%\solr-webapp\webapp\WEB-INF\lib\*;%DEFAULT_SERVER_DIR%\lib\ext\*" ^
-    org.apache.solr.cli.SolrCLI status -maxWaitSecs !SOLR_START_WAIT! -solr !SOLR_URL_SCHEME!://%SOLR_TOOL_HOST%:%SOLR_PORT%/solr
+    org.apache.solr.cli.SolrCLI status -maxWaitSecs !SOLR_START_WAIT! -solrUrl !SOLR_URL_SCHEME!://%SOLR_TOOL_HOST%:%SOLR_PORT%/solr
   IF NOT "!ERRORLEVEL!"=="0" (
       set "SCRIPT_ERROR=Solr did not start or was not reachable. Check the logs for errors."
       goto err
@@ -1477,10 +1320,11 @@ for /f "usebackq" %%i in (`dir /b "%SOLR_TIP%\bin" ^| findstr /i "^solr-.*\.port
           @echo.
           set has_info=1
           echo Found Solr process %%k running on port !SOME_SOLR_PORT!
+          REM Passing in %2 (-h or -help) directly is captured by a custom help path for usage output
           "%JAVA%" %SOLR_SSL_OPTS% %AUTHC_OPTS% %SOLR_ZK_CREDS_AND_ACLS% -Dsolr.install.dir="%SOLR_TIP%" ^
             -Dlog4j.configurationFile="file:///%DEFAULT_SERVER_DIR%\resources\log4j2-console.xml" ^
             -classpath "%DEFAULT_SERVER_DIR%\solr-webapp\webapp\WEB-INF\lib\*;%DEFAULT_SERVER_DIR%\lib\ext\*" ^
-            org.apache.solr.cli.SolrCLI status -solr !SOLR_URL_SCHEME!://%SOLR_TOOL_HOST%:!SOME_SOLR_PORT!/solr
+            org.apache.solr.cli.SolrCLI status -solrUrl !SOLR_URL_SCHEME!://%SOLR_TOOL_HOST%:!SOME_SOLR_PORT!/solr %2
           @echo.
         )
       )
@@ -1491,47 +1335,6 @@ if NOT "!has_info!"=="1" echo No running Solr nodes found.
 set has_info=
 goto done
 
-:parse_healthcheck_args
-IF [%1]==[] goto run_healthcheck
-IF "%1"=="-V" goto set_healthcheck_verbose
-IF "%1"=="-c" goto set_healthcheck_collection
-IF "%1"=="-collection" goto set_healthcheck_collection
-IF "%1"=="-z" goto set_healthcheck_zk
-IF "%1"=="-zkhost" goto set_healthcheck_zk
-IF "%1"=="-zkHost" goto set_healthcheck_zk
-IF "%1"=="-help" goto usage
-IF "%1"=="-usage" goto usage
-IF "%1"=="/?" goto usage
-goto run_healthcheck
-
-:set_healthcheck_verbose
-set HEALTHCHECK_VERBOSE="-verbose"
-SHIFT
-goto parse_healthcheck_args
-
-:set_healthcheck_collection
-set HEALTHCHECK_COLLECTION=%~2
-SHIFT
-SHIFT
-goto parse_healthcheck_args
-
-:set_healthcheck_zk
-set ZK_HOST=%~2
-SHIFT
-SHIFT
-goto parse_healthcheck_args
-
-:run_healthcheck
-IF NOT DEFINED HEALTHCHECK_COLLECTION goto healthcheck_usage
-IF NOT DEFINED HEALTHCHECK_VERBOSE set "HEALTHCHECK_VERBOSE="
-IF NOT DEFINED HEALTHCHECK_ZK_HOST set "HEALTHCHECK_ZK_HOST=localhost:9983"
-echo ZK_HOST: !ZK_HOST!
-"%JAVA%" %SOLR_SSL_OPTS% %AUTHC_OPTS% %SOLR_ZK_CREDS_AND_ACLS% -Dsolr.install.dir="%SOLR_TIP%" ^
-  -Dlog4j.configurationFile="file:///%DEFAULT_SERVER_DIR%\resources\log4j2-console.xml" ^
-  -classpath "%DEFAULT_SERVER_DIR%\solr-webapp\webapp\WEB-INF\lib\*;%DEFAULT_SERVER_DIR%\lib\ext\*" ^
-  org.apache.solr.cli.SolrCLI healthcheck -collection !HEALTHCHECK_COLLECTION! -zkHost !ZK_HOST! %HEALTHCHECK_VERBOSE%
-goto done
-
 :run_solrcli
 "%JAVA%" %SOLR_SSL_OPTS% %AUTHC_OPTS% %SOLR_ZK_CREDS_AND_ACLS% -Dsolr.install.dir="%SOLR_TIP%" ^
   -Dlog4j.configurationFile="file:///%DEFAULT_SERVER_DIR%\resources\log4j2-console.xml" ^
@@ -1565,19 +1368,6 @@ SHIFT
 SHIFT
 goto parse_config_args
 
-:run_config
-IF NOT "!ZK_HOST!"=="" SET "CONFIG_ARGS=!CONFIG_ARGS! -z !ZK_HOST!"
-IF NOT "!SOLR_URL_SCHEME!"=="" SET "CONFIG_ARGS=!CONFIG_ARGS! -scheme !SOLR_URL_SCHEME!"
-
-"%JAVA%" %SOLR_SSL_OPTS% %AUTHC_OPTS% %SOLR_ZK_CREDS_AND_ACLS% -Dsolr.install.dir="%SOLR_TIP%" ^
-  -Dlog4j.configurationFile="file:///%DEFAULT_SERVER_DIR%\resources\log4j2-console.xml" ^
-  -classpath "%DEFAULT_SERVER_DIR%\solr-webapp\webapp\WEB-INF\lib\*;%DEFAULT_SERVER_DIR%\lib\ext\*" ^
-  org.apache.solr.cli.SolrCLI config !CONFIG_ARGS!
-if errorlevel 1 (
-   exit /b 1
-)
-goto done
-
 :get_version
 "%JAVA%" %SOLR_SSL_OPTS% %AUTHC_OPTS% %SOLR_ZK_CREDS_AND_ACLS% -Dsolr.install.dir="%SOLR_TIP%" ^
   -Dlog4j.configurationFile="file:///%DEFAULT_SERVER_DIR%\resources\log4j2-console.xml" ^
@@ -1585,192 +1375,6 @@ goto done
   org.apache.solr.cli.SolrCLI version
 goto done
 
-:parse_create_args
-IF [%1]==[] goto run_create
-IF "%1"=="-V" goto set_create_verbose
-IF "%1"=="-c" goto set_create_name
-IF "%1"=="-core" goto set_create_name
-IF "%1"=="-collection" goto set_create_name
-IF "%1"=="-d" goto set_create_confdir
-IF "%1"=="-confdir" goto set_create_confdir
-IF "%1"=="-n" goto set_create_confname
-IF "%1"=="-confname" goto set_create_confname
-IF "%1"=="-s" goto set_create_shards
-IF "%1"=="-shards" goto set_create_shards
-IF "%1"=="-rf" goto set_create_rf
-IF "%1"=="-replicationFactor" goto set_create_rf
-IF "%1"=="-p" goto set_create_port
-IF "%1"=="-port" goto set_create_port
-IF "%1"=="-help" goto usage
-IF "%1"=="-usage" goto usage
-IF "%1"=="/?" goto usage
-goto run_create
-
-
-:set_create_verbose
-set CREATE_VERBOSE="-verbose"
-SHIFT
-goto parse_create_args
-
-:set_create_name
-set CREATE_NAME=%~2
-SHIFT
-SHIFT
-goto parse_create_args
-
-:set_create_confdir
-set CREATE_CONFDIR=%~2
-SHIFT
-SHIFT
-goto parse_create_args
-
-:set_create_confname
-set CREATE_CONFNAME=%~2
-SHIFT
-SHIFT
-goto parse_create_args
-
-:set_create_port
-set CREATE_PORT=%~2
-SHIFT
-SHIFT
-goto parse_create_args
-
-:set_create_shards
-set CREATE_NUM_SHARDS=%~2
-SHIFT
-SHIFT
-goto parse_create_args
-
-:set_create_rf
-set CREATE_REPFACT=%~2
-SHIFT
-SHIFT
-goto parse_create_args
-
-:run_create
-IF "!CREATE_NAME!"=="" (
-  set "SCRIPT_ERROR=Name (-c) is a required parameter for %SCRIPT_CMD%"
-  goto invalid_cmd_line
-)
-IF NOT DEFINED CREATE_VERBOSE set "CREATE_VERBOSE="
-IF "!CREATE_CONFDIR!"=="" set CREATE_CONFDIR=_default
-IF "!CREATE_NUM_SHARDS!"=="" set CREATE_NUM_SHARDS=1
-IF "!CREATE_REPFACT!"=="" set CREATE_REPFACT=1
-IF "!CREATE_CONFNAME!"=="" set CREATE_CONFNAME=!CREATE_NAME!
-
-REM Find a port that Solr is running on
-if "!CREATE_PORT!"=="" (
-  for /f "usebackq" %%i in (`dir /b "%SOLR_TIP%\bin" ^| findstr /i "^solr-.*\.port$"`) do (
-    set SOME_SOLR_PORT=
-    For /F "Delims=" %%J In ('type "%SOLR_TIP%\bin\%%i"') do set SOME_SOLR_PORT=%%~J
-    if NOT "!SOME_SOLR_PORT!"=="" (
-      for /f "tokens=2,5" %%j in ('netstat -aon ^| find "TCP " ^| find ":0 " ^| find ":!SOME_SOLR_PORT! "') do (
-        IF NOT "%%k"=="0" set CREATE_PORT=!SOME_SOLR_PORT!
-      )
-    )
-  )
-)
-if "!CREATE_PORT!"=="" (
-  set "SCRIPT_ERROR=Could not find a running Solr instance on this host! Please use the -p option to specify the port."
-  goto err
-)
-
-if "!CREATE_CONFDIR!"=="_default" (
-  echo WARNING: Using _default configset with data driven schema functionality. NOT RECOMMENDED for production use.
-  echo          To turn off: bin\solr config -c !CREATE_NAME! -p !CREATE_PORT! -action set-user-property -property update.autoCreateFields -value false
-)
-
-if "%SCRIPT_CMD%"=="create_core" (
-  "%JAVA%" %SOLR_SSL_OPTS% %AUTHC_OPTS% %SOLR_ZK_CREDS_AND_ACLS% -Dsolr.install.dir="%SOLR_TIP%" ^
-    -Dlog4j.configurationFile="file:///%DEFAULT_SERVER_DIR%\resources\log4j2-console.xml" ^
-    -classpath "%DEFAULT_SERVER_DIR%\solr-webapp\webapp\WEB-INF\lib\*;%DEFAULT_SERVER_DIR%\lib\ext\*" ^
-    org.apache.solr.cli.SolrCLI create_core -name !CREATE_NAME! -solrUrl !SOLR_URL_SCHEME!://%SOLR_TOOL_HOST%:!CREATE_PORT!/solr ^
-    -confdir !CREATE_CONFDIR! -configsetsDir "%SOLR_TIP%\server\solr\configsets" %CREATE_VERBOSE%
-) else (
-  "%JAVA%" %SOLR_SSL_OPTS% %AUTHC_OPTS% %SOLR_ZK_CREDS_AND_ACLS% -Dsolr.install.dir="%SOLR_TIP%" -Dsolr.default.confdir="%DEFAULT_CONFDIR%"^
-    -Dlog4j.configurationFile="file:///%DEFAULT_SERVER_DIR%\resources\log4j2-console.xml" ^
-    -classpath "%DEFAULT_SERVER_DIR%\solr-webapp\webapp\WEB-INF\lib\*;%DEFAULT_SERVER_DIR%\lib\ext\*" ^
-    org.apache.solr.cli.SolrCLI create -name !CREATE_NAME! -shards !CREATE_NUM_SHARDS! -replicationFactor !CREATE_REPFACT! ^
-    -confname !CREATE_CONFNAME! -confdir !CREATE_CONFDIR! -configsetsDir "%SOLR_TIP%\server\solr\configsets" ^
-    -solrUrl !SOLR_URL_SCHEME!://%SOLR_TOOL_HOST%:!CREATE_PORT!/solr %CREATE_VERBOSE%
-)
-
-goto done
-
-:parse_delete_args
-IF [%1]==[] goto run_delete
-IF "%1"=="-V" goto set_delete_verbose
-IF "%1"=="-c" goto set_delete_name
-IF "%1"=="-core" goto set_delete_name
-IF "%1"=="-collection" goto set_delete_name
-IF "%1"=="-p" goto set_delete_port
-IF "%1"=="-port" goto set_delete_port
-IF "%1"=="-deleteConfig" goto set_delete_config
-IF "%1"=="-help" goto usage
-IF "%1"=="-usage" goto usage
-IF "%1"=="/?" goto usage
-goto run_delete
-
-:set_delete_verbose
-set DELETE_VERBOSE="-verbose"
-SHIFT
-goto parse_delete_args
-
-:set_delete_name
-set DELETE_NAME=%~2
-SHIFT
-SHIFT
-goto parse_delete_args
-
-:set_delete_port
-set DELETE_PORT=%~2
-SHIFT
-SHIFT
-goto parse_delete_args
-
-:set_delete_config
-set DELETE_CONFIG=%~2
-SHIFT
-SHIFT
-goto parse_delete_args
-
-:run_delete
-IF NOT DEFINED DELETE_VERBOSE set "DELETE_VERBOSE="
-IF "!DELETE_NAME!"=="" (
-  set "SCRIPT_ERROR=Name (-c) is a required parameter for %SCRIPT_CMD%"
-  goto invalid_cmd_line
-)
-
-REM Find a port that Solr is running on
-if "!DELETE_PORT!"=="" (
-  for /f "usebackq" %%i in (`dir /b "%SOLR_TIP%\bin" ^| findstr /i "^solr-.*\.port$"`) do (
-    set SOME_SOLR_PORT=
-    For /F "Delims=" %%J In ('type "%SOLR_TIP%\bin\%%i"') do set SOME_SOLR_PORT=%%~J
-    if NOT "!SOME_SOLR_PORT!"=="" (
-      for /f "tokens=2,5" %%j in ('netstat -aon ^| find "TCP " ^| find ":0 " ^| find ":!SOME_SOLR_PORT! "') do (
-        IF NOT "%%k"=="0" set DELETE_PORT=!SOME_SOLR_PORT!
-      )
-    )
-  )
-)
-if "!DELETE_PORT!"=="" (
-  set "SCRIPT_ERROR=Could not find a running Solr instance on this host! Please use the -p option to specify the port."
-  goto err
-)
-
-if "!DELETE_CONFIG!"=="" (
-  set DELETE_CONFIG=true
-)
-
-"%JAVA%" %SOLR_SSL_OPTS% %AUTHC_OPTS% %SOLR_ZK_CREDS_AND_ACLS% -Dsolr.install.dir="%SOLR_TIP%" ^
--Dlog4j.configurationFile="file:///%DEFAULT_SERVER_DIR%\resources\log4j2-console.xml" ^
--classpath "%DEFAULT_SERVER_DIR%\solr-webapp\webapp\WEB-INF\lib\*;%DEFAULT_SERVER_DIR%\lib\ext\*" ^
-org.apache.solr.cli.SolrCLI delete -name !DELETE_NAME! -deleteConfig !DELETE_CONFIG! ^
--solrUrl !SOLR_URL_SCHEME!://%SOLR_TOOL_HOST%:!DELETE_PORT!/solr %DELETE_VERBOSE%
-
-goto done
-
 REM Clumsy to do the state machine thing for -d and -n, but that's required for back-compat
 :parse_zk_args
 IF "%1"=="-V" (
@@ -2047,19 +1651,19 @@ IF "%FIRST_ARG%"=="start" (
 ) ELSE IF "%FIRST_ARG%"=="stop" (
   goto stop_usage
 ) ELSE IF "%FIRST_ARG%"=="healthcheck" (
-  goto healthcheck_usage
+  goto run_solrcli
 ) ELSE IF "%FIRST_ARG%"=="create" (
-  goto create_usage
+  goto run_solrcli
 ) ELSE IF "%FIRST_ARG%"=="create_core" (
-  goto create_core_usage
+  goto run_solrcli
 ) ELSE IF "%FIRST_ARG%"=="create_collection" (
-  goto create_collection_usage
+  goto run_solrcli
 ) ELSE IF "%FIRST_ARG%"=="zk" (
   goto zk_short_usage
 ) ELSE IF "%FIRST_ARG%"=="auth" (
   goto auth_usage
 ) ELSE IF "%FIRST_ARG%"=="status" (
-  goto status_usage
+  goto run_solrcli
 ) ELSE (
   goto script_usage
 )
diff --git a/solr/core/src/java/org/apache/solr/cli/AssertTool.java b/solr/core/src/java/org/apache/solr/cli/AssertTool.java
index b88dad4d805..94fc3bd9890 100644
--- a/solr/core/src/java/org/apache/solr/cli/AssertTool.java
+++ b/solr/core/src/java/org/apache/solr/cli/AssertTool.java
@@ -26,7 +26,6 @@ import java.nio.file.attribute.FileOwnerAttributeView;
 import java.util.List;
 import java.util.concurrent.TimeUnit;
 import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.HelpFormatter;
 import org.apache.commons.cli.Option;
 import org.apache.solr.client.solrj.SolrClient;
 import org.apache.solr.client.solrj.SolrRequest;
@@ -135,7 +134,7 @@ public class AssertTool extends ToolBase {
   public int runTool(CommandLine cli) throws Exception {
     verbose = cli.hasOption(SolrCLI.OPTION_VERBOSE.getOpt());
 
-    int toolExitStatus = 0;
+    int toolExitStatus;
     try {
       toolExitStatus = runAssert(cli);
     } catch (Exception exc) {
@@ -168,13 +167,6 @@ public class AssertTool extends ToolBase {
    * @throws Exception if a tool failed, e.g. authentication failure
    */
   protected int runAssert(CommandLine cli) throws Exception {
-    if (cli.getOptions().length == 0 || cli.getArgs().length > 0 || cli.hasOption("h")) {
-      new HelpFormatter()
-          .printHelp(
-              "bin/solr assert [-m <message>] [-e] [-rR] [-s <url>] [-S <url>] [-c <url>] [-C <url>] [-u <dir>] [-x <dir>] [-X <dir>]",
-              SolrCLI.getToolOptions(this));
-      return 1;
-    }
     if (cli.hasOption("m")) {
       message = cli.getOptionValue("m");
     }
diff --git a/solr/core/src/java/org/apache/solr/cli/AuthTool.java b/solr/core/src/java/org/apache/solr/cli/AuthTool.java
index f87ed52c6a3..9e9244626c7 100644
--- a/solr/core/src/java/org/apache/solr/cli/AuthTool.java
+++ b/solr/core/src/java/org/apache/solr/cli/AuthTool.java
@@ -133,14 +133,6 @@ public class AuthTool extends ToolBase {
   @Override
   public int runTool(CommandLine cli) throws Exception {
     SolrCLI.raiseLogLevelUnlessVerbose(cli);
-    if (cli.getOptions().length == 0
-        || cli.getArgs().length == 0
-        || cli.getArgs().length > 1
-        || cli.hasOption("h")) {
-      new HelpFormatter()
-          .printHelp("bin/solr auth <enable|disable> [OPTIONS]", SolrCLI.getToolOptions(this));
-      return 1;
-    }
 
     ensureArgumentIsValidBooleanIfPresent(cli, "blockUnknown");
     ensureArgumentIsValidBooleanIfPresent(cli, "updateIncludeFileOnly");
diff --git a/solr/core/src/java/org/apache/solr/cli/ConfigTool.java b/solr/core/src/java/org/apache/solr/cli/ConfigTool.java
index 86ce0d9f4cd..0d58b3fc88b 100644
--- a/solr/core/src/java/org/apache/solr/cli/ConfigTool.java
+++ b/solr/core/src/java/org/apache/solr/cli/ConfigTool.java
@@ -47,65 +47,43 @@ public class ConfigTool extends ToolBase {
 
   @Override
   public List<Option> getOptions() {
-    List<Option> configOptions =
-        List.of(
-            Option.builder("action")
-                .argName("ACTION")
-                .hasArg()
-                .required(false)
-                .desc(
-                    "Config API action, one of: set-property, unset-property; set-user-property, unset-user-property; default is 'set-property'.")
-                .build(),
-            Option.builder("property")
-                .argName("PROP")
-                .hasArg()
-                .required(true)
-                .desc(
-                    "Name of the Config API property to apply the action to, such as: 'updateHandler.autoSoftCommit.maxTime'.")
-                .build(),
-            Option.builder("value")
-                .argName("VALUE")
-                .hasArg()
-                .required(false)
-                .desc("Set the property to this value; accepts JSON objects and strings.")
-                .build(),
-            SolrCLI.OPTION_SOLRURL,
-            SolrCLI.OPTION_ZKHOST,
-            Option.builder("p")
-                .argName("PORT")
-                .hasArg()
-                .required(false)
-                .desc("The port of the Solr node to use when applying configuration change.")
-                .longOpt("port")
-                .build(),
-            Option.builder("s")
-                .argName("SCHEME")
-                .hasArg()
-                .required(false)
-                .desc(
-                    "The scheme for accessing Solr.  Accepted values: http or https.  Default is 'http'")
-                .longOpt("scheme")
-                .build());
-    return SolrCLI.joinOptions(configOptions, SolrCLI.cloudOptions);
+    return List.of(
+        Option.builder("c")
+            .longOpt("name")
+            .argName("NAME")
+            .hasArg()
+            .required(true)
+            .desc("Name of the collection.")
+            .build(),
+        Option.builder("action")
+            .argName("ACTION")
+            .hasArg()
+            .required(false)
+            .desc(
+                "Config API action, one of: set-property, unset-property, set-user-property, unset-user-property; default is 'set-property'.")
+            .build(),
+        Option.builder("property")
+            .argName("PROP")
+            .hasArg()
+            .required(true)
+            .desc(
+                "Name of the Config API property to apply the action to, such as: 'updateHandler.autoSoftCommit.maxTime'.")
+            .build(),
+        Option.builder("value")
+            .argName("VALUE")
+            .hasArg()
+            .required(false)
+            .desc("Set the property to this value; accepts JSON objects and strings.")
+            .build(),
+        SolrCLI.OPTION_SOLRURL,
+        SolrCLI.OPTION_ZKHOST);
   }
 
   @Override
   public void runImpl(CommandLine cli) throws Exception {
-    String solrUrl;
-    try {
-      solrUrl = SolrCLI.resolveSolrUrl(cli);
-    } catch (IllegalStateException e) {
-      // Fallback to using the provided scheme and port
-      final String scheme = cli.getOptionValue("scheme", "http");
-      if (cli.hasOption("port")) {
-        solrUrl = scheme + "://localhost:" + cli.getOptionValue("port", "8983") + "/solr";
-      } else {
-        throw e;
-      }
-    }
-
+    String solrUrl = SolrCLI.resolveSolrUrl(cli);
     String action = cli.getOptionValue("action", "set-property");
-    String collection = cli.getOptionValue("collection");
+    String collection = cli.getOptionValue("name");
     String property = cli.getOptionValue("property");
     String value = cli.getOptionValue("value");
 
diff --git a/solr/core/src/java/org/apache/solr/cli/CreateCollectionTool.java b/solr/core/src/java/org/apache/solr/cli/CreateCollectionTool.java
index 610e94a231a..1a37b5ac058 100644
--- a/solr/core/src/java/org/apache/solr/cli/CreateCollectionTool.java
+++ b/solr/core/src/java/org/apache/solr/cli/CreateCollectionTool.java
@@ -17,8 +17,7 @@
 
 package org.apache.solr.cli;
 
-import static org.apache.solr.common.params.CommonParams.NAME;
-
+import java.io.File;
 import java.io.PrintStream;
 import java.nio.file.Path;
 import java.util.Collections;
@@ -43,6 +42,51 @@ import org.noggit.JSONWriter;
 /** Supports create_collection command in the bin/solr script. */
 public class CreateCollectionTool extends ToolBase {
 
+  public static final List<Option> CREATE_COLLECTION_OPTIONS =
+      List.of(
+          SolrCLI.OPTION_ZKHOST,
+          SolrCLI.OPTION_SOLRURL,
+          Option.builder("c")
+              .longOpt("name")
+              .argName("NAME")
+              .hasArg()
+              .required(true)
+              .desc("Name of collection to create.")
+              .build(),
+          Option.builder("s")
+              .longOpt("shards")
+              .argName("#")
+              .hasArg()
+              .required(false)
+              .desc("Number of shards; default is 1.")
+              .build(),
+          Option.builder("rf")
+              .longOpt("replicationFactor")
+              .argName("#")
+              .hasArg()
+              .required(false)
+              .desc(
+                  "Number of copies of each document across the collection (replicas per shard); default is 1.")
+              .build(),
+          Option.builder("d")
+              .longOpt("confdir")
+              .argName("NAME")
+              .hasArg()
+              .required(false)
+              .desc(
+                  "Configuration directory to copy when creating the new collection; default is "
+                      + SolrCLI.DEFAULT_CONFIG_SET
+                      + '.')
+              .build(),
+          Option.builder("n")
+              .longOpt("confname")
+              .argName("NAME")
+              .hasArg()
+              .required(false)
+              .desc("Configuration name; default is the collection name.")
+              .build(),
+          SolrCLI.OPTION_VERBOSE);
+
   public CreateCollectionTool() {
     this(CLIO.getOutStream());
   }
@@ -58,7 +102,7 @@ public class CreateCollectionTool extends ToolBase {
 
   @Override
   public List<Option> getOptions() {
-    return SolrCLI.CREATE_COLLECTION_OPTIONS;
+    return CREATE_COLLECTION_OPTIONS;
   }
 
   @Override
@@ -67,9 +111,7 @@ public class CreateCollectionTool extends ToolBase {
     String zkHost = SolrCLI.getZkHost(cli);
     if (zkHost == null) {
       throw new IllegalStateException(
-          "Solr at "
-              + cli.getOptionValue("solrUrl")
-              + " is running in standalone server mode, please use the create_core command instead;\n"
+          "Solr at is running in standalone server mode, please use the create_core command instead;\n"
               + "create_collection can only be used when running in SolrCloud mode.\n");
     }
 
@@ -84,6 +126,13 @@ public class CreateCollectionTool extends ToolBase {
 
   protected void runCloudTool(CloudSolrClient cloudSolrClient, CommandLine cli) throws Exception {
 
+    String collectionName = cli.getOptionValue("name");
+    final String solrInstallDir = System.getProperty("solr.install.dir");
+    String confName = cli.getOptionValue("confname");
+    String confDir = cli.getOptionValue("confdir", "_default");
+    ensureConfDirExists(confDir, solrInstallDir);
+    printDefaultConfigsetWarningIfNecessary(cli);
+
     Set<String> liveNodes = cloudSolrClient.getClusterState().getLiveNodes();
     if (liveNodes.isEmpty())
       throw new IllegalStateException(
@@ -96,46 +145,42 @@ public class CreateCollectionTool extends ToolBase {
       solrUrl = ZkStateReader.from(cloudSolrClient).getBaseUrlForNodeName(firstLiveNode);
     }
 
-    String collectionName = cli.getOptionValue(NAME);
-
     // build a URL to create the collection
     int numShards = Integer.parseInt(cli.getOptionValue("shards", String.valueOf(1)));
     int replicationFactor =
         Integer.parseInt(cli.getOptionValue("replicationFactor", String.valueOf(1)));
 
-    String confname = cli.getOptionValue("confname");
-    String confdir = cli.getOptionValue("confdir");
-    String configsetsDir = cli.getOptionValue("configsetsDir");
+    final String configsetsDir = solrInstallDir + "/server/solr/configsets";
 
     boolean configExistsInZk =
-        confname != null
-            && !confname.trim().isEmpty()
+        confName != null
+            && !confName.trim().isEmpty()
             && ZkStateReader.from(cloudSolrClient)
                 .getZkClient()
-                .exists("/configs/" + confname, true);
+                .exists("/configs/" + confName, true);
 
     if (CollectionAdminParams.SYSTEM_COLL.equals(collectionName)) {
       // do nothing
     } else if (configExistsInZk) {
-      echo("Re-using existing configuration directory " + confname);
-    } else if (confdir != null && !confdir.trim().isEmpty()) {
-      if (confname == null || confname.trim().isEmpty()) {
-        confname = collectionName;
+      echo("Re-using existing configuration directory " + confName);
+    } else { // if (confdir != null && !confdir.trim().isEmpty()) {
+      if (confName == null || confName.trim().isEmpty()) {
+        confName = collectionName;
       }
-      Path confPath = ConfigSetService.getConfigsetPath(confdir, configsetsDir);
+      Path confPath = ConfigSetService.getConfigsetPath(confDir, configsetsDir);
 
       echoIfVerbose(
           "Uploading "
               + confPath.toAbsolutePath()
               + " for config "
-              + confname
+              + confName
               + " to ZooKeeper at "
               + cloudSolrClient.getClusterStateProvider().getQuorumHosts(),
           cli);
       ZkMaintenanceUtils.uploadToZK(
           ZkStateReader.from(cloudSolrClient).getZkClient(),
           confPath,
-          ZkMaintenanceUtils.CONFIGS_ZKNODE + "/" + confname,
+          ZkMaintenanceUtils.CONFIGS_ZKNODE + "/" + confName,
           ZkMaintenanceUtils.UPLOAD_FILENAME_EXCLUDE_PATTERN);
     }
 
@@ -156,7 +201,7 @@ public class CreateCollectionTool extends ToolBase {
       response =
           cloudSolrClient.request(
               CollectionAdminRequest.createCollection(
-                  collectionName, confname, numShards, replicationFactor));
+                  collectionName, confName, numShards, replicationFactor));
     } catch (SolrServerException sse) {
       throw new Exception(
           "Failed to create collection '" + collectionName + "' due to: " + sse.getMessage());
@@ -174,11 +219,56 @@ public class CreateCollectionTool extends ToolBase {
               collectionName,
               numShards,
               replicationFactor);
-      if (confname != null && !confname.trim().isEmpty()) {
-        endMessage += String.format(Locale.ROOT, " with config-set '%s'", confname);
+      if (confName != null && !confName.trim().isEmpty()) {
+        endMessage += String.format(Locale.ROOT, " with config-set '%s'", confName);
       }
 
       echo(endMessage);
     }
   }
+
+  /**
+   * Ensure the confDirName is a path to a directory by itself or when it is combined with the
+   * solrInstallDir.
+   */
+  private void ensureConfDirExists(String confDirName, String solrInstallDir) {
+    if (!new File(confDirName).isDirectory()) {
+      final String fullConfDir = solrInstallDir + "/server/solr/configsets/" + confDirName;
+      if (!new File(fullConfDir).isDirectory()) {
+        echo("Specified configuration directory " + confDirName + " not found!");
+        System.exit(1);
+      }
+    }
+  }
+
+  private void printDefaultConfigsetWarningIfNecessary(CommandLine cli) {
+    final String confDirectoryName = cli.getOptionValue("confdir", "_default"); // CREATE_CONFDIR
+    final String confName = cli.getOptionValue("confname", "");
+
+    if (confDirectoryName.equals("_default")
+        && (confName.equals("") || confName.equals("_default"))) {
+      final String collectionName = cli.getOptionValue("name");
+      final String solrUrl = cli.getOptionValue("solrUrl");
+      final String curlCommand =
+          String.format(
+              Locale.ROOT,
+              "curl %s/%s/config -d "
+                  + "'{\"set-user-property\": {\"update.autoCreateFields\":\"false\"}}'",
+              solrUrl,
+              collectionName);
+      final String configCommand =
+          String.format(
+              Locale.ROOT,
+              "bin/solr config -c %s -p 8983 -action set-user-property -property update.autoCreateFields -value false",
+              collectionName);
+      echo(
+          "WARNING: Using _default configset. Data driven schema functionality is enabled by default, which is");
+      echo("         NOT RECOMMENDED for production use.");
+      echo("");
+      echo("         To turn it off:");
+      echo("            " + curlCommand);
+      echo("         Or:");
+      echo("            " + configCommand);
+    }
+  }
 }
diff --git a/solr/core/src/java/org/apache/solr/cli/CreateCoreTool.java b/solr/core/src/java/org/apache/solr/cli/CreateCoreTool.java
index 0efcb5bfb7e..6c396346b95 100644
--- a/solr/core/src/java/org/apache/solr/cli/CreateCoreTool.java
+++ b/solr/core/src/java/org/apache/solr/cli/CreateCoreTool.java
@@ -16,10 +16,7 @@
  */
 package org.apache.solr.cli;
 
-import static org.apache.solr.common.params.CommonParams.NAME;
-
 import java.io.File;
-import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.PrintStream;
 import java.util.List;
@@ -54,14 +51,16 @@ public class CreateCoreTool extends ToolBase {
   public List<Option> getOptions() {
     return List.of(
         SolrCLI.OPTION_SOLRURL,
-        Option.builder(NAME)
+        Option.builder("c")
+            .longOpt("name")
             .argName("NAME")
             .hasArg()
             .required(true)
             .desc("Name of the core to create.")
             .build(),
-        Option.builder("confdir")
-            .argName("CONFIG")
+        Option.builder("d")
+            .longOpt("confdir")
+            .argName("NAME")
             .hasArg()
             .required(false)
             .desc(
@@ -69,41 +68,30 @@ public class CreateCoreTool extends ToolBase {
                     + SolrCLI.DEFAULT_CONFIG_SET
                     + '.')
             .build(),
-        Option.builder("configsetsDir")
-            .argName("DIR")
-            .hasArg()
-            .required(true)
-            .desc("Path to configsets directory on the local system.")
-            .build(),
+        // Option.builder("configsetsDir")
+        //    .argName("DIR")
+        //     .hasArg()
+        //    .required(true)
+        //    .desc("Path to configsets directory on the local system.")
+        //    .build(),
         SolrCLI.OPTION_VERBOSE);
   }
 
   @Override
   public void runImpl(CommandLine cli) throws Exception {
+    String coreName = cli.getOptionValue("name");
     String solrUrl = cli.getOptionValue("solrUrl", SolrCLI.DEFAULT_SOLR_URL);
-    if (!solrUrl.endsWith("/")) solrUrl += "/";
-
-    File configsetsDir = new File(cli.getOptionValue("configsetsDir"));
-    if (!configsetsDir.isDirectory())
-      throw new FileNotFoundException(configsetsDir.getAbsolutePath() + " not found!");
-
-    String configSet = cli.getOptionValue("confdir", SolrCLI.DEFAULT_CONFIG_SET);
-    File configSetDir = new File(configsetsDir, configSet);
-    if (!configSetDir.isDirectory()) {
-      // we allow them to pass a directory instead of a configset name
-      File possibleConfigDir = new File(configSet);
-      if (possibleConfigDir.isDirectory()) {
-        configSetDir = possibleConfigDir;
-      } else {
-        throw new FileNotFoundException(
-            "Specified config directory "
-                + configSet
-                + " not found in "
-                + configsetsDir.getAbsolutePath());
-      }
-    }
 
-    String coreName = cli.getOptionValue(NAME);
+    final String solrInstallDir = System.getProperty("solr.install.dir");
+    final String confDirName =
+        cli.getOptionValue("confdir", SolrCLI.DEFAULT_CONFIG_SET); // CREATE_CONFDIR
+
+    // we allow them to pass a directory instead of a configset name
+    File configsetDir = new File(confDirName);
+    if (!configsetDir.isDirectory()) {
+      ensureConfDirExists(confDirName, solrInstallDir);
+    }
+    printDefaultConfigsetWarningIfNecessary(cli);
 
     String coreRootDirectory; // usually same as solr home, but not always
     try (var solrClient = SolrCLI.getSolrClient(solrUrl)) {
@@ -121,12 +109,6 @@ public class CreateCoreTool extends ToolBase {
 
       // convert raw JSON into user-friendly output
       coreRootDirectory = (String) systemInfo.get("core_root");
-
-      // Fall back to solr_home, in case we are running against older server that does not return
-      // the property
-      if (coreRootDirectory == null) coreRootDirectory = (String) systemInfo.get("solr_home");
-      if (coreRootDirectory == null)
-        coreRootDirectory = configsetsDir.getParentFile().getAbsolutePath();
     }
 
     if (SolrCLI.safeCheckCoreExists(solrUrl, coreName)) {
@@ -137,27 +119,16 @@ public class CreateCoreTool extends ToolBase {
     }
 
     File coreInstanceDir = new File(coreRootDirectory, coreName);
-    File confDir = new File(configSetDir, "conf");
+    File confDir = new File(getFullConfDir(confDirName, solrInstallDir), "conf");
     if (!coreInstanceDir.isDirectory()) {
       coreInstanceDir.mkdirs();
-      if (!coreInstanceDir.isDirectory())
+      if (!coreInstanceDir.isDirectory()) {
         throw new IOException(
             "Failed to create new core instance directory: " + coreInstanceDir.getAbsolutePath());
-
-      if (confDir.isDirectory()) {
-        FileUtils.copyDirectoryToDirectory(confDir, coreInstanceDir);
-      } else {
-        // hmmm ... the configset we're cloning doesn't have a conf sub-directory,
-        // we'll just assume it is OK if it has solrconfig.xml
-        if ((new File(configSetDir, "solrconfig.xml")).isFile()) {
-          FileUtils.copyDirectory(configSetDir, new File(coreInstanceDir, "conf"));
-        } else {
-          throw new IllegalArgumentException(
-              "\n"
-                  + configSetDir.getAbsolutePath()
-                  + " doesn't contain a conf subdirectory or solrconfig.xml\n");
-        }
       }
+
+      FileUtils.copyDirectoryToDirectory(confDir, coreInstanceDir);
+
       echoIfVerbose(
           "\nCopying configuration to new core instance directory:\n"
               + coreInstanceDir.getAbsolutePath(),
@@ -180,4 +151,49 @@ public class CreateCoreTool extends ToolBase {
       throw e;
     }
   }
-} // end CreateCoreTool class
+
+  private String getFullConfDir(String confDirName, String solrInstallDir) {
+    return solrInstallDir + "/server/solr/configsets/" + confDirName;
+  }
+
+  private String ensureConfDirExists(String confDirName, String solrInstallDir) {
+    String fullConfDir = getFullConfDir(confDirName, solrInstallDir);
+    if (!new File(fullConfDir).isDirectory()) {
+      echo("Specified configuration directory " + confDirName + " not found!");
+      System.exit(1);
+    }
+
+    return fullConfDir;
+  }
+
+  private void printDefaultConfigsetWarningIfNecessary(CommandLine cli) {
+    final String confDirectoryName = cli.getOptionValue("confdir", "_default"); // CREATE_CONFDIR
+    final String confName = cli.getOptionValue("confname", "");
+
+    if (confDirectoryName.equals("_default")
+        && (confName.equals("") || confName.equals("_default"))) {
+      final String collectionName = cli.getOptionValue("collection");
+      final String solrUrl = cli.getOptionValue("solrUrl", SolrCLI.DEFAULT_SOLR_URL);
+      final String curlCommand =
+          String.format(
+              Locale.ROOT,
+              "curl %s/%s/config -d "
+                  + "'{\"set-user-property\": {\"update.autoCreateFields\":\"false\"}}'",
+              solrUrl,
+              collectionName);
+      final String configCommand =
+          String.format(
+              Locale.ROOT,
+              "bin/solr config -c %s -p 8983 -action set-user-property -property update.autoCreateFields -value false",
+              collectionName);
+      echo(
+          "WARNING: Using _default configset. Data driven schema functionality is enabled by default, which is");
+      echo("         NOT RECOMMENDED for production use.");
+      echo("");
+      echo("         To turn it off:");
+      echo("            " + curlCommand);
+      echo("         Or:");
+      echo("            " + configCommand);
+    }
+  }
+}
diff --git a/solr/core/src/java/org/apache/solr/cli/CreateTool.java b/solr/core/src/java/org/apache/solr/cli/CreateTool.java
index e3933928607..fff9379c9a4 100644
--- a/solr/core/src/java/org/apache/solr/cli/CreateTool.java
+++ b/solr/core/src/java/org/apache/solr/cli/CreateTool.java
@@ -43,14 +43,13 @@ public class CreateTool extends ToolBase {
 
   @Override
   public List<Option> getOptions() {
-    return SolrCLI.CREATE_COLLECTION_OPTIONS;
+    return CreateCollectionTool.CREATE_COLLECTION_OPTIONS;
   }
 
   @Override
   public void runImpl(CommandLine cli) throws Exception {
     SolrCLI.raiseLogLevelUnlessVerbose(cli);
     String solrUrl = cli.getOptionValue("solrUrl", SolrCLI.DEFAULT_SOLR_URL);
-    if (!solrUrl.endsWith("/")) solrUrl += "/";
 
     ToolBase tool;
     try (var solrClient = SolrCLI.getSolrClient(solrUrl)) {
@@ -64,4 +63,4 @@ public class CreateTool extends ToolBase {
       tool.runImpl(cli);
     }
   }
-} // end CreateTool class
+}
diff --git a/solr/core/src/java/org/apache/solr/cli/DeleteTool.java b/solr/core/src/java/org/apache/solr/cli/DeleteTool.java
index d4d3d2e1943..7948d05b071 100644
--- a/solr/core/src/java/org/apache/solr/cli/DeleteTool.java
+++ b/solr/core/src/java/org/apache/solr/cli/DeleteTool.java
@@ -65,7 +65,8 @@ public class DeleteTool extends ToolBase {
   public List<Option> getOptions() {
     return List.of(
         SolrCLI.OPTION_SOLRURL,
-        Option.builder(NAME)
+        Option.builder("c")
+            .longOpt("name")
             .argName("NAME")
             .hasArg()
             .required(true)
@@ -91,7 +92,6 @@ public class DeleteTool extends ToolBase {
   public void runImpl(CommandLine cli) throws Exception {
     SolrCLI.raiseLogLevelUnlessVerbose(cli);
     String solrUrl = cli.getOptionValue("solrUrl", SolrCLI.DEFAULT_SOLR_URL);
-    if (!solrUrl.endsWith("/")) solrUrl += "/";
 
     try (var solrClient = SolrCLI.getSolrClient(solrUrl)) {
       Map<String, Object> systemInfo =
diff --git a/solr/core/src/java/org/apache/solr/cli/HealthcheckTool.java b/solr/core/src/java/org/apache/solr/cli/HealthcheckTool.java
index 8d181b9a196..44e4ea757b2 100644
--- a/solr/core/src/java/org/apache/solr/cli/HealthcheckTool.java
+++ b/solr/core/src/java/org/apache/solr/cli/HealthcheckTool.java
@@ -60,11 +60,11 @@ public class HealthcheckTool extends ToolBase {
         SolrCLI.OPTION_SOLRURL,
         SolrCLI.OPTION_ZKHOST,
         Option.builder("c")
-            .argName("COLLECTION")
+            .longOpt("name")
+            .argName("NAME")
             .hasArg()
             .required(false)
-            .desc("Name of collection; no default.")
-            .longOpt("collection")
+            .desc("Name of the collection to check.")
             .build());
   }
 
@@ -104,7 +104,7 @@ public class HealthcheckTool extends ToolBase {
 
   protected void runCloudTool(CloudSolrClient cloudSolrClient, CommandLine cli) throws Exception {
     SolrCLI.raiseLogLevelUnlessVerbose(cli);
-    String collection = cli.getOptionValue("collection");
+    String collection = cli.getOptionValue("name");
     if (collection == null) {
       throw new IllegalArgumentException("Must provide a collection to run a healthcheck against!");
     }
diff --git a/solr/core/src/java/org/apache/solr/cli/SolrCLI.java b/solr/core/src/java/org/apache/solr/cli/SolrCLI.java
index 7ab38b078b0..518bfb93039 100755
--- a/solr/core/src/java/org/apache/solr/cli/SolrCLI.java
+++ b/solr/core/src/java/org/apache/solr/cli/SolrCLI.java
@@ -19,6 +19,8 @@ package org.apache.solr.cli;
 import static org.apache.solr.common.SolrException.ErrorCode.FORBIDDEN;
 import static org.apache.solr.common.SolrException.ErrorCode.UNAUTHORIZED;
 import static org.apache.solr.common.params.CommonParams.NAME;
+import static org.apache.solr.packagemanager.PackageUtils.print;
+import static org.apache.solr.packagemanager.PackageUtils.printGreen;
 
 import com.google.common.annotations.VisibleForTesting;
 import java.io.File;
@@ -37,12 +39,10 @@ import java.util.Optional;
 import java.util.Set;
 import java.util.TreeSet;
 import java.util.concurrent.TimeUnit;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipInputStream;
 import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.GnuParser;
+import org.apache.commons.cli.DefaultParser;
 import org.apache.commons.cli.HelpFormatter;
 import org.apache.commons.cli.Option;
 import org.apache.commons.cli.Options;
@@ -79,10 +79,13 @@ public class SolrCLI implements CLIO {
 
   public static final Option OPTION_ZKHOST =
       Option.builder("z")
+          .longOpt("zkHost")
           .argName("HOST")
           .hasArg()
           .required(false)
-          .desc("Address of the ZooKeeper ensemble; defaults to: " + ZK_HOST)
+          .desc(
+              "Zookeeper connection string; unnecessary if ZK_HOST is defined in solr.in.sh; otherwise, defaults to "
+                  + ZK_HOST)
           .longOpt("zkHost")
           .build();
   public static final Option OPTION_SOLRURL =
@@ -97,27 +100,16 @@ public class SolrCLI implements CLIO {
   public static final Option OPTION_VERBOSE =
       Option.builder("verbose").required(false).desc("Enable more verbose command output.").build();
 
+  // should this be boolean or just a otption?
   public static final Option OPTION_RECURSE =
-      Option.builder("recurse")
+      Option.builder("r")
+          .longOpt("recurse")
           .argName("recurse")
           .hasArg()
           .required(false)
           .desc("Recurse (true|false), default is false.")
-          // .type(Boolean.class)
           .build();
 
-  public static final List<Option> cloudOptions =
-      List.of(
-          OPTION_ZKHOST,
-          Option.builder("c")
-              .argName("COLLECTION")
-              .hasArg()
-              .required(false)
-              .desc("Name of collection")
-              .longOpt("collection")
-              .build(),
-          OPTION_VERBOSE);
-
   public static void exit(int exitStatus) {
     try {
       System.exit(exitStatus);
@@ -130,10 +122,7 @@ public class SolrCLI implements CLIO {
   /** Runs a tool. */
   public static void main(String[] args) throws Exception {
     if (args == null || args.length == 0 || args[0] == null || args[0].trim().length() == 0) {
-      CLIO.err(
-          "Invalid command-line args! Must pass the name of a tool to run.\n"
-              + "Supported tools:\n");
-      displayToolOptions();
+      printHelp();
       exit(1);
     }
 
@@ -142,7 +131,7 @@ public class SolrCLI implements CLIO {
       if (args.length != 1) {
         CLIO.err("Version tool does not accept any parameters!");
       }
-      CLIO.out("Solr version is: " + SolrVersion.LATEST.toString());
+      CLIO.out("Solr version is: " + SolrVersion.LATEST);
       exit(0);
     }
 
@@ -257,33 +246,6 @@ public class SolrCLI implements CLIO {
     throw new IllegalArgumentException(toolType + " is not a valid command!");
   }
 
-  private static void displayToolOptions() throws Exception {
-    HelpFormatter formatter = new HelpFormatter();
-    formatter.printHelp("healthcheck", getToolOptions(new HealthcheckTool()));
-    formatter.printHelp("status", getToolOptions(new StatusTool()));
-    formatter.printHelp("api", getToolOptions(new ApiTool()));
-    formatter.printHelp("create_collection", getToolOptions(new CreateCollectionTool()));
-    formatter.printHelp("create_core", getToolOptions(new CreateCoreTool()));
-    formatter.printHelp("create", getToolOptions(new CreateTool()));
-    formatter.printHelp("delete", getToolOptions(new DeleteTool()));
-    formatter.printHelp("config", getToolOptions(new ConfigTool()));
-    formatter.printHelp("run_example", getToolOptions(new RunExampleTool()));
-    formatter.printHelp("upconfig", getToolOptions(new ConfigSetUploadTool()));
-    formatter.printHelp("downconfig", getToolOptions(new ConfigSetDownloadTool()));
-    formatter.printHelp("rm", getToolOptions(new ZkRmTool()));
-    formatter.printHelp("cp", getToolOptions(new ZkCpTool()));
-    formatter.printHelp("mv", getToolOptions(new ZkMvTool()));
-    formatter.printHelp("ls", getToolOptions(new ZkLsTool()));
-    formatter.printHelp("export", getToolOptions(new ExportTool()));
-    formatter.printHelp("package", getToolOptions(new PackageTool()));
-
-    List<Class<? extends Tool>> toolClasses = findToolClassesInPackage("org.apache.solr.util");
-    for (Class<? extends Tool> next : toolClasses) {
-      Tool tool = next.getConstructor().newInstance();
-      formatter.printHelp(tool.getName(), getToolOptions(tool));
-    }
-  }
-
   public static Options getToolOptions(Tool tool) {
     Options options = new Options();
     options.addOption("help", false, "Print this message");
@@ -295,18 +257,6 @@ public class SolrCLI implements CLIO {
     return options;
   }
 
-  public static List<Option> joinOptions(List<Option> lhs, List<Option> rhs) {
-    if (lhs == null) {
-      return rhs == null ? List.of() : rhs;
-    }
-
-    if (rhs == null) {
-      return lhs;
-    }
-
-    return Stream.concat(lhs.stream(), rhs.stream()).collect(Collectors.toUnmodifiableList());
-  }
-
   /** Parses the command-line arguments passed by the user. */
   public static CommandLine processCommandLineArgs(
       String toolName, List<Option> customOptions, String[] args) {
@@ -323,7 +273,7 @@ public class SolrCLI implements CLIO {
 
     CommandLine cli = null;
     try {
-      cli = (new GnuParser()).parse(options, args);
+      cli = (new DefaultParser()).parse(options, args);
     } catch (ParseException exp) {
       boolean hasHelpArg = false;
       if (args != null) {
@@ -466,52 +416,28 @@ public class SolrCLI implements CLIO {
         numSeconds);
   }
 
-  public static final List<Option> CREATE_COLLECTION_OPTIONS =
-      List.of(
-          OPTION_ZKHOST,
-          OPTION_SOLRURL,
-          Option.builder(NAME)
-              .argName("NAME")
-              .hasArg()
-              .required(true)
-              .desc("Name of collection to create.")
-              .build(),
-          Option.builder("shards")
-              .argName("#")
-              .hasArg()
-              .required(false)
-              .desc("Number of shards; default is 1.")
-              .build(),
-          Option.builder("replicationFactor")
-              .argName("#")
-              .hasArg()
-              .required(false)
-              .desc(
-                  "Number of copies of each document across the collection (replicas per shard); default is 1.")
-              .build(),
-          Option.builder("confdir")
-              .argName("NAME")
-              .hasArg()
-              .required(false)
-              .desc(
-                  "Configuration directory to copy when creating the new collection; default is "
-                      + DEFAULT_CONFIG_SET
-                      + '.')
-              .build(),
-          Option.builder("confname")
-              .argName("NAME")
-              .hasArg()
-              .required(false)
-              .desc("Configuration name; default is the collection name.")
-              .build(),
-          Option.builder("configsetsDir")
-              .argName("DIR")
-              .hasArg()
-              .required(true)
-              .desc("Path to configsets directory on the local system.")
-              .build(),
-          OPTION_VERBOSE);
-
+  private static void printHelp() {
+
+    print("Usage: solr COMMAND OPTIONS");
+    print(
+        "       where COMMAND is one of: start, stop, restart, status, healthcheck, create, create_core, create_collection, delete, version, zk, auth, assert, config, export, api, package");
+    print("");
+    print("  Standalone server example (start Solr running in the background on port 8984):");
+    print("");
+    printGreen("    ./solr start -p 8984");
+    print("");
+    print(
+        "  SolrCloud example (start Solr running in SolrCloud mode using localhost:2181 to connect to Zookeeper, with 1g max heap size and remote Java debug options enabled):");
+    print("");
+    printGreen(
+        "    ./solr start -c -m 1g -z localhost:2181 -a \"-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=1044\"");
+    print("");
+    print(
+        "  Omit '-z localhost:2181' from the above command if you have defined ZK_HOST in solr.in.sh.");
+    print("");
+    print("Pass -help or -h after any COMMAND to see command-specific usage information,");
+    print("such as:    ./solr start -help or ./solr stop -h");
+  }
   /**
    * Get the base URL of a live Solr instance from either the solrUrl command-line option from
    * ZooKeeper.
@@ -520,21 +446,27 @@ public class SolrCLI implements CLIO {
     String solrUrl = cli.getOptionValue("solrUrl");
     if (solrUrl == null) {
       String zkHost = cli.getOptionValue("zkHost");
-      if (zkHost == null)
-        throw new IllegalStateException(
-            "Must provide either the '-solrUrl' or '-zkHost' parameters!");
-
-      try (CloudSolrClient cloudSolrClient =
-          new CloudHttp2SolrClient.Builder(Collections.singletonList(zkHost), Optional.empty())
-              .build()) {
-        cloudSolrClient.connect();
-        Set<String> liveNodes = cloudSolrClient.getClusterState().getLiveNodes();
-        if (liveNodes.isEmpty())
-          throw new IllegalStateException(
-              "No live nodes found! Cannot determine 'solrUrl' from ZooKeeper: " + zkHost);
-
-        String firstLiveNode = liveNodes.iterator().next();
-        solrUrl = ZkStateReader.from(cloudSolrClient).getBaseUrlForNodeName(firstLiveNode);
+      if (zkHost == null) {
+        solrUrl = DEFAULT_SOLR_URL;
+        CLIO.getOutStream()
+            .println(
+                "Neither -zkHost or -solrUrl parameters provided so assuming solrUrl is "
+                    + DEFAULT_SOLR_URL
+                    + ".");
+      } else {
+
+        try (CloudSolrClient cloudSolrClient =
+            new CloudHttp2SolrClient.Builder(Collections.singletonList(zkHost), Optional.empty())
+                .build()) {
+          cloudSolrClient.connect();
+          Set<String> liveNodes = cloudSolrClient.getClusterState().getLiveNodes();
+          if (liveNodes.isEmpty())
+            throw new IllegalStateException(
+                "No live nodes found! Cannot determine 'solrUrl' from ZooKeeper: " + zkHost);
+
+          String firstLiveNode = liveNodes.iterator().next();
+          solrUrl = ZkStateReader.from(cloudSolrClient).getBaseUrlForNodeName(firstLiveNode);
+        }
       }
     }
     return solrUrl;
@@ -546,15 +478,20 @@ public class SolrCLI implements CLIO {
    */
   public static String getZkHost(CommandLine cli) throws Exception {
     String zkHost = cli.getOptionValue("zkHost");
-    if (zkHost != null) return zkHost;
+    if (zkHost != null && !zkHost.isBlank()) {
+      return zkHost;
+    }
 
     // find it using the localPort
     String solrUrl = cli.getOptionValue("solrUrl");
-    if (solrUrl == null)
-      throw new IllegalStateException(
-          "Must provide either the -zkHost or -solrUrl parameters to use the create_collection command!");
-
-    if (!solrUrl.endsWith("/")) solrUrl += "/";
+    if (solrUrl == null) {
+      solrUrl = DEFAULT_SOLR_URL;
+      CLIO.getOutStream()
+          .println(
+              "Neither -zkHost or -solrUrl parameters provided so assuming solrUrl is "
+                  + DEFAULT_SOLR_URL
+                  + ".");
+    }
 
     try (var solrClient = getSolrClient(solrUrl)) {
       // hit Solr to get system info
diff --git a/solr/core/src/java/org/apache/solr/cli/StatusTool.java b/solr/core/src/java/org/apache/solr/cli/StatusTool.java
index 9d771e38132..b933fe43f98 100644
--- a/solr/core/src/java/org/apache/solr/cli/StatusTool.java
+++ b/solr/core/src/java/org/apache/solr/cli/StatusTool.java
@@ -26,7 +26,9 @@ import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
 import javax.net.ssl.SSLPeerUnverifiedException;
 import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.HelpFormatter;
 import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
 import org.apache.solr.client.solrj.SolrClient;
 import org.apache.solr.client.solrj.SolrRequest;
 import org.apache.solr.client.solrj.request.CollectionAdminRequest;
@@ -56,14 +58,13 @@ public class StatusTool extends ToolBase {
   @Override
   public List<Option> getOptions() {
     return List.of(
-        Option.builder("solr")
+        // Unlike most of the other tools, this is an internal, not end user
+        // focused setting.  Therefore, no default value is provided.
+        Option.builder("solrUrl")
             .argName("URL")
             .hasArg()
             .required(false)
-            .desc(
-                "Address of the Solr Web application, defaults to: "
-                    + SolrCLI.DEFAULT_SOLR_URL
-                    + '.')
+            .desc("Property set by calling scripts, not meant for user configuration.")
             .build(),
         Option.builder("maxWaitSecs")
             .argName("SECS")
@@ -75,8 +76,19 @@ public class StatusTool extends ToolBase {
 
   @Override
   public void runImpl(CommandLine cli) throws Exception {
+    // Override the default help behaviour to put out a customized message that omits the internally
+    // focused Options.
+    if ((cli.getOptions().length == 0 && cli.getArgs().length == 0)
+        || cli.hasOption("h")
+        || cli.hasOption("help")) {
+      final Options options = new Options();
+      getOptions().forEach(options::addOption);
+      new HelpFormatter().printHelp("status", options);
+      return;
+    }
+
     int maxWaitSecs = Integer.parseInt(cli.getOptionValue("maxWaitSecs", "0"));
-    String solrUrl = cli.getOptionValue("solr", SolrCLI.DEFAULT_SOLR_URL);
+    String solrUrl = cli.getOptionValue("solrUrl");
     if (maxWaitSecs > 0) {
       int solrPort = (new URL(solrUrl)).getPort();
       echo("Waiting up to " + maxWaitSecs + " seconds to see Solr running on port " + solrPort);
@@ -137,8 +149,6 @@ public class StatusTool extends ToolBase {
   public Map<String, Object> getStatus(String solrUrl) throws Exception {
     Map<String, Object> status;
 
-    if (!solrUrl.endsWith("/")) solrUrl += "/";
-
     try (var solrClient = SolrCLI.getSolrClient(solrUrl)) {
       NamedList<Object> systemInfo =
           solrClient.request(
diff --git a/solr/core/src/test/org/apache/solr/cli/HealthcheckToolTest.java b/solr/core/src/test/org/apache/solr/cli/HealthcheckToolTest.java
index 3826523db79..fd9a4a0c230 100644
--- a/solr/core/src/test/org/apache/solr/cli/HealthcheckToolTest.java
+++ b/solr/core/src/test/org/apache/solr/cli/HealthcheckToolTest.java
@@ -48,7 +48,7 @@ public class HealthcheckToolTest extends SolrCloudTestCase {
 
     String[] args =
         new String[] {
-          "healthcheck", "-collection", "bob", "-zkHost", cluster.getZkClient().getZkServerAddress()
+          "healthcheck", "-c", "bob", "-zkHost", cluster.getZkClient().getZkServerAddress()
         };
     assertEquals(0, runTool(args));
   }
@@ -61,7 +61,7 @@ public class HealthcheckToolTest extends SolrCloudTestCase {
     String solrUrl =
         ZkStateReader.from(cluster.getSolrClient()).getBaseUrlForNodeName(firstLiveNode);
 
-    String[] args = new String[] {"healthcheck", "-collection", "bob", "-solrUrl", solrUrl};
+    String[] args = new String[] {"healthcheck", "-c", "bob", "-solrUrl", solrUrl};
     assertEquals(0, runTool(args));
   }
 
diff --git a/solr/core/src/test/org/apache/solr/cloud/SolrCloudExampleTest.java b/solr/core/src/test/org/apache/solr/cloud/SolrCloudExampleTest.java
index bee0dd60723..2b7a74a2f67 100644
--- a/solr/core/src/test/org/apache/solr/cloud/SolrCloudExampleTest.java
+++ b/solr/core/src/test/org/apache/solr/cloud/SolrCloudExampleTest.java
@@ -191,7 +191,7 @@ public class SolrCloudExampleTest extends AbstractFullDistribZkTestBase {
   protected void doTestHealthcheck(String testCollectionName, String zkHost) throws Exception {
     String[] args =
         new String[] {
-          "-collection", testCollectionName,
+          "-name", testCollectionName,
           "-zkHost", zkHost
         };
     HealthcheckTool tool = new HealthcheckTool();
@@ -218,7 +218,6 @@ public class SolrCloudExampleTest extends AbstractFullDistribZkTestBase {
    * collection.
    */
   protected void doTestConfigUpdate(String testCollectionName, String solrUrl) throws Exception {
-    if (!solrUrl.endsWith("/")) solrUrl += "/";
 
     try (SolrClient solrClient = SolrCLI.getSolrClient(solrUrl)) {
       NamedList<Object> configJson =
@@ -233,7 +232,7 @@ public class SolrCloudExampleTest extends AbstractFullDistribZkTestBase {
       Integer maxTime = 3000;
       String[] args =
           new String[] {
-            "-collection", testCollectionName,
+            "-name", testCollectionName,
             "-property", prop,
             "-value", maxTime.toString(),
             "-solrUrl", solrUrl
diff --git a/solr/core/src/test/org/apache/solr/security/BasicAuthIntegrationTest.java b/solr/core/src/test/org/apache/solr/security/BasicAuthIntegrationTest.java
index 013f1577a24..3599a4e2ebe 100644
--- a/solr/core/src/test/org/apache/solr/security/BasicAuthIntegrationTest.java
+++ b/solr/core/src/test/org/apache/solr/security/BasicAuthIntegrationTest.java
@@ -298,7 +298,7 @@ public class BasicAuthIntegrationTest extends SolrCloudAuthTestCase {
       verifySecurityStatus(cl, baseUrl + "/admin/info/key", "key", NOT_NULL_PREDICATE, 20);
       assertAuthMetricsMinimums(17, 8, 8, 1, 0, 0);
 
-      String[] toolArgs = new String[] {"status", "-solr", baseUrl};
+      String[] toolArgs = new String[] {"status", "-solrUrl", baseUrl};
       ByteArrayOutputStream baos = new ByteArrayOutputStream();
       PrintStream stdoutSim = new PrintStream(baos, true, StandardCharsets.UTF_8.name());
       StatusTool tool = new StatusTool(stdoutSim);
@@ -312,7 +312,7 @@ public class BasicAuthIntegrationTest extends SolrCloudAuthTestCase {
         assertTrue(obj.containsKey("memory"));
       } catch (Exception e) {
         log.error(
-            "RunExampleTool failed due to: {}; stdout from tool prior to failure: {}",
+            "StatusTool failed due to: {}; stdout from tool prior to failure: {}",
             e,
             baos.toString(StandardCharsets.UTF_8.name())); // nowarn
       }
diff --git a/solr/packaging/test/test_status.bats b/solr/packaging/test/test_config.bats
similarity index 55%
copy from solr/packaging/test/test_status.bats
copy to solr/packaging/test/test_config.bats
index c1ca0c5986f..b30ff762f0a 100644
--- a/solr/packaging/test/test_status.bats
+++ b/solr/packaging/test/test_config.bats
@@ -17,30 +17,38 @@
 
 load bats_helper
 
-setup() {
+setup_file() {
   common_clean_setup
+  solr start -c
+}
+
+teardown_file() {
+  common_setup
+  solr stop -all
+}
+
+setup() {
+  common_setup
 }
 
 teardown() {
   # save a snapshot of SOLR_HOME for failed tests
   save_home_on_failure
 
-  solr stop -all >/dev/null 2>&1
+  delete_all_collections
 }
 
-@test "status detects locally running solr" {
-  run solr status
-  assert_output --partial "No Solr nodes are running."
-  run solr start
-  run solr status
-  assert_output --partial "Found 1 Solr nodes:"
-  run solr stop
-  run solr status
-  assert_output --partial "No Solr nodes are running."
+@test "setting property" {
+  solr create_collection -c COLL_NAME
 
+  run solr config -c COLL_NAME -action set-property -property updateHandler.autoCommit.maxDocs -value 100 -solrUrl http://localhost:8983/solr
+  assert_output --partial "Successfully set-property updateHandler.autoCommit.maxDocs to 100"
 }
 
-@test "status does not expose cli parameters to end user" {
-  run solr status -solr http://localhost:8983/solr
-  assert_output --partial "ERROR: Unrecognized or misplaced argument: -solr!"
+@test "short form of setting property" {
+  solr create_collection -c COLL_NAME
+
+  run solr config -c COLL_NAME -property updateHandler.autoCommit.maxDocs -value 100
+  assert_output --partial "Successfully set-property updateHandler.autoCommit.maxDocs to 100"
+  assert_output --partial "assuming solrUrl is http://localhost:8983/solr"
 }
diff --git a/solr/packaging/test/test_create_collection.bats b/solr/packaging/test/test_create_collection.bats
index 04ff281aa3f..f4037ebccfe 100644
--- a/solr/packaging/test/test_create_collection.bats
+++ b/solr/packaging/test/test_create_collection.bats
@@ -41,15 +41,27 @@ teardown() {
 @test "create collection" {
   run solr create_collection -c COLL_NAME
   assert_output --partial "Created collection 'COLL_NAME'"
+  assert_output --partial "assuming solrUrl is http://localhost:8983/solr"
+}
+
+@test "create collection using solrUrl" {
+  run solr create_collection -c COLL_NAME -solrUrl http://localhost:8983/solr
+  assert_output --partial "Created collection 'COLL_NAME'"  
+  refute_output --partial "assuming solrUrl is http://localhost:8983/solr"
+}
+
+@test "create collection using Zookeeper" {
+  run solr create_collection -c COLL_NAME -zkHost localhost:9983
+  assert_output --partial "Created collection 'COLL_NAME'"
 }
 
 @test "reject d option with invalid config dir" {
-  run ! solr create_collection -c COLL_NAME -d /asdf
+  run ! solr create_collection -c COLL_NAME -d /asdf  -solrUrl http://localhost:8983/solr
   assert_output --partial "Specified configuration directory /asdf not found!"
 }
 
 @test "accept d option with builtin config" {
-  run solr create_collection -c COLL_NAME -d sample_techproducts_configs
+  run solr create_collection -c COLL_NAME -d sample_techproducts_configs -solrUrl http://localhost:8983/solr
   assert_output --partial "Created collection 'COLL_NAME'"
 }
 
@@ -59,34 +71,34 @@ teardown() {
   test -d $source_configset_dir
   cp -r "${source_configset_dir}" "${dest_configset_dir}"
 
-  run solr create_collection -c COLL_NAME -d "${dest_configset_dir}"
+  run solr create_collection -c COLL_NAME -d "${dest_configset_dir}" -solrUrl http://localhost:8983/solr
   assert_output --partial "Created collection 'COLL_NAME'"
 }
 
 @test "accept n option as config name" {
-  run solr create_collection -c COLL_NAME -n other_conf_name
+  run solr create_collection -c COLL_NAME -n other_conf_name -solrUrl http://localhost:8983/solr
   assert_output --partial "Created collection 'COLL_NAME'"
   assert_output --partial "config-set 'other_conf_name'"
 }
 
 @test "allow config reuse when n option specifies same config" {
-  run -0 solr create_collection -c COLL_NAME_1 -n shared_config
+  run -0 solr create_collection -c COLL_NAME_1 -n shared_config -solrUrl http://localhost:8983/solr
   assert_output --partial "Created collection 'COLL_NAME_1'"
   assert_output --partial "config-set 'shared_config'"
 
-  run -0 solr create_collection -c COLL_NAME_2 -n shared_config
+  run -0 solr create_collection -c COLL_NAME_2 -n shared_config -solrUrl http://localhost:8983/solr
   assert_output --partial "Created collection 'COLL_NAME_2'"
   assert_output --partial "config-set 'shared_config'"
 }
 
 @test "create multisharded collections when s provided" {
-  run -0 solr create_collection -c COLL_NAME -s 2
+  run -0 solr create_collection -c COLL_NAME -s 2 -solrUrl http://localhost:8983/solr
   assert_output --partial "Created collection 'COLL_NAME'"
   assert_output --partial "2 shard(s)"
 }
 
 @test "create replicated collections when rf provided" {
-  run -0 solr create_collection -c COLL_NAME -rf 2
+  run -0 solr create_collection -c COLL_NAME -rf 2 -solrUrl http://localhost:8983/solr
   assert_output --partial "Created collection 'COLL_NAME'"
   assert_output --partial "2 replica(s)"
-}
\ No newline at end of file
+}
diff --git a/solr/packaging/test/test_help.bats b/solr/packaging/test/test_help.bats
index 0bdcb17566f..49015a64213 100644
--- a/solr/packaging/test/test_help.bats
+++ b/solr/packaging/test/test_help.bats
@@ -21,6 +21,17 @@ setup() {
   common_clean_setup
 }
 
+@test "solr help flag prints help" {
+  run -1 solr -help
+  assert_output --partial 'Usage: solr COMMAND OPTIONS'
+  refute_output --partial 'ERROR'
+}
+@test "solr with no flags prints help" {
+  run -1 solr
+  assert_output --partial 'Usage: solr COMMAND OPTIONS'
+  refute_output --partial 'ERROR'
+}
+
 @test "start help flag prints help" {
   run solr start -help
   assert_output --partial 'Usage: solr start'
@@ -40,36 +51,38 @@ setup() {
 }
 
 @test "status help flag prints help" {
-  skip "Currently the status -help flag doesn't return nice help text!"
+  run solr status -help
+  assert_output --partial 'usage: status'
+  refute_output --partial 'ERROR'
 }
 
 @test "healthcheck help flag prints help" {
   run solr healthcheck -help
-  assert_output --partial 'Usage: solr healthcheck'
+  assert_output --partial 'usage: healthcheck'
   refute_output --partial 'ERROR'
 }
 
 @test "create help flag prints help" {
   run solr create -help
-  assert_output --partial 'Usage: solr create'
+  assert_output --partial 'usage: create'
   refute_output --partial 'ERROR'
 }
 
 @test "createcore help flag prints help" {
   run solr create_core -help
-  assert_output --partial 'Usage: solr create_core'
+  assert_output --partial 'usage: create_core'
   refute_output --partial 'ERROR'
 }
 
 @test "createcollection help flag prints help" {
   run solr create_collection -help
-  assert_output --partial 'Usage: solr create_collection'
+  assert_output --partial 'usage: create_collection'
   refute_output --partial 'ERROR'
 }
 
 @test "delete help flag prints help" {
   run solr delete -help
-  assert_output --partial 'Usage: solr delete'
+  assert_output --partial 'usage: delete'
   refute_output --partial 'ERROR'
 }
 
@@ -90,5 +103,7 @@ setup() {
 }
 
 @test "assert help flag prints help" {
-  skip "Currently the assert -help flag doesn't return nice help text!"
-}
\ No newline at end of file
+  run solr assert -help
+  assert_output --partial 'usage: assert'
+  refute_output --partial 'ERROR'
+}
diff --git a/solr/packaging/test/test_status.bats b/solr/packaging/test/test_status.bats
index c1ca0c5986f..64885dc7f52 100644
--- a/solr/packaging/test/test_status.bats
+++ b/solr/packaging/test/test_status.bats
@@ -31,16 +31,24 @@ teardown() {
 @test "status detects locally running solr" {
   run solr status
   assert_output --partial "No Solr nodes are running."
-  run solr start
+  solr start
   run solr status
   assert_output --partial "Found 1 Solr nodes:"
-  run solr stop
+  solr stop
   run solr status
   assert_output --partial "No Solr nodes are running."
 
 }
 
-@test "status does not expose cli parameters to end user" {
-  run solr status -solr http://localhost:8983/solr
-  assert_output --partial "ERROR: Unrecognized or misplaced argument: -solr!"
+@test "status shell script ignores passed in -solrUrl cli parameter from user" {
+  solr start
+  run solr status -solrUrl http://localhost:9999/solr
+  assert_output --partial "Found 1 Solr nodes:"
+  assert_output --partial "running on port 8983"
+}
+
+@test "status help flag outputs message highlighting not to use solrUrl." {
+  run solr status -help
+  assert_output --partial 'usage: status'
+  refute_output --partial 'ERROR'
 }
diff --git a/solr/solr-ref-guide/modules/deployment-guide/pages/solr-control-script-reference.adoc b/solr/solr-ref-guide/modules/deployment-guide/pages/solr-control-script-reference.adoc
index 5c20a5197ae..b82e642e754 100644
--- a/solr/solr-ref-guide/modules/deployment-guide/pages/solr-control-script-reference.adoc
+++ b/solr/solr-ref-guide/modules/deployment-guide/pages/solr-control-script-reference.adoc
@@ -188,7 +188,7 @@ If you want to accept all of the defaults, you can simply add the `-noprompt` op
 +
 Specify the port to start the Solr HTTP listener on; with the classic default port for Solr being 8983.
 The specified port (SOLR_PORT) will also be used to determine the stop port.
-The stop port is defined as STOP_PORT=($SOLR_PORT-1000) and JMX RMI listen port is defined as RMI_PORT=($SOLR_PORT+10000). 
+The stop port is defined as STOP_PORT=($SOLR_PORT-1000) and JMX RMI listen port is defined as RMI_PORT=($SOLR_PORT+10000).
 For instance, if you set -p 8985, then the STOP_PORT=7985 and RMI_PORT=18985.
 If this is not specified, `8983` will be used.
 +
@@ -208,7 +208,7 @@ If set, the specified directory should contain a solr.xml file, unless solr.xml
 +
 This parameter is ignored when running examples (`-e`), as the `solr.solr.home` depends on which example is run.
 +
-The default value is `server/solr`. 
+The default value is `server/solr`.
 If passed relative dir, validation with current dir will be done, before trying default `server/<dir>`.
 +
 *Example*: `bin/solr start -s newHome`
@@ -630,9 +630,9 @@ The `bin/solr` script can also help you create new collections or cores, or dele
 
 === Create a Core or Collection
 
-The `create` command creates a core or collection depending on whether Solr is running in standalone (core) or SolrCloud mode (collection). 
+The `create` command creates a core or collection depending on whether Solr is running in standalone (core) or SolrCloud mode (collection).
 In other words, this action detects which mode Solr is running in, and then takes the appropriate action (either `create_core` or `create_collection`).
-  
+
 `bin/solr create [options]`
 
 `bin/solr create -help`
@@ -675,20 +675,6 @@ This defaults to the same name as the core or collection.
 +
 *Example*: `bin/solr create -n basic`
 
-`-p <port>` or `-port <port>`::
-+
-[%autowidth,frame=none]
-|===
-|Optional |Default: _see description_
-|===
-+
-The port of a local Solr instance to send the create command to.
-By default the script tries to detect the port by looking for running Solr instances.
-+
-This option is useful if you are running multiple Solr instances on the same host, thus requiring you to be specific about which instance to create the core in.
-+
-*Example*: `bin/solr create -p 8983`
-
 `-s <shards>` or `-shards <shards>`::
 +
 [%autowidth,frame=none]
@@ -727,8 +713,8 @@ It is possible to override this warning with the -force parameter.
 
 === Create a Collection
 
-The `create_collection` command creates a collection, and is only available when running in SolrCloud mode. 
-  
+The `create_collection` command creates a collection, and is only available when running in SolrCloud mode.
+
 `bin/solr create_collection [options]`
 
 `bin/solr create_collection -help`
@@ -765,7 +751,7 @@ Alternatively, you can pass the path to your own configuration directory instead
 +
 *Example*: `bin/solr create_collection -c mycoll -d /tmp/myconfig`
 +
-By default the script will upload the specified confdir directory into Zookeeper using the same name as the collection (-c) option. 
+By default the script will upload the specified confdir directory into Zookeeper using the same name as the collection (-c) option.
 Alternatively, if you want to reuse an existing directory or create a confdir in Zookeeper that can be shared by multiple collections, use the -n option
 +
 
@@ -833,8 +819,8 @@ It is possible to override this warning with the -force parameter.
 
 === Create a Core
 
-The `create_core` command creates a core and is only available when running in user-managed (single-node) mode. 
-  
+The `create_core` command creates a core and is only available when running in user-managed (single-node) mode.
+
 `bin/solr create_core [options]`
 
 `bin/solr create_core -help`
@@ -931,7 +917,7 @@ Consequently, we recommend that you do not share data-driven configurations betw
 You can turn off schemaless functionality for a collection with the following command, assuming the collection name is `mycollection`.
 
 [source,bash]
-$ bin/solr config -c mycollection -p 8983 -action set-user-property -property update.autoCreateFields -value false
+$ bin/solr config -c mycollection -action set-user-property -property update.autoCreateFields -value false
 
 See also the section <<Set or Unset Configuration Properties>>.
 
@@ -974,19 +960,14 @@ If the configuration directory is being used by another collection, then it will
 +
 *Example*: `bin/solr delete -deleteConfig false`
 
-`-p <port>` or `-port <port>`::
+`-forceDeleteConfig`::
 +
 [%autowidth,frame=none]
 |===
-|Optional |Default: _see description_
+|Optional |Default: `true`
 |===
 +
-The port of a local Solr instance to send the delete command to.
-If not specified, the script will search the local system for a running Solr instance and will use the port of the first server it finds.
-+
-This option is useful if you are running multiple Solr instances on the same host, thus requiring you to be specific about which instance to delete the core from.
-+
-*Example*: `bin/solr delete -p 8983`
+Skip safety checks when deleting the configuration directory used by a collection.
 
 == Authentication
 
@@ -1058,7 +1039,7 @@ The command takes the following parameters:
 |Optional |Default: none
 |===
 +
-The username and password in the format of `username:password` of the initial user.  
+The username and password in the format of `username:password` of the initial user.
 Applicable for basicAuth only.
 +
 If you prefer not to pass the username and password as an argument to the script, you can choose the `-prompt` option.
@@ -1164,29 +1145,29 @@ The `bin/solr` script enables a subset of the Config API: xref:configuration-gui
 
 To set the common property `updateHandler.autoCommit.maxDocs` to `100` on collection `mycollection`:
 
-`bin/solr config -c mycollection -p 8983 -action set-property -property updateHandler.autoCommit.maxDocs -value 100`
+`bin/solr config -c mycollection -action set-property -property updateHandler.autoCommit.maxDocs -value 100`
 
 The default `-action` is `set-property`, so the above can be shortened by not mentioning it:
 
-`bin/solr config -c mycollection -p 8983 -property updateHandler.autoCommit.maxDocs -value 100`
+`bin/solr config -c mycollection -property updateHandler.autoCommit.maxDocs -value 100`
 
 To unset a previously set common property, specify `-action unset-property` with no `-value`:
 
-`bin/solr config -c mycollection -p 8983 -action unset-property -property updateHandler.autoCommit.maxDocs`
+`bin/solr config -c mycollection -action unset-property -property updateHandler.autoCommit.maxDocs`
 
 === Set or Unset User-Defined Properties
 
 To set the user-defined property `update.autoCreateFields` to `false` (to disable xref:indexing-guide:schemaless-mode.adoc[]):
 
-`bin/solr config -c mycollection -p 8983 -action set-user-property -property update.autoCreateFields -value false`
+`bin/solr config -c mycollection -action set-user-property -property update.autoCreateFields -value false`
 
 To unset a previously set user-defined property, specify `-action unset-user-property` with no `-value`:
 
-`bin/solr config -c mycollection -p 8983 -action unset-user-property -property update.autoCreateFields`
+`bin/solr config -c mycollection -action unset-user-property -property update.autoCreateFields`
 
 === Config Parameters
 
-`-c <name>` or `-collection <name>`::
+`-c <name>` or `-name <name>`::
 +
 [%autowidth,frame=none]
 |===
@@ -1232,15 +1213,6 @@ Set the property to this value; accepts JSON objects and strings.
 The ZooKeeper connection string, usable in SolrCloud mode.
 Unnecessary if `ZK_HOST` is defined in `solr.in.sh` or `solr.in.cmd`.
 
-`-p <port>` or `-port <port>`::
-+
-[%autowidth,frame=none]
-|===
-|Optional |Default: none
-|===
-+
-`localhost` port of the Solr node to use when applying the configuration change.
-
 `-solrUrl <url>`::
 +
 [%autowidth,frame=none]
@@ -1480,10 +1452,10 @@ Optional if `ZK_HOST` is defined in `solr.in.sh` or `solr.in.cmd`.
 +
 *Example*: `-z 123.321.23.43:2181`
 
-When `<src>` is a zk resource, `<dest>` may be '.'. 
-If `<dest>` ends with '/', then `<dest>` will be a local folder or parent znode and the last element of the <src> path will be appended unless `<src>` also ends in a slash. 
+When `<src>` is a zk resource, `<dest>` may be '.'.
+If `<dest>` ends with '/', then `<dest>` will be a local folder or parent znode and the last element of the <src> path will be appended unless `<src>` also ends in a slash.
 `<dest>` may be `zk:`, which may be useful when using the `cp -r` form to backup/restore the entire zk state.
-You must enclose local paths that end in a wildcard in quotes or just end the local path in a slash. 
+You must enclose local paths that end in a wildcard in quotes or just end the local path in a slash.
 That is, `bin/solr zk cp -r /some/dir/ zk:/ -z localhost:2181` is equivalent to `bin/solr zk cp -r "/some/dir/*" zk:/ -z localhost:2181` but `bin/solr zk cp -r /some/dir/\* zk:/ -z localhost:2181` will throw an error.
 
 Here's an example of backup/restore for a ZK configuration: