usb device management
windows
It interactively scans your Windows USB host bus, lists the available devices, lets you choose one, then bind the device to wsl.
param(
[string]$Distro = "" # WSL distro name; empty = default distro
)
Write-Host "====================================================" -ForegroundColor Cyan
Write-Host " INTERACTIVE WINDOWS TO WSL USB BIND MANAGER"
Write-Host "====================================================" -ForegroundColor Cyan
if (-not (Get-Command usbipd -ErrorAction SilentlyContinue)) {
Write-Error "usbipd not found. Install it with: winget install usbipd"
exit 1
}
# 1. Fetch connected devices (lines that start with a BUSID such as 2-3).
# Stop at the 'Persisted' section so stale entries are not listed.
$devices = @()
foreach ($line in (usbipd list)) {
if ($line -match '^Persisted') { break }
if ($line -match '^\d+-\d+\s') { $devices += $line.TrimEnd() }
}
if ($devices.Count -eq 0) {
Write-Error "No USB devices detected or usbipd service is down."
exit 1
}
# 2. Interactive selection menu
Write-Host "`nSelect the target USB device to attach to WSL:"
Write-Host "----------------------------------------------------"
for ($i = 0; $i -lt $devices.Count; $i++) {
Write-Host (" [{0}] {1}" -f ($i + 1), $devices[$i])
}
Write-Host "----------------------------------------------------"
$choice = 0
while ($choice -lt 1 -or $choice -gt $devices.Count) {
$inputVal = Read-Host "Enter choice (1-$($devices.Count))"
if ($inputVal -match '^[0-9]+$') {
$choice = [int]$inputVal
}
}
# 3. Parse BUSID
$selectedDevice = $devices[$choice - 1]
$busId = ($selectedDevice.Trim() -split '\s+')[0]
Write-Host "`nSelected BUSID: [$busId]" -ForegroundColor Green
# 4. Bind (once, needs admin) and attach
$distroArg = if ($Distro) { "--distribution $Distro" } else { "" }
if ($selectedDevice -match "Attached") {
Write-Host "Device is already attached to a WSL instance." -ForegroundColor Yellow
} else {
if ($selectedDevice -match "Not shared") {
Write-Host "Binding device... (accept the admin UAC prompt)"
Start-Process usbipd -ArgumentList "bind --busid $busId" -Verb RunAs -Wait
}
Write-Host "Attaching USB device to WSL..."
# attach does not need admin once the device is bound
usbipd attach --wsl $Distro --busid $busId 2>&1 | Out-Host
if ($LASTEXITCODE -ne 0) {
Write-Host "Attach failed (see message above)." -ForegroundColor Red
exit 1
}
}
# Done. Inside WSL run: lsusb ; ls /dev/ttyACM*
Write-Host "`nDone. In WSL run: lsusb ; ls /dev/ttyACM*" -ForegroundColor Green
Write-Host "===================================================="
ubuntu
Here is an updated, interactive version of the script. It scans the system for all connected USB devices, presents them in a numbered menu for you to select, and prompts you to enter your preferred custom name for the /dev/ symlink.
#!/usr/bin/env bash
# Exit on unexpected script errors
set -e
echo "===================================================="
echo " 🔮 INTERACTIVE USB DEVLINK GENERATOR"
echo "===================================================="
sudo usermod -a -G dialout $USER
# 1. Gather all USB devices with readable indexes
echo "Scanning USB bus..."
mapfile -t USB_DEVICES < <(lsusb | grep -v "root hub")
if [ ${#USB_DEVICES[@]} -eq 0 ]; then
echo "❌ No external USB devices found. Is your device attached to WSL?"
exit 1
fi
# 2. Present interactive selection menu
echo -e "\nSelect the target USB device:"
echo "----------------------------------------------------"
for i in "${!USB_DEVICES[@]}"; do
echo " [$((i+1))] ${USB_DEVICES[$i]}"
done
echo "----------------------------------------------------"
while true; do
read -rp "Enter choice (1-${#USB_DEVICES[@]}): " CHOICE
if [[ "$CHOICE" =~ ^[0-9]+$ ]] && [ "$CHOICE" -ge 1 ] && [ "$CHOICE" -le "${#USB_DEVICES[@]}" ]; then
SELECTED_DEVICE="${USB_DEVICES[$((CHOICE-1))]}"
break
else
echo "Invalid choice. Please pick a number from the menu."
fi
done
echo -e "\nYou selected: $SELECTED_DEVICE"
# 3. Parse selected device IDs
VID_PID=$(echo "$SELECTED_DEVICE" | awk '{print $6}')
VID=$(echo "$VID_PID" | cut -d':' -f1)
PID=$(echo "$VID_PID" | cut -d':' -f2)
# 4. Prompt for custom device symlink name
echo -e "\n===================================================="
echo " STEP 2: Choose Target Symlink Name"
echo "===================================================="
read -rp "Enter desired dev name (e.g., u2can, my_motor, robot_arm): " CUSTOM_NAME
# Sanitize input (remove slashes or spaces)
CUSTOM_NAME=$(echo "$CUSTOM_NAME" | tr -cd '[:alnum:]_-')
if [ -z "$CUSTOM_NAME" ]; then
echo "Defaulting to 'u2can_device' due to empty/invalid string."
CUSTOM_NAME="u2can_device"
fi
TARGET_LINK="/dev/$CUSTOM_NAME"
echo "Your device will be linked at: $TARGET_LINK"
# 5. Generate and write the custom udev Rule
echo -e "\n===================================================="
echo " STEP 3: Writing Configuration Rules"
echo "===================================================="
RULE_FILE="/etc/udev/rules.d/99-interactive-usb.rules"
RULE_CONTENT="SUBSYSTEM==\"tty\", ATTRS{idVendor}==\"$VID\", ATTRS{idProduct}==\"$PID\", MODE=\"0666\", SYMLINK+=\"$CUSTOM_NAME\""
echo "Writing rule to $RULE_FILE..."
echo "$RULE_CONTENT" | sudo tee "$RULE_FILE" > /dev/null
# 6. Reload the hardware management engine
echo -e "\n===================================================="
echo " STEP 4: Reloading Systems Engine"
echo "===================================================="
sudo udevadm control --reload-rules
sudo udevadm trigger
echo "udev rule matrix refreshed successfully!"
# 7. Check for dynamic device assignment status
echo -e "\n===================================================="
echo " STEP 5: Validating Hardware Mapping Engine"
echo "===================================================="
# Scan for an active device matching the IDs to extract the current tty path
TTY_MATCH=$(udevadm trigger --verbose --dry-run --subsystem-match=tty --attr-match=idVendor="$VID" --attr-match=idProduct="$PID" 2>/dev/null | head -n 1 || true)
if [ -n "$TTY_MATCH" ]; then
NODE_NAME=$(basename "$TTY_MATCH")
echo "System assigned hardware node: /dev/$NODE_NAME"
echo "----------------------------------------------------"
sudo udevadm info --query=property --name="/dev/$NODE_NAME" | grep -E "ID_VENDOR_ID|ID_MODEL_ID|DEVNAME|DEVLINKS"
echo "----------------------------------------------------"
else
echo "ℹ️ Device successfully registered in rule matrix."
echo "If using WSL2, remember to detach and re-attach via Windows 'usbipd' to fully bind the custom link."
fi
echo "===================================================="