Computer and IT knowledge - things to know - All
#!/usr/bin/env bash
# =============================================================================
# aruba_cx_poe_bounce.sh
#
# Bounces (or tests) PoE on a single interface of an Aruba CX switch via
# the AOS-CX REST API (v10.09+, CSRF-token auth).
#
# Usage:
# ./aruba_cx_poe_bounce.sh # no args: print usage and exit
# ./aruba_cx_poe_bounce.sh --exec # disable PoE, wait, re-enable PoE
# ./aruba_cx_poe_bounce.sh --test # read-only: print current PoE state
# ./aruba_cx_poe_bounce.sh --enable-poe # enable PoE only if currently disabled
#
# Requires: curl, python3 (URL-encoding interface name), jq (optional, pretty output)
#
# Config below: set SWITCH, USER, PASS, IFACE, WAIT_SECONDS before running.
#
# Version
# 2026-08-04 mw initial version
# =============================================================================
set -euo pipefail
# --- Config ---
SWITCH="192.168.1.1"
API_VER="v10.12" # verify: curl -k https://$SWITCH/rest/
USER="admin"
PASS='changeme' # single-quote if it contains $ or other shell-special chars
IFACE="1/1/1" # switch port to bounce PoE on
WAIT_SECONDS=10 # global timer between disable and enable
TEST_MODE=false
EXEC_MODE=false
ENABLE_MODE=false
print_usage() {
cat <<USAGE
Usage: $0 [--exec] [--test] [--enable-poe]
--exec Run the PoE bounce: disable PoE, wait ${WAIT_SECONDS}s, re-enable PoE
--test Read-only: print current PoE state, no changes made
--enable-poe Check current PoE state; enable it only if currently disabled
No arguments prints this usage and exits.
USAGE
}
if [[ $# -eq 0 ]]; then
print_usage
exit 0
fi
while [[ $# -gt 0 ]]; do
case "$1" in
--test) TEST_MODE=true; shift ;;
--exec) EXEC_MODE=true; shift ;;
--enable-poe) ENABLE_MODE=true; shift ;;
-h|--help) print_usage; exit 0 ;;
*) echo "Unknown argument: $1" >&2; print_usage; exit 1 ;;
esac
done
if [[ "$TEST_MODE" == false && "$EXEC_MODE" == false && "$ENABLE_MODE" == false ]]; then
echo "Error: specify --exec, --test, or --enable-poe." >&2
print_usage
exit 1
fi
BASE="https://${SWITCH}/rest/${API_VER}"
COOKIE_JAR=$(mktemp)
LOGIN_HEADERS=$(mktemp)
CSRF_TOKEN=""
# --- Logging ---
log() {
printf '[%s] %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$1"
}
cleanup() {
log "Logging out"
curl -sk -b "$COOKIE_JAR" -H "x-csrf-token: ${CSRF_TOKEN}" -X POST "${BASE}/logout" >/dev/null || true
rm -f "$COOKIE_JAR" "$LOGIN_HEADERS"
}
trap cleanup EXIT
encode_iface() {
python3 -c "import urllib.parse,sys; print(urllib.parse.quote(sys.argv[1], safe=''))" "$1"
}
get_poe_status() {
local enc
enc=$(encode_iface "$IFACE")
local http_code
http_code=$(curl -sk -o /tmp/poe_status.json -w '%{http_code}' \
-b "$COOKIE_JAR" -H "x-csrf-token: ${CSRF_TOKEN}" \
"${BASE}/system/interfaces/${enc}/poe_interface")
if [[ "$http_code" -ge 200 && "$http_code" -lt 300 ]]; then
log "PoE status on ${IFACE} -> HTTP ${http_code} OK"
if command -v jq >/dev/null 2>&1; then
jq . /tmp/poe_status.json
else
cat /tmp/poe_status.json
fi
else
log "PoE status query on ${IFACE} -> HTTP ${http_code} FAILED: $(cat /tmp/poe_status.json)"
exit 1
fi
}
get_poe_admin_disable() {
local enc
enc=$(encode_iface "$IFACE")
local http_code
http_code=$(curl -sk -o /tmp/poe_query.json -w '%{http_code}' \
-b "$COOKIE_JAR" -H "x-csrf-token: ${CSRF_TOKEN}" \
"${BASE}/system/interfaces/${enc}/poe_interface")
if [[ "$http_code" -lt 200 || "$http_code" -ge 300 ]]; then
log "PoE status query on ${IFACE} -> HTTP ${http_code} FAILED: $(cat /tmp/poe_query.json)"
exit 1
fi
python3 -c "
import json
with open('/tmp/poe_query.json') as f:
data = json.load(f)
print(json.dumps(data.get('config', {}).get('admin_disable', None)))
"
}
set_poe() {
local state="$1" # true = disable, false = enable
local enc
enc=$(encode_iface "$IFACE")
local http_code
http_code=$(curl -sk -o /tmp/poe_resp.json -w '%{http_code}' \
-b "$COOKIE_JAR" -X PATCH \
-H "Content-Type: application/json" \
-H "x-csrf-token: ${CSRF_TOKEN}" \
-d "{\"config\":{\"admin_disable\":${state}}}" \
"${BASE}/system/interfaces/${enc}/poe_interface")
if [[ "$http_code" -ge 200 && "$http_code" -lt 300 ]]; then
log "PoE admin_disable=${state} on ${IFACE} -> HTTP ${http_code} OK"
else
log "PoE admin_disable=${state} on ${IFACE} -> HTTP ${http_code} FAILED: $(cat /tmp/poe_resp.json)"
exit 1
fi
}
# --- Login ---
log "Logging in to ${SWITCH}"
login_code=$(curl -sk -D "$LOGIN_HEADERS" -c "$COOKIE_JAR" -o /dev/null -w '%{http_code}' -X POST \
-H "x-use-csrf-token: true" \
-d "username=${USER}&password=${PASS}" \
"${BASE}/login")
if [[ "$login_code" -ge 200 && "$login_code" -lt 300 ]]; then
log "Login OK (HTTP ${login_code})"
else
log "Login FAILED (HTTP ${login_code})"
exit 1
fi
CSRF_TOKEN=$(grep -i '^x-csrf-token:' "$LOGIN_HEADERS" | tr -d '\r' | awk -F': ' '{print $2}')
if [[ -z "$CSRF_TOKEN" ]]; then
log "WARNING: no x-csrf-token header found in login response - firmware may not require it, or login flow changed"
else
log "CSRF token acquired"
fi
if [[ "$TEST_MODE" == true ]]; then
# --- Test mode: read-only, no config change ---
log "TEST MODE: reading current PoE state on ${IFACE}"
get_poe_status
log "Done (test mode, no changes made)"
elif [[ "$ENABLE_MODE" == true ]]; then
# --- Enable-if-disabled mode ---
log "ENABLE MODE: checking current PoE state on ${IFACE}"
admin_disable=$(get_poe_admin_disable)
case "$admin_disable" in
true)
log "PoE currently disabled on ${IFACE} - enabling"
set_poe false
;;
false)
log "PoE already enabled on ${IFACE} - no action needed"
;;
*)
log "Could not determine current PoE state (value: ${admin_disable}) - aborting"
exit 1
;;
esac
log "Done"
else
# --- Bounce PoE ---
log "Disabling PoE on ${IFACE}"
set_poe true
log "Waiting ${WAIT_SECONDS}s"
sleep "$WAIT_SECONDS"
log "Enabling PoE on ${IFACE}"
set_poe false
log "Done"
fi computer2know :: thank you for your visit :: have a nice day :: © 2026