How to Manage USB Device Passthrough in Hyperion

Written By Sebastian Sime (Draft Writer)

Updated at February 20th, 2026

→ 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. Power off the VM on which to attach the USB device

Step 2. 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 3. Select the VM number to attach the USB device

EXAMPLE

=== ALL VMs ===
 1) Win2025T2                 [shut off]
 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 (shut off)
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