Programmatic USB Device Re-Mounting in Windows: Solutions for Remote Development Scenarios


3 views

During remote development sessions, physically reconnecting USB devices becomes impossible. Traditional solutions like unplugging/replugging don't work when accessing machines via RDP or SSH. Let's explore robust programmatic alternatives.

The most reliable native approach uses WMI to trigger device rediscovery:

// PowerShell script to trigger USB device rediscovery
$wmiQuery = "SELECT * FROM Win32_Volume WHERE DriveType=2"
$usbDevices = Get-WmiObject -Query $wmiQuery

foreach ($device in $usbDevices) {
    if ($device.DriveLetter) {
        Write-Host "Remounting drive $($device.DriveLetter)"
        $device.Dismount($false, $false)
        $device.Mount()
    }
}

Microsoft's command-line Device Console tool offers granular control:

@echo off
:: Scan for hardware changes
devcon.exe rescan
:: Alternatively, restart the USB controller
devcon.exe restart "USB\*"

For C++ developers, the USB Device Tree Viewer library provides direct access:

#include 
#include 

void RefreshUSBDevices() {
    DEVINST deviceID;
    CM_Locate_DevNode(&deviceID, NULL, CM_LOCATE_DEVNODE_NORMAL);
    CM_Reenumerate_DevNode(deviceID, CM_REENUMERATE_NORMAL);
}

When multiple devices share a hub, add selective removal logic:

// PowerShell selective removal by device instance ID
$targetDevice = Get-PnpDevice | Where-Object { 
    $_.FriendlyName -like "*YourDeviceName*" -and 
    $_.Status -eq "OK" 
}
$targetDevice | Disable-PnpDevice -Confirm:$false
Start-Sleep -Seconds 2
$targetDevice | Enable-PnpDevice -Confirm:$false

For enterprise environments, SafelyRemove's API provides robust control:

// C# example using SafelyRemove SDK
var controller = new SafelyRemoveController();
var devices = controller.GetConnectedDevices();
var target = devices.FirstOrDefault(d => d.Name.Contains("BackupHDD"));

if (target != null) {
    controller.SafelyRemove(target.Id);
    Thread.Sleep(1000);
    controller.ConnectDevice(target.PortId);
}
  • Always include error handling for device busy states
  • Implement retry logic with exponential backoff
  • Log all operations for debugging remote sessions
  • Consider virtual USB solutions for critical workflows

When working remotely through RDP or SSH, physically reconnecting a USB device after safe ejection becomes impossible. This creates workflow interruptions when you realize you need to access the device again. While solutions exist, many have limitations when multiple devices share the same USB hub.

Common approaches like using devcon.exe (Device Console) often fail unpredictably:

devcon.exe restart "USB\VID_0781&PID_5581*"

This may cause unintended side effects with other connected devices. The Windows Device Manager "Scan for hardware changes" option similarly lacks precision.

After thorough testing, I recommend using SafelyRemove's API for controlled USB device re-mounting. Their command-line interface provides precise control:

safelyremove.exe /remount /device:"Kingston DataTraveler"

Key advantages:

  • Targets specific devices without affecting others
  • Maintains proper device ejection protocols
  • Provides detailed error reporting

For those preferring native solutions, this PowerShell script can help (though less reliable than specialized tools):

$device = Get-PnpDevice | Where-Object {$_.FriendlyName -like "*USB Mass Storage*"}
Disable-PnpDevice -InstanceId $device.InstanceId -Confirm:$false
Start-Sleep -Seconds 2
Enable-PnpDevice -InstanceId $device.InstanceId -Confirm:$false

When implementing any solution:

  1. Test with non-critical devices first
  2. Monitor system event logs for USB-related errors
  3. Consider USB controller power management settings