Script Guide: Automating ConnectWise URL Creation for macOS

Key takeaways

  • The script automates the retrieval and storage of ConnectWise Control Launch URLs on macOS, significantly streamlining remote support.
  • It offers customization options for instance IDs, domains, session groups, and custom fields, tailoring to specific IT environments.
  • Inclusion of a help function and error handling enhances user guidance and troubleshooting.
  • The script’s approach is more efficient and organized compared to manual URL management or basic scripting solutions.
  • Security and controlled access to generated URLs are essential for maintaining IT security.
  • Testing the script in a specific macOS environment is recommended before full deployment.
  • Integrating this script into a wider toolset like NinjaOne can further optimize remote support and IT management tasks.

Background

In today’s interconnected IT landscape, efficiency and reliability in remote support are not just conveniences but necessities. Advanced scripting, particularly in the context of managing remote assistance software, plays a pivotal role in achieving these objectives. The script we’re discussing today exemplifies this, providing a streamlined approach to managing ConnectWise Control (formerly ScreenConnect) sessions on macOS.

This Bash script is designed for IT professionals and Managed Service Providers (MSPs) who use ConnectWise Control for remote support. Its primary function is to retrieve and save ConnectWise Control Launch URLs, a crucial component in remote desktop assistance. This process involves leveraging specific instance IDs, domain information, and session groups to build accurate and accessible URLs. Its significance lies in its automation of a typically manual and time-consuming task, thereby enhancing productivity and response times for IT support teams.

The script:

#!/usr/bin/env bash
#
# Description: Retrieves the Connectwise ScreenConnect Launch URL and saves it to a custom field (defaults to screenconnectURL). Requires the domain used for ScreenConnect and a Session Group that all machines are a part of to successfully build the URL.
# By using this script, you indicate your acceptance of the following legal terms as well as our Terms of Use at https://www.ninjaone.com/terms-of-use.
# Ownership Rights: NinjaOne owns and will continue to own all right, title, and interest in and to the script (including the copyright). NinjaOne is giving you a limited license to use the script in accordance with these legal terms. 
# Use Limitation: You may only use the script for your legitimate personal or internal business purposes, and you may not share the script with another party. 
# Republication Prohibition: Under no circumstances are you permitted to re-publish the script in any script library or website belonging to or under the control of any other software provider. 
# Warranty Disclaimer: The script is provided “as is” and “as available”, without warranty of any kind. NinjaOne makes no promise or guarantee that the script will be free from defects or that it will meet your specific needs or expectations. 
# Assumption of Risk: Your use of the script is at your own risk. You acknowledge that there are certain inherent risks in using the script, and you understand and assume each of those risks. 
# Waiver and Release: You will not hold NinjaOne responsible for any adverse or unintended consequences resulting from your use of the script, and you waive any legal or equitable rights or remedies you may have against NinjaOne relating to your use of the script. 
# EULA: If you are a NinjaOne customer, your use of the script is subject to the End User License Agreement applicable to you (EULA).
#
# Preset Parameter: --instanceId "ReplaceMeWithYourInstanceId"
#   The Instance ID for your instance of ScreenConnect. Used to differentiate between multiple installed ScreenConnect instances.
#   To get the instance ID, you can see it in the program name, e.g., connectwisecontrol-yourinstanceidhere.
#   It's also available in the ScreenConnect Admin Center (Administration > Advanced > Server Information).
#
# Preset Parameter: --screenconnectDomain "replace.me"
#   The domain used for your ScreenConnect instance.
#
# Preset Parameter: --sessionGroup "ReplaceMe"
#   A session group that contains all of your machines (defaults to All Machines)
#
# Preset Parameter: --customField "ReplaceMeWithAnyMultilineCustomField"
#   The custom field you would like to store this information in.
#
# Preset Parameter: --help
#   Displays some help text.

# These are all our preset parameter defaults. You can set these = to something if you would prefer the script defaults to a certain parameter value.
_arg_instanceId=
_arg_screenconnectdomain=
_arg_sessiongroup="All Machines"
_arg_customfield="screenconnectURL"
_fieldValue=

# Help text function for when invalid input is encountered
print_help() {
  printf '\n\n%s\n\n' 'Usage: [--instanceId|-i <arg>] [--screenconnectDomain|-d <arg>] [--sessionGroup|-g <arg>] [--customField|-c <arg>] [--help|-h]'
  printf '%s\n' 'Preset Parameter: --instanceid "ReplaceWithYourInstanceID"'
  printf '\t%s\n' "Replace the text encased in quotes with your instance ID. You can see the instance ID in the ScreenConnect Admin Center (Administration > Advanced > Server Information). It's also usually present in the application name on any installed instance, e.g., connectwisecontrol-yourinstanceid."
  printf '\n%s\n' 'Preset Parameter: --screenconnectDomain "replace.me"'
  printf '\t%s' "Replace the text encased in quotes with the domain used for ConnectWise ScreenConnect, e.g., 'example.screenconnect.com'."
  printf '\n%s\n' 'Preset Parameter: --sessionGroup "Replace Me"'
  printf '\t%s' "Replace the text encased in quotes with the name of a Session Group in ConnectWise ScreenConnect that contains All Machines (defaults to All Machines). ex. 'All Machines'"
  printf '\n%s\n' 'Preset Parameter: --customField "replaceMe"'
  printf '\t%s' "Replace the text encased in quotes with the name of a custom field you'd like to store this information to (defaults to launchUrl). ex. 'screenconnectUrl'"
  printf '\n%s\n' 'Preset Parameter: --help'
  printf '\t%s\n' "Displays this help menu."
}

# Determines whether or not help text is necessary and routes the output to stderr
die() {
  local _ret="${2:-1}"
  echo "$1" >&2
  test "${_PRINT_HELP:-no}" = yes && print_help >&2
  exit "${_ret}"
}

# Grabbing the parameters and parsing through them.
parse_commandline() {
  while test $# -gt 0; do
    _key="$1"
    case "$_key" in
    --screenconnectdomain | --screenconnectDomain | --domain | -d)
      test $# -lt 2 && die "Missing value for the optional argument '$_key'." 1
      _arg_screenconnectdomain=$2
      shift
      ;;
    --screenconnectdomain=*)
      _arg_screenconnectdomain="${_key##--screenconnectdomain=}"
      ;;
    --instanceId | --instanceid | -i)
      test $# -lt 2 && die "Missing value for the optional argument '$_key'." 1
      _arg_instanceId=$2
      shift
      ;;
    --instanceid=*)
      _arg_instanceId="${_key##--instanceid=}"
      ;;
    --sessionGroup | --sessiongroup | -g)
      test $# -lt 2 && die "Missing value for the optional argument '$_key'." 1
      _arg_sessiongroup=$2
      shift
      ;;
    --sessiongroup=*)
      _arg_sessiongroup="${_key##--sessiongroup=}"
      ;;
    --customField | --customfield | -c)
      test $# -lt 2 && die "Missing value for the optional argument '$_key'." 1
      _arg_customfield=$2
      shift
      ;;
    --customfield=*)
      _arg_customfield="${_key##--customfield=}"
      ;;
    --help | -h)
      _PRINT_HELP=yes die 0
      ;;
    *)
      _PRINT_HELP=yes die "FATAL ERROR: Got an unexpected argument '$1'" 1
      ;;
    esac
    shift
  done
}

# Function to set a custom field
setCustomField() {
  echo "$_fieldValue" | /Applications/NinjaRMMAgent/programdata/ninjarmm-cli set --stdin "$_arg_customfield"
}

export PATH=$PATH:/usr/sbin:/usr/bin

parse_commandline "$@"

# If script form is used override commandline agruments
if [[ -n $screenconnectDomain ]]; then
  _arg_screenconnectdomain="$screenconnectDomain"
fi

if [[ -n $sessionGroup ]]; then
  _arg_sessiongroup="$sessionGroup"
fi

if [[ -n $instanceId ]]; then
  _arg_instanceId="$instanceId"
fi

if [[ -n $customFieldName ]]; then
  _arg_customfield="$customFieldName"
fi

# If we weren't given an instance id we should warn that this is not advised.
if [[ -z $_arg_instanceId ]]; then
  echo "WARNING: Without the instance id we will be unable to tell which ScreenConnect instance is yours (if multiple are installed). This may result in the wrong URL being displayed."
  echo "To get the instance id you can find it in ScreenConnect itself (Admin > Advanced > Server Information > Instance Identifier Fingerprint). It's also in the application name on every installed copy 'connectwisecontrol-yourinstanceidhere'"
fi

# --screenconnectDomain and --sessionGroup are required. We should also escape the session group given.
if [[ -z $_arg_screenconnectdomain || -z $_arg_sessiongroup ]]; then
  _PRINT_HELP=yes die "FATAL ERROR: Unable to build the URL without the Domain and Session Group!" 1
else
  _arg_sessiongroup=$(echo "$_arg_sessiongroup" | perl -MURI::Escape -ne 'chomp;print uri_escape($_),"\n"')
fi

# Double check ScreenConnect is installed
installedPkg=$(pkgutil --pkgs | grep "connectwisecontrol-$_arg_instanceId")
if [[ -z $installedPkg ]]; then
  _PRINT_HELP=no die "FATAL ERROR: It appears ConnectWise ScreenConnect is not installed!" 1
fi

# Lets start building some urls
for pkg in $installedPkg; do
  file="/Applications/$pkg.app/Contents/Resources/ClientLaunchParameters.txt.lproj/locversion.plist"
  id=$(grep -Eo 's=.{8}-.{4}-.{4}-.{4}-.{12}' "$file" | sed 's/s=//g' | sed 's/&e=Access//g')
  instanceid=${pkg//"connectwisecontrol-"/}
  # We shouldn't have multiple results but if we do we should warn the technician
  if [[ -n "$launchurls" ]]; then
    echo "WARNING: Multiple installed instances detected and no instance id was given. One of these urls will be incorrect."
    launchurls=$(
      printf '%s\n' "$launchurls"
      printf '%s\t' "$instanceid"
      printf '%s\n' "https://$_arg_screenconnectdomain/Host#Access/$_arg_sessiongroup//$id/Join"
    )
  else
    launchurls=$(
      printf '%s\t\t' "InstanceID"
      printf '%s\n' "LaunchURL"
      printf '%s\t' "$instanceid"
      printf '%s\t' "https://$_arg_screenconnectdomain/Host#Access/$_arg_sessiongroup//$id/Join"
    )
  fi
done

# Check that we were successful
if [[ -n $launchurls ]]; then
  echo "Launch URL(s) Created"
else
  _PRINT_HELP=no die "FATAL ERROR: Failed to create Launch URL(s)!" 1
fi

# Change how we output the results based on how many urls we received.
if [[ $(echo "$launchurls" | wc -l) -gt 2 ]]; then
  _fieldValue="$launchurls"
  echo "$_fieldValue"
else
  _fieldValue=$(echo "$launchurls" | tail -n 1 | awk '{print $2}')
  echo "$_fieldValue"
fi

echo "Setting Custom Field..."
setCustomField
exit 0

 

Access over 300+ scripts in the NinjaOne Dojo

Get Access

Detailed breakdown

The script operates in several stages:

  • Parameter initialization: It begins by setting up default values for various parameters like instance ID, domain, session group, and custom field name.
  • Help function: A help text function is incorporated, which guides users through the script’s usage, especially in cases of invalid inputs.
  • Command line parsing: It parses through command-line arguments to customize settings like domain and instance ID.
  • Custom field setting: The script includes a function to set a custom field in the NinjaRMM tool, where the ConnectWise Control URL will be stored.
  • Building launch URLs: The core functionality is in building the Launch URLs by extracting necessary IDs from installed packages and constructing the URL based on provided parameters.
  • Output handling: Depending on the number of URLs generated, it either stores them in a custom field or outputs them directly.

Potential use cases

Imagine an IT professional managing a fleet of devices across different client organizations. They need to provide timely remote support but managing individual session URLs is cumbersome. Using this script, they can quickly generate and store these URLs, ensuring swift and organized remote access.

Comparisons

Traditionally, IT professionals might manually configure each session URL or use less sophisticated scripts. This script, however, automates the entire process and is specifically tailored for ConnectWise Control on macOS, offering a more efficient and error-free solution.

FAQs:

  • How do I find the instance ID?
    • Check the ScreenConnect Admin Center or the application name on installed instances.
  • Is it compatible with all macOS versions?
    • It’s designed for general compatibility but always test on your specific version first.
  • Can I customize the storage field for URLs?
    • Yes, the script allows setting a custom field of your choice.

Implications

While the script streamlines the process of managing remote sessions, it’s essential to consider security implications. Ensuring that URLs are stored securely and access is controlled is crucial for IT security.

Recommendations

  • Regularly update the script to cater to new updates in ConnectWise Control.
  • Keep a check on security permissions for the stored URLs.
  • Test the script in a controlled environment before widespread deployment.

Final thoughts

Incorporating such scripts into a broader toolkit like NinjaOne can significantly enhance an IT professional’s ability to manage remote support efficiently and securely. NinjaOne’s comprehensive approach to remote monitoring and management complements these scripts, providing a robust platform for IT management.

Next Steps

Building an efficient and effective IT team requires a centralized solution that acts as your core service deliver tool. NinjaOne enables IT teams to monitor, manage, secure, and support all their devices, wherever they are, without the need for complex on-premises infrastructure.

Learn more about NinjaOne Remote Script Deployment, check out a live tour, or start your free trial of the NinjaOne platform.

Categories:

You might also like

×

See NinjaOne in action!

By submitting this form, I accept NinjaOne's privacy policy.

NinjaOne Terms & Conditions

By clicking the “I Accept” button below, you indicate your acceptance of the following legal terms as well as our Terms of Use:

  • Ownership Rights: NinjaOne owns and will continue to own all right, title, and interest in and to the script (including the copyright). NinjaOne is giving you a limited license to use the script in accordance with these legal terms.
  • Use Limitation: You may only use the script for your legitimate personal or internal business purposes, and you may not share the script with another party.
  • Republication Prohibition: Under no circumstances are you permitted to re-publish the script in any script library belonging to or under the control of any other software provider.
  • Warranty Disclaimer: The script is provided “as is” and “as available”, without warranty of any kind. NinjaOne makes no promise or guarantee that the script will be free from defects or that it will meet your specific needs or expectations.
  • Assumption of Risk: Your use of the script is at your own risk. You acknowledge that there are certain inherent risks in using the script, and you understand and assume each of those risks.
  • Waiver and Release: You will not hold NinjaOne responsible for any adverse or unintended consequences resulting from your use of the script, and you waive any legal or equitable rights or remedies you may have against NinjaOne relating to your use of the script.
  • EULA: If you are a NinjaOne customer, your use of the script is subject to the End User License Agreement applicable to you (EULA).