From 7efe7658542456940ab80e930956046eb76ed52a Mon Sep 17 00:00:00 2001 From: David Schroeder Date: Sat, 25 Jul 2026 10:18:31 -0500 Subject: [PATCH] v2.initial upload --- README.md | 50 ++++++++++++++++++- defaults.inc | 41 +++++++++------ proxmenu-scripts.sh | 119 ++++++++++++++++++++++++-------------------- run.sh | 11 ++-- 4 files changed, 145 insertions(+), 76 deletions(-) diff --git a/README.md b/README.md index ad24098..e5dd876 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,49 @@ -# TA-Proxmenu - Proxmox Scripts for TA Use +# TA-ProxMenu - bash <(curl -sL https://go.scity.us/install-tapm) +Interactive installation and configuration helpers used when deploying Proxmox +VE environments. + +## Install + +Run as `root` on a Proxmox VE host: + +```bash +bash <(curl -fsSL https://go.scity.us/install-tapm) +``` + +The installed launcher loads the shared iDSSYS defaults, checks for updates, +and opens the interactive menu. + +## Direct actions + +The menu script also supports these direct actions: + +```text +pulse Install Pulse monitoring +rmm Install the ConnectWise RMM agent +omsa Install Dell OpenManage Server Administrator +glances Install Glances +acronis Install the Acronis agent +proxmenux Install or open ProxMenux +screenconnect Install the ScreenConnect agent +restart Restart local Proxmox services +cpu Detect and optionally apply a migration-safe CPU model +mm Toggle local HA maintenance mode +timeout Set VM shutdown timeouts +``` + +## Companion files + +Large installer artifacts used by this project are stored in the separate +`TAI/files` repository. The SentinelOne package filename and displayed version +are defined together in `defaults.inc`. + +## Runtime requirements + +- Proxmox VE and root privileges +- Bash, Git, curl, wget, and standard Debian package tools +- `/opt/idssys/defaults/default.inc` +- `/opt/idssys/defaults/colors.inc` + +The Keepalived deployment additionally requires a healthy, quorate Proxmox +cluster and passwordless root SSH between cluster nodes. diff --git a/defaults.inc b/defaults.inc index 70652dd..2c768bd 100755 --- a/defaults.inc +++ b/defaults.inc @@ -1,27 +1,39 @@ #!/usr/bin/env bash # TA-Proxmenu - Proxmox Setup Scripts for TA Use -action="$1" +action="${1:-}" FOLDER='/opt/idssys/ta-proxmenu' -VERS='2026.7.25-4' +VERS='2026.7.25-5' noupdate=' ' - -RNIP=$(ip addr show $(ip route | awk '/default/ { print $5 }') | grep "inet" | head -n 1 | awk '/inet/ {print $2}' | cut -d'/' -f1) - - -download_url="https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/stable-virtio/virtio-win.iso" -if curl -m 3 -s --head --request GET ${download_url} | grep "HTTP/2 200" > /dev/null; then - while redirect_url=$( curl -I -s -S -f -w "%{redirect_url}\\n" -o /dev/null "${download_url}" ); do - VIRTIO_DOWNLOAD_URL=${download_url}; url=${redirect_url}; [[ -z "$url" ]] && break - done +default_interface="$(ip route 2>/dev/null | awk '/^default/ { print $5; exit }')" +if [[ -n "$default_interface" ]]; then + RNIP="$(ip -4 -o addr show dev "$default_interface" scope global 2>/dev/null | awk '{ sub(/\\/.*/, "", $4); print $4; exit }')" else - VIRTIO_DOWNLOAD_URL="https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/archive-virtio/virtio-win-0.1.285-1/virtio-win-0.1.285.iso" + RNIP="" fi -VIRTIO_FILE=${VIRTIO_DOWNLOAD_URL##*/} -[ -d /mnt/pve/PVE-Shared-Storage/template/iso ] && DLDIR=/mnt/pve/PVE-Shared-Storage/template/iso || DLDIR=/var/lib/vz/template/iso +VIRTIO_STABLE_URL="https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/stable-virtio/virtio-win.iso" +VIRTIO_FALLBACK_URL="https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/archive-virtio/virtio-win-0.1.285-1/virtio-win-0.1.285.iso" +VIRTIO_DOWNLOAD_URL="$(curl --location --fail --silent --show-error --head \ + --connect-timeout 3 --max-time 10 --output /dev/null \ + --write-out '%{url_effective}' "$VIRTIO_STABLE_URL" 2>/dev/null)" + +if [[ -z "$VIRTIO_DOWNLOAD_URL" ]]; then + VIRTIO_DOWNLOAD_URL="$VIRTIO_FALLBACK_URL" +fi +VIRTIO_FILE="${VIRTIO_DOWNLOAD_URL##*/}" + +S1_VERSION='26_1_1_31' +S1_PACKAGE="SentinelAgent_linux_x86_64_v${S1_VERSION}.deb" +S1_DOWNLOAD_URL="https://git.scity.us/TAI/files/raw/branch/main/${S1_PACKAGE}" + +if [[ -d /mnt/pve/PVE-Shared-Storage/template/iso ]]; then + DLDIR='/mnt/pve/PVE-Shared-Storage/template/iso' +else + DLDIR='/var/lib/vz/template/iso' +fi @@ -32,4 +44,3 @@ VIRTIO_FILE=${VIRTIO_DOWNLOAD_URL##*/} # apt-get update # fi - diff --git a/proxmenu-scripts.sh b/proxmenu-scripts.sh index d8bfca4..850c682 100755 --- a/proxmenu-scripts.sh +++ b/proxmenu-scripts.sh @@ -2,16 +2,24 @@ # TA-Proxmenu - Proxmox Setup Scripts for TA Use -[ "${2}" != "q" ] && source /opt/idssys/defaults/colors.inc +[ "${2:-}" != "q" ] && source /opt/idssys/defaults/colors.inc source /opt/idssys/defaults/default.inc source /opt/idssys/ta-proxmenu/defaults.inc +ACTION_REQUESTED=0 +[[ -n "${action:-}" ]] && ACTION_REQUESTED=1 + +FINISH_ACTION() { + (( ACTION_REQUESTED == 1 )) && exit 0 + ENTER2CONTINUE +} + INSTALL_PULSE() { echo bash <(curl -fsSL https://github.com/rcourtman/Pulse/releases/latest/download/install.sh) echo echo -e "\n${idsCL[Green]}Pulse has been installed${idsCL[Default]}" - [ ${action-x} ] && exit 0 || ENTER2CONTINUE + FINISH_ACTION } INSTALL_ACRONIS() { @@ -20,14 +28,14 @@ INSTALL_ACRONIS() { [Nn]) MAIN_MENU;; * ) echo - cd /tmp + cd /tmp || return 1 wget "https://us5-cloud.acronis.com/bc/api/ams/links/agents/redirect?language=multi&channel=CURRENT&system=linux&architecture=64&productType=enterprise&login=010180ae-63c4-4495-bed0-4ec934c25af9&white_labeled=0" -O ./acronisinstall chmod +x ./acronisinstall ./acronisinstall rm -f ./acronisinstall echo echo -e "\n${idsCL[Green]}Acronis has been installed${idsCL[Default]}" - [ ${action-x} ] && exit 0 || ENTER2CONTINUE + FINISH_ACTION ;; esac } @@ -42,14 +50,13 @@ INSTALL_PROXMENUX() { # systemctl disable --now proxmenux-monitor menu # echo -e "\n${idsCL[Green]}ProxMenux has been installed${idsCL[Default]}" -# [ ${action-x} ] && exit 0 || ENTER2CONTINUE # esac } PROXMENUX_POST_INSTALL() { PMFLDR='/usr/local/share/proxmenux/scripts/post_install' - [ ! -f ${PMFLDR}/customizable_post_install.sh ] && INSTALL_PROXMENUX - bash ${PMFLDR}/customizable_post_install.sh + [ ! -f "${PMFLDR}/customizable_post_install.sh" ] && INSTALL_PROXMENUX + bash "${PMFLDR}/customizable_post_install.sh" touch /opt/.PROXMENUX_POST_INSTALL [ -s /etc/apt/sources.list ] && cat /dev/null > /etc/apt/sources.list @@ -64,7 +71,7 @@ INSTALL_GLANCES() { echo apt install glances -y echo -e "\n${idsCL[Green]}Glances has been installed${idsCL[Default]}" - [ ${action-x} ] && exit 0 || ENTER2CONTINUE + FINISH_ACTION esac } @@ -75,7 +82,8 @@ INSTALL_SCREENCONNECT() { * ) echo echo -en "\n${idsCL[LightYellow]}Paste the URL provided from the Build Installer: ${idsCL[Default]}" - read -e SCURL + read -r -e SCURL + [[ -n "$SCURL" ]] || { echo "No URL supplied."; FINISH_ACTION; return; } wget "${SCURL}" -O /tmp/scinstall dpkg -i /tmp/scinstall apt install --fix-broken -y @@ -84,7 +92,7 @@ INSTALL_SCREENCONNECT() { rm -f /tmp/scinstall systemctl disable --now proxmenux-monitor echo -e "\n${idsCL[Green]}ScreenConnect has been installed${idsCL[Default]}" - [ ${action-x} ] && exit 0 || ENTER2CONTINUE + FINISH_ACTION esac } @@ -96,32 +104,41 @@ INSTALL_RMM() { echo echo -en "\n${idsCL[LightYellow]}Paste the Linux Server URL provided from the Download Agent screen: ${idsCL[Default]}" - read -e RMMURL + read -r -e RMMURL + [[ -n "$RMMURL" ]] || { echo "No URL supplied."; FINISH_ACTION; return; } wget "${RMMURL}" -O /tmp/rmminstall - TOKEN="$(echo ${RMMURL} | awk -F 'TKN' '{print $2}' | awk -F '/RUN' '{print $1}')" - CMD="TOKEN=${TOKEN} bash /tmp/rmminstall" - eval ${CMD} + if [[ "$RMMURL" != *TKN* || "$RMMURL" != */RUN* ]]; then + echo "Unable to extract the RMM token from the URL." + FINISH_ACTION + return + fi + TOKEN="${RMMURL#*TKN}" + TOKEN="${TOKEN%%/RUN*}" + [[ -n "$TOKEN" ]] || { echo "The RMM token is empty."; FINISH_ACTION; return; } + TOKEN="$TOKEN" bash /tmp/rmminstall systemctl restart ITSPlatform # rm -f /tmp/rmminstall echo -e "\n${idsCL[Green]}RMM has been installed${idsCL[Default]}" - [ ${action-x} ] && exit 0 || ENTER2CONTINUE + FINISH_ACTION esac } INSTALL_S1() { echo echo -en "${idsCL[LightYellow]}Paste the customers SentinelOne Site Token: ${idsCL[Default]}" - read -e s1token - cd /tmp - wget "https://git.scity.us/TAI/files/raw/branch/main/SentinelAgent_linux_x86_64_v26_1_1_31.deb" - dpkg -i ./SentinelAgent_linux_x86_64*.deb - /opt/sentinelone/bin/sentinelctl management token set ${s1token} + read -r -e s1token + [[ -n "$s1token" ]] || { echo "No SentinelOne site token supplied."; FINISH_ACTION; return; } + cd /tmp || return 1 + rm -f "/tmp/${S1_PACKAGE}" + wget "$S1_DOWNLOAD_URL" -O "/tmp/${S1_PACKAGE}" + dpkg -i "/tmp/${S1_PACKAGE}" + /opt/sentinelone/bin/sentinelctl management token set "$s1token" /opt/sentinelone/bin/sentinelctl control start - rm -f ./SentinelAgent_linux_x86_64*.deb + rm -f "/tmp/${S1_PACKAGE}" echo -e "\n${idsCL[Green]}SentinelOne Agent has been installed. Make sure its added to a \"DETECT ONLY\" policy${idsCL[Default]}" - [ ${action-x} ] && exit 0 || ENTER2CONTINUE + FINISH_ACTION } INSTALL_OMSA() { @@ -130,8 +147,8 @@ INSTALL_OMSA() { [Nn]) echo;; * ) echo - mkdir /tmp/omsa - cd /tmp/omsa + mkdir -p /tmp/omsa + cd /tmp/omsa || return 1 apt install -y gnupg libcurl4t64 libncurses6 libxslt1.1 libgpm2 libtinfo6 mkdir -p /etc/apt/keyrings wget -qO - https://linux.dell.com/repo/pgp_pubkeys/0x1285491434D8786F.asc | gpg --dearmor -o /etc/apt/keyrings/linux.dell.com.gpg @@ -165,25 +182,25 @@ INSTALL_OMSA() { dpkg -i libssl1.1_1.1.1w-0+deb11u1_amd64.deb apt install -y srvadmin-all /opt/dell/srvadmin/sbin/srvadmin-services.sh start - rm -Rf /tmp/omsa + rm -rf -- /tmp/omsa echo -e "\n${idsCL[Green]}Dell OMSA has been installed${idsCL[Default]}" echo -e "\n${idsCL[LightCyan]}Available at: ${idsCL[LightGreen]}https://${RNIP}:1311${idsCL[Default]}" - [ ${action-x} ] && exit 0 || ENTER2CONTINUE + FINISH_ACTION esac } DOWNLOAD_VIRTIO() { echo -e "\n${idsCL[LightCyan]}Current \"Stable\" version available for download: ${idsCL[White]}${VIRTIO_FILE}${idsCL[Default]}" - if [ -f ${dldir}/${VIRTIO_FILE} ]; then + if [ -f "${DLDIR}/${VIRTIO_FILE}" ]; then echo -en "\n${idsCL[LightRed]}Removing existing download ... " - rm -f ${DLDIR}/${VIRTIO_FILE} + rm -f "${DLDIR}/${VIRTIO_FILE}" echo -e "${idsCL[Red]}Done${idsCL[Default]}" fi - wget -q -F -P ${DLDIR} ${VIRTIO_DOWNLOAD_URL} & + wget -q -P "$DLDIR" "$VIRTIO_DOWNLOAD_URL" & echo -e "\n${idsCL[LightCyan]}Downloading will continue in the background\n" - [ ${action-x} ] && exit 0 || ENTER2CONTINUE + FINISH_ACTION } DETECT_CPU(){ @@ -211,7 +228,7 @@ DETECT_CPU(){ sed -i "/cpu:/c cpu: $(proxclmc --list-only)" /etc/pve/nodes/*/qemu-server/*.conf echo echo -e "\n${idsCL[Green]}All VM's have been reconfigured\n${idsCL[LightCyan]}This will require the VM's to be powered off and then turned back on in order to take effect${idsCL[Default]}" - [ ${action-x} ] && exit 0 || ENTER2CONTINUE + FINISH_ACTION ;; *) echo;; esac @@ -233,7 +250,7 @@ RESTART_PVE_SERVICES(){ systemctl restart pve-cluster pvedaemon pvestatd pveproxy echo -e "${idsCL[Green]}Done${idsCL[Default]}" echo -e "\n${idsCL[Green]}This hosts Proxmox services have been restarted${idsCL[Default]}\n" - [ ${action-x} ] && exit 0 || ENTER2CONTINUE + FINISH_ACTION ;; esac } @@ -250,7 +267,7 @@ SET_VM_SHUTDOWNTIMEOUT(){ *) echo "Updating all VM's shutdown timeout to 180 seconds..." sed -E -i 's/(down=)[0-9]+/\1180/g' /etc/pve/nodes/*/qemu-server/*.conf - [ ${action-x} ] && exit 0 || ENTER2CONTINUE + FINISH_ACTION ;; esac } @@ -272,7 +289,7 @@ MAINTENANCE_MODE(){ ha-manager crm-command node-maintenance enable $(hostname) & echo -e "\n${idsCL[Green]}This host will be entered into maintenance mode${idsCL[Default]}\n" fi - [ ${action-x} ] && exit 0 || ENTER2CONTINUE + FINISH_ACTION ;; esac } @@ -284,10 +301,10 @@ INSTALL_KEEPALIVE() { * ) echo - source /opt/idssys/ta-proxmenu/inc/deploy-proxmox-keepalived.sh + bash /opt/idssys/ta-proxmenu/inc/deploy-proxmox-keepalived.sh echo -e "\n${idsCL[Green]}Keepalive has been installed${idsCL[Default]}" - [ ${action-x} ] && exit 0 || ENTER2CONTINUE + FINISH_ACTION esac } @@ -311,16 +328,16 @@ MAIN_MENU() { echo echo -en "${idsCL[White]} [${idsCL[LightYellow]}0${idsCL[Default]}] ${idsCL[White]}Run Post-Install Script${idsCL[Default]}" - [ -f /opt/.PROXMENUX_POST_INSTALL ] && echo -e "${idsCL[Cyan]} - Has been ran prevously${idsCL[Default]}" || echo + [ -f /opt/.PROXMENUX_POST_INSTALL ] && echo -e "${idsCL[Cyan]} - Has been run previously${idsCL[Default]}" || echo echo -e "${idsCL[White]} [${idsCL[LightYellow]}1${idsCL[Default]}] ${idsCL[White]}Detect CPU-Arch for Live Migrations${idsCL[Default]}" - if ! echo ${CRES} | grep -i pulse &> /dev/null ; then + if ! grep -qi pulse <<< "$CRES"; then echo -e "${idsCL[White]} [${idsCL[LightYellow]}2${idsCL[Default]}] ${idsCL[White]}Install Pulse Monitoring${idsCL[Default]}" else echo -e "${idsCL[DarkGray]} [2] Pulse Monitoring is already installed${idsCL[Default]}" fi - if [ -f ${DLDIR}/${VIRTIO_FILE} ]; then + if [ -f "${DLDIR}/${VIRTIO_FILE}" ]; then echo -e "${idsCL[DarkGray]} [3] Current VirtIO drivers already downloaded to 'local' on this host${idsCL[Default]}" - elif [ -f ${DLDIR}/virtio*.iso ]; then + elif compgen -G "${DLDIR}/virtio*.iso" > /dev/null; then echo -e "${idsCL[White]} [${idsCL[LightYellow]}3${idsCL[Default]}] ${idsCL[LightGreen]}**${idsCL[White]}Download the available updated Win-VirtIO drivers to 'local' on this host${idsCL[Default]}" else echo -e "${idsCL[White]} [${idsCL[LightYellow]}3${idsCL[Default]}] ${idsCL[White]}Download the current Win-VirtIO drivers to 'local' on this host${idsCL[Default]}" @@ -330,7 +347,7 @@ MAIN_MENU() { else echo -e "${idsCL[DarkGray]} [4] Glances is already installed${idsCL[Default]}" fi - if [ "$(echo ${DPL} | awk '/srvadmin-all/ {print }'|wc -l)" -eq 0 ]; then + if ! grep -q 'srvadmin-all' <<< "$DPL"; then echo -e "${idsCL[White]} [${idsCL[LightYellow]}5${idsCL[Default]}] ${idsCL[White]}Install Dell OpenManage Server Administrator${idsCL[Default]}" else echo -e "${idsCL[DarkGray]} [5] Dell OMSA is already installed - ${idsCL[Cyan]}https://${RNIP}:1311" @@ -341,13 +358,13 @@ MAIN_MENU() { else echo -e "${idsCL[DarkGray]} [6] ConnectWise RMM Agent is already installed${idsCL[Default]}" fi - if [ "$(echo ${DPL} | awk '/cyberprotect/ {print }'|wc -l)" -eq 0 ]; then + if ! grep -q 'cyberprotect' <<< "$DPL"; then echo -e "${idsCL[White]} [${idsCL[LightYellow]}7${idsCL[Default]}] ${idsCL[White]}Install Acronis Backup Agent${idsCL[Default]}" else echo -e "${idsCL[DarkGray]} [7] Acronis Backup is already installed${idsCL[Default]}" fi - if [ "$(echo ${DPL} | awk '/sentinelagent/ {print }'|wc -l)" -eq 0 ]; then - echo -e "${idsCL[White]} [${idsCL[LightYellow]}8${idsCL[Default]}] ${idsCL[White]}Install SentinelOne Agent (v25_4_2_21)${idsCL[Default]}" + if ! grep -q 'sentinelagent' <<< "$DPL"; then + echo -e "${idsCL[White]} [${idsCL[LightYellow]}8${idsCL[Default]}] ${idsCL[White]}Install SentinelOne Agent (v${S1_VERSION//_/.})${idsCL[Default]}" else echo -e "${idsCL[DarkGray]} [8] SentinelOne is already installed${idsCL[Default]}" fi @@ -389,14 +406,14 @@ MAIN_MENU() { [Rr]) RESTART_PVE_SERVICES;; [Kk]) INSTALL_KEEPALIVE;; [Qq]) EXIT1; exit 0;; - *) echo -e "Thats an invaild option,\nplease select a valid option only."; sleep 1;; + *) echo -e "That's an invalid option.\nPlease select a valid option."; sleep 1;; esac done } -if [ ${action-x} ]; then - case $action in +if (( ACTION_REQUESTED == 1 )); then + case "$action" in pulse) INSTALL_PULSE;; rmm) INSTALL_RMM;; omsa) INSTALL_OMSA;; @@ -404,10 +421,10 @@ if [ ${action-x} ]; then acronis) INSTALL_ACRONIS;; proxmenux) [ ! -f /usr/local/bin/menu ] && INSTALL_PROXMENUX || /usr/local/bin/menu;; screenconnect) INSTALL_SCREENCONNECT;; - restart) RESTART_PVE_SERVICES ${2};; + restart) RESTART_PVE_SERVICES "${2:-}";; cpu) DETECT_CPU;; mm) MAINTENANCE_MODE;; - timeout) SET_VM_SHUTDOWNTIMEOUT ${2};; + timeout) SET_VM_SHUTDOWNTIMEOUT "${2:-}";; *) MAIN_MENU;; esac else @@ -416,7 +433,3 @@ fi exit 0 - - - - diff --git a/run.sh b/run.sh index d61597d..1a884b2 100755 --- a/run.sh +++ b/run.sh @@ -1,11 +1,11 @@ #!/usr/bin/env bash # TA-Proxmenu preloader -[ "${2}" != "q" ] && source /opt/idssys/defaults/colors.inc +[ "${2:-}" != "q" ] && source /opt/idssys/defaults/colors.inc source /opt/idssys/defaults/default.inc source /opt/idssys/ta-proxmenu/defaults.inc -if [[ "${noupdate}" != *" ${1} "* ]] && [[ "${noupdate}" != *" ${2} "* ]]; then +if [[ "${noupdate}" != *" ${1:-} "* ]] && [[ "${noupdate}" != *" ${2:-} "* ]]; then if curl -m 3 -s --head --request GET https://git.scity.us | grep "HTTP/2 200" > /dev/null; then if [ "${1}" != "tapm" ]; then echo -en "${idsCL[LightCyan]}Checking for updates...${idsCL[Default]}" @@ -18,7 +18,7 @@ if [[ "${noupdate}" != *" ${1} "* ]] && [[ "${noupdate}" != *" ${2} "* ]]; then git clone https://git.scity.us/voltron/iDS-Defaults.git /opt/idssys/defaults else cd /opt/idssys/defaults - if [ "`git log --pretty=%H ...refs/heads/master^ | head -n 1`" != "`git ls-remote origin -h refs/heads/master |cut -f1`" ]; then + if [ "$(git rev-parse HEAD)" != "$(git ls-remote origin refs/heads/master | cut -f1)" ]; then if [ "${1}" != "tapm" ]; then echo -en "\e[1A"; echo -en "\e[0K\r${idsCL[LightCyan]}Updating iDSSYS-Defaults...${idsCL[Default]}" @@ -36,7 +36,7 @@ if [[ "${noupdate}" != *" ${1} "* ]] && [[ "${noupdate}" != *" ${2} "* ]]; then fi cd /opt/idssys/ta-proxmenu - if [ "`git log --pretty=%H ...refs/heads/main^ | head -n 1`" != "`git ls-remote origin -h refs/heads/main |cut -f1`" ]; then + if [ "$(git rev-parse HEAD)" != "$(git ls-remote origin refs/heads/main | cut -f1)" ]; then if [ "${1}" != "tapm" ]; then [ ${udtd} -eq 0 ] && echo -en "\e[1A"; echo -en "\e[0K\r${idsCL[LightCyan]}Updating TA-Proxmenu...${idsCL[Default]}" @@ -64,8 +64,7 @@ if [[ "${noupdate}" != *" ${1} "* ]] && [[ "${noupdate}" != *" ${2} "* ]]; then fi if [ "${1}" != "tapm" ] && [ "${1}" != "update" ] && [ "${1}" != "u" ]; then - /opt/idssys/ta-proxmenu/proxmenu-scripts.sh $1 $2 $3 $4 + /opt/idssys/ta-proxmenu/proxmenu-scripts.sh "${1:-}" "${2:-}" "${3:-}" "${4:-}" fi exit 0 -