How to Manage USB Device Passthrough in Hyperion

Written By Sebastian Sime (Draft Writer)

Updated at December 4th, 2025

→ Applies to: Hyperion 9.x and above

 

Step 1. Connect to Hyperion appliance via SSH as admin

ssh admin@<your_ip_address_or_hostname>

 

Step 2. Become Super User

sudo su -

 

Step 3. Download the script in tmp directory

wget -P /tmp https://storage.googleapis.com/syneto_public_files/downloads/Syneto-Tools/USB/syneto-usbctl.sh

 

Step 4 (optional). If download fails, manually create and edit /tmp/syneto-usbctl.sh file

vi /tmp/syneto-usbctl.sh

IMPORTANT
Make sure to copy and paste the exact lines below.

#!/bin/bash

set -euo pipefail

if ! command -v lsusb &>/dev/null; then
    echo "Missing lsusb. Install with: sudo dnf install usbutils"
    exit 1
fi

if ! command -v virsh &>/dev/null; then
    echo "Missing virsh. Install libvirt."
    exit 1
fi

############################################################
# Select VM (ALL states)
############################################################
select_vm() {
    echo
    echo "=== ALL VMs ==="

    mapfile -t VM_LIST < <(virsh list --all --name | sed '/^$/d')

    if [[ ${#VM_LIST[@]} -eq 0 ]]; then
        echo "No VMs found."
        exit 1
    fi

    for i in "${!VM_LIST[@]}"; do
        state=$(virsh domstate "${VM_LIST[$i]}")
        printf "%2d) %-25s [%s]\n" "$((i+1))" "${VM_LIST[$i]}" "$state"
    done

    echo
    read -p "Select VM number: " n
    (( n>=1 && n<=${#VM_LIST[@]} )) || { echo "Invalid VM."; exit 1; }

    VM="${VM_LIST[$((n-1))]}"
    VM_STATE=$(virsh domstate "$VM")

    echo "Selected VM: $VM ($VM_STATE)"
}

############################################################
# Determine attach mode based on VM state
############################################################
attach_mode() {
    if [[ "$VM_STATE" == "running" ]]; then
        ATTACH_OPTS=(--live --persistent)
    else
        ATTACH_OPTS=(--persistent)
        echo "âš  VM is NOT running. USB will be attached persistently only."
    fi
}

############################################################
# ATTACH USB DEVICE
############################################################
attach_usb() {
    echo
    echo "=== USB DEVICES ON HOST ==="
    mapfile -t USB_LIST < <(lsusb)

    for i in "${!USB_LIST[@]}"; do
        printf "%2d) %s\n" "$((i+1))" "${USB_LIST[$i]}"
    done

    echo
    read -p "Select USB device number to ATTACH: " n
    (( n>=1 && n<=${#USB_LIST[@]} )) || { echo "Invalid selection."; exit 1; }

    line="${USB_LIST[$((n-1))]}"

    VID=$(echo "$line" | grep -oP "(?<=ID )[\da-fA-F]+(?=:)")
    PID=$(echo "$line" | grep -oP "(?<=:)[\da-fA-F]+(?= )")

    if [[ -z "$VID" || -z "$PID" ]]; then
        echo "❌ Could not parse VID:PID from:"
        echo "   $line"
        exit 1
    fi

    echo "Detected VID:PID → $VID:$PID"

    select_vm
    attach_mode

    echo
    echo "Attaching USB device $VID:$PID to $VM ..."

    virsh attach-device "$VM" "${ATTACH_OPTS[@]}" --file /dev/stdin <<EOF
<hostdev mode='subsystem' type='usb' managed='yes'>
  <source>
    <vendor id='0x$VID'/>
    <product id='0x$PID'/>
  </source>
</hostdev>
EOF

    echo "✔ Attached successfully."
}

############################################################
# DETACH USB DEVICE (EXACT PERSIST XML MATCHING)
############################################################
detach_usb() {

    select_vm

    echo
    echo "=== ATTACHED USB DEVICES ==="

    # Extract EXACT persistent XML blocks (no reconstruction)
    mapfile -d '' -t HOSTDEVS < <(
        virsh dumpxml --inactive "$VM" |
        awk '
            /<hostdev/ {
                inblock=1;
                block=$0;
                next;
            }
            inblock {
                block = block "\n" $0;
                if ($0 ~ /<\/hostdev>/) {
                    print block;
                    printf "%c", 0;    # NUL terminator for mapfile
                    inblock=0;
                    block="";
                }
            }
        '
    )

    if [[ ${#HOSTDEVS[@]} -eq 0 ]]; then
        echo "No hostdev devices attached in persistent XML."
        return
    fi

    # List devices
    for i in "${!HOSTDEVS[@]}"; do
        block="${HOSTDEVS[$i]}"

        VID=$(echo "$block" | sed -n "s/.*<vendor id='0x\([0-9a-fA-F]*\)'.*/\1/p")
        PID=$(echo "$block" | sed -n "s/.*<product id='0x\([0-9a-fA-F]*\)'.*/\1/p")

        echo "$((i+1))) USB Device ${VID:-unknown}:${PID:-unknown}"
    done

    echo
    read -p "Select hostdev number to DETACH: " n
    (( n>=1 && n<=${#HOSTDEVS[@]} )) || { echo "Invalid selection!"; exit 1; }

    REAL_XML="${HOSTDEVS[$((n-1))]}"

    echo
    echo "Detaching exact persistent XML block:"
    echo "--------------------------------"
    echo "$REAL_XML"
    echo "--------------------------------"

    # Detach persistent first (must succeed for attach symmetry)
    printf '%s\n' "$REAL_XML" | virsh detach-device "$VM" --persistent --file /dev/stdin || true

    # Detach live if VM is running
    if [[ "$VM_STATE" == "running" ]]; then
    printf '%s\n' "$REAL_XML" | virsh detach-device "$VM" --live --file /dev/stdin 2>/dev/null || true
    fi

    echo "✔ Detach operation completed."
}

############################################################
# MAIN MENU
############################################################
echo "==========================================="
echo "       Syneto USB Management Tool"
echo "==========================================="
echo "1) Attach USB device to VM"
echo "2) Detach USB device from VM"
echo "3) Exit"
echo "==========================================="
read -p "Select option: " choice

case "$choice" in
    1) attach_usb ;;
    2) detach_usb ;;
    3) echo "Bye."; exit 0 ;;
    *) echo "Invalid option"; exit 1 ;;
esac

Save and EXIT

:wq

 

Step 5. Give permissions to /tmp/syneto-usbctl.sh file

chmod +x /tmp/syneto-usbctl.sh

 

Step 6. Run the script

/tmp/syneto-usbctl.sh

EXAMPLE OUTPUT

===========================================
       Syneto USB Management Tool
===========================================
1) Attach USB device to VM
2) Detach USB device from VM
3) Exit
===========================================
Select option:

 

Step 7 (optional). Check that no errors occur

If you receive this error:

--2025-12-03 16:56:25--  https://storage.googleapis.com/syneto_public_files/downloads/Syneto-Tools/USB/syneto-usbctl.sh
Resolving storage.googleapis.com (storage.googleapis.com)... 142.251.208.123, 142.251.39.27, 142.251.38.219, ...
Connecting to storage.googleapis.com (storage.googleapis.com)|142.251.208.123|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 5370 (5.2K) [text/x-sh]
Saving to: ‘syneto-usbctl.sh.1’
syneto-usbctl.sh.1                                            100%[==============================================================================================================================================>]   5.24K  --.-KB/s    in 0s      
2025-12-03 16:56:25 (205 MB/s) - ‘syneto-usbctl.sh.1’ saved [5370/5370]
Missing lsusb. Install with: sudo dnf install usbutils


Install the usbutils package:

sudo dnf install usbutils

EXAMPLE

[root@syneto-os-f0330a82 admin]# sudo dnf install usbutils
syneto                                                                                                                                                                                                               4.4 MB/s | 2.1 MB     00:00    
Last metadata expiration check: 0:00:01 ago on Wed Dec  3 17:03:17 2025.
Dependencies resolved.
=====================================================================================================================================================================================================================================================
 Package                                                     Architecture                                              Version                                                       Repository                                                 Size
=====================================================================================================================================================================================================================================================
Installing:
 usbutils                                                    x86_64                                                    017-1.el9                                                     syneto                                                    115 k
Transaction Summary
=====================================================================================================================================================================================================================================================
Install  1 Package
Total download size: 115 k
Installed size: 382 k
Is this ok [y/N]: y

Press “y” to install the usbutils package

 

Step 8 (optional). In case of error occurred at Step 7, run the script again

/tmp/syneto-usbctl.sh

EXAMPLE OUTPUT

===========================================
       Syneto USB Management Tool
===========================================
1) Attach USB device to VM
2) Detach USB device from VM
3) Exit
===========================================
Select option:

 

Attach USB device to VM


Step 1. Select the number of the USB device to attach

EXAMPLE

Select option: 1
=== USB DEVICES ON HOST ===
 1) Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
 2) Bus 001 Device 002: ID 1604:10c0 Tascam Dell Integrated Hub
 3) Bus 001 Device 003: ID 1da0:55a7 Parade Technologies, Inc. USB2.0 Hub
 4) Bus 001 Device 004: ID 0463:ffff MGE UPS Systems UPS
 5) Bus 001 Device 005: ID 1604:10c0 Tascam Dell Integrated Hub
 6) Bus 001 Device 006: ID 1604:10c0 Tascam Dell Integrated Hub
 7) Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
 8) Bus 002 Device 002: ID 1da0:5507 Parade Technologies, Inc. USB3.0 Hub
 9) Bus 002 Device 003: ID 0951:1666 Kingston Technology DataTraveler 100 G3/G4/SE9 G2/50 Kyson
Select USB device number to ATTACH:

 

Step 2. Select the VM number to attach the USB device

EXAMPLE

=== ALL VMs ===
 1) Win2025T2                 [running]
 2) REC-TEST1                 [shut off]
 3) TEST2                     [shut off]
 4) ups-monitor               [shut off]
 5) Win2025T1                 [shut off]
Select VM number: 1
Selected VM: Win2025T2 (running)
Attaching USB device 0951:1666 to Win2025T2 ...
Device attached successfully
✔ Attached successfully.

 

Detach USB device from VM


Step 1. Select the number of the USB device to detach

EXAMPLE

Select option: 1
=== USB DEVICES ON HOST ===
 1) Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
 2) Bus 001 Device 002: ID 1604:10c0 Tascam Dell Integrated Hub
 3) Bus 001 Device 003: ID 1da0:55a7 Parade Technologies, Inc. USB2.0 Hub
 4) Bus 001 Device 004: ID 0463:ffff MGE UPS Systems UPS
 5) Bus 001 Device 005: ID 1604:10c0 Tascam Dell Integrated Hub
 6) Bus 001 Device 006: ID 1604:10c0 Tascam Dell Integrated Hub
 7) Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
 8) Bus 002 Device 002: ID 1da0:5507 Parade Technologies, Inc. USB3.0 Hub
 9) Bus 002 Device 003: ID 0951:1666 Kingston Technology DataTraveler 100 G3/G4/SE9 G2/50 Kyson
Select USB device number to DETACH:

 

Step 2. Select the VM number to detach the USB device

EXAMPLE

=== ALL VMs ===
 1) Win2025T2                 [running]
 2) REC-TEST1                 [shut off]
 3) TEST2                     [shut off]
 4) ups-monitor               [shut off]
 5) Win2025T1                 [shut off]
Select VM number: 1
Selected VM: Win2025T2 (running)
Detaching USB device 0951:1666 from Win2025T2 ...
Device detached successfully
✔ Detached successfully.

 

Video Example