#!/bin/sh
# ============================================================
# LogDiag OS Inspection Script - VMware ESXi
# Applies to : ESXi 6.5 / 6.7 / 7.0 / 8.0 (run inside ESXi Shell / SSH)
# Usage      : run as root ->  sh vmware-esxi-pm.sh [output-dir]
#              output-dir defaults to a datastore path when available,
#              otherwise /tmp (ramdisk, limited space).
# Output     : <output-dir>/<hostname>.<serial>.pm-<timestamp>.tgz
# Note       : read-only collection, no host configuration is changed.
#              For a full official support bundle use `vm-support` instead.
# ============================================================

HOSTNAME_STR=$(hostname 2>/dev/null || echo unknown)
SERIAL=$(esxcli hardware platform get 2>/dev/null | awk -F': ' '/Serial Number/{print $2; exit}' | tr -d ' /')
[ -z "$SERIAL" ] && SERIAL=NotAvailable
STAMP=$(date +%Y%m%d_%H%M%S)
DIRNAME="${HOSTNAME_STR}.${SERIAL}.pm-${STAMP}"

# Prefer a datastore for output: /tmp on ESXi is a small ramdisk.
BASEDIR="$1"
if [ -z "$BASEDIR" ]; then
    BASEDIR=$(ls -d /vmfs/volumes/*/ 2>/dev/null | head -1)
    [ -z "$BASEDIR" ] && BASEDIR=/tmp
fi
CFGDIR="${BASEDIR%/}/${DIRNAME}"
mkdir -p "$CFGDIR" || { echo "cannot create $CFGDIR"; exit 1; }

# run <outfile> <command line>
run() {
    OUT="$CFGDIR/$1"; shift
    mkdir -p "$(dirname "$OUT")"
    {
        echo "### $*"
        sh -c "$*" 2>&1 || echo "[command failed or not available]"
        echo ""
    } >> "$OUT"
}

echo "Collecting system information ..."
date > "$CFGDIR/date.log"
run system/version.log         "vmware -vl; esxcli system version get"
run system/hostname.log        "esxcli system hostname get"
run system/uptime.log          "uptime; esxcli system stats uptime get"
run system/boot.log            "esxcli system boot device get"
run system/time.log            "esxcli system time get; esxcli system ntp get"
run system/modules.log         "esxcli system module list | head -60"
run system/services.log        "chkconfig --list 2>/dev/null; /etc/init.d/hostd status; /etc/init.d/vpxa status"
run system/advanced-changed.log "esxcli system settings advanced list -d"

echo "Collecting hardware information ..."
run hardware/platform.log      "esxcli hardware platform get"
run hardware/cpu.log           "esxcli hardware cpu global get; esxcli hardware cpu list | head -80"
run hardware/memory.log        "esxcli hardware memory get"
run hardware/pci.log           "esxcli hardware pci list | head -400"
run hardware/bootdevice.log    "esxcli hardware bootdevice list"
run hardware/ipmi-sel.log      "esxcli hardware ipmi sel list 2>/dev/null | head -200"
run hardware/ipmi-sdr.log      "esxcli hardware ipmi sdr list 2>/dev/null | head -200"

echo "Collecting storage information ..."
run storage/adapters.log       "esxcli storage core adapter list"
run storage/devices.log        "esxcli storage core device list"
run storage/device-stats.log   "esxcli storage core device stats get | head -200"
run storage/paths.log          "esxcli storage core path list | head -300"
run storage/nmp.log            "esxcli storage nmp device list | head -200"
run storage/vmfs.log           "esxcli storage vmfs extent list; esxcli storage filesystem list"
run storage/df.log             "df -h"
run storage/scsidevs.log       "esxcfg-scsidevs -l 2>/dev/null | head -300"

echo "Collecting network information ..."
run network/nics.log           "esxcli network nic list"
run network/ip.log             "esxcli network ip interface list; esxcli network ip interface ipv4 get"
run network/vswitch.log        "esxcli network vswitch standard list; esxcli network vswitch dvs vmware list 2>/dev/null"
run network/route.log          "esxcli network ip route ipv4 list"
run network/dns.log            "esxcli network ip dns server list"
run network/firewall.log       "esxcli network firewall get"
for NIC in $(esxcli network nic list 2>/dev/null | awk 'NR>2 {print $1}'); do
    run "network/nic.${NIC}.log" "esxcli network nic get -n ${NIC}"
done

echo "Collecting virtual machine inventory ..."
run vms/vm-list.log            "vim-cmd vmsvc/getallvms"
run vms/vm-process.log         "esxcli vm process list"

echo "Collecting logs (tails) ..."
run logs/vmkernel.log          "tail -500 /var/log/vmkernel.log"
run logs/vmkwarning.log        "tail -200 /var/log/vmkwarning.log"
run logs/hostd.log             "tail -300 /var/log/hostd.log"
run logs/vobd.log              "tail -200 /var/log/vobd.log"
run logs/syslog.log            "tail -200 /var/log/syslog.log"

echo "Collecting performance snapshot ..."
run performance/esxtop.log     "esxtop -b -n 2 -d 5 2>/dev/null | head -20"
run performance/memstats.log   "memstats -r comp-stats 2>/dev/null | head -60"
run performance/psinfo.log     "ps -Tcjstv 2>/dev/null | head -80"

echo "Compressing inspection data ..."
cd "$BASEDIR" || exit 1
tar -czf "${DIRNAME}.tgz" "${DIRNAME}" && rm -rf "$CFGDIR"
echo "Inspection data saved to ${BASEDIR%/}/${DIRNAME}.tgz"
exit 0
