This PowerShell script will disable the ability to eject specific hardware devices in Windows.
I personally use it to prevent accidentally ejecting the USB drive that I am booting a persistent Windows installation from.
$DeviceSubKeys = @('USB\VID_1234&PID_9876\...')
$CM_DEVCAP_EJECTSUPPORTED = 0x2
$CM_DEVCAP_REMOVABLE = 0x4
$Flags = @($CM_DEVCAP_EJECTSUPPORTED, $CM_DEVCAP_REMOVABLE)
foreach ($DeviceSubKey in $DeviceSubKeys) {
$FullKey = "HKLM:\SYSTEM\CurrentControlSet\Enum\$DeviceSubKey"
if (-not (Test-Path $FullKey)) {
throw "Registry key $FullKey does not exist"
}
try {
$OldCapabilities = Get-ItemProperty $FullKey -Name Capabilities -ErrorAction Stop | Select -ExpandProperty Capabilities
} catch {
throw "Registry key $FullKey does not have a Capabilities value"
}
$NewCapabilities = $OldCapabilities
foreach ($Flag in $Flags) {
$NewCapabilities = $NewCapabilities -band (-bnot $Flag)
}
if ($NewCapabilities -ne $OldCapabilities) {
Set-ItemProperty -Path $FullKey -Name Capabilities -Type DWord -Value $NewCapabilities
Write-Host ("$DeviceSubKey [Capabilities] 0x{0:x} -> 0x{1:x}" -f $OldCapabilities, $NewCapabilities) -ForegroundColor Green
} else {
Write-Host "$DeviceSubKey [Capabilities] unchanged" -ForegroundColor Yellow
}
}Array of parent instance IDs of the devices to clear Capabilities flags from.
To determine this value, open Device Manager and view the Properties of the corresponding device. Under the Details tab, find the Parent property.
The property affixed to HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ should produce a valid registry key.
Array of Capabilities flags to clear from each device in DeviceSubKeys.
See cfgmgr32.h for additional flags.
Windows writes the Capabilities value on boot. Therefore, the script must run on each startup for its changes to persist.
Create a new task in Task Scheduler and configure it as follows:
- Run as user:
SYSTEM - Trigger: At startup
- Action: Start a program
- Program:
powershell.exe - Arguments:
-NoProfile -ExecutionPolicy Bypass -File "script.ps1"
- Program:
- Conditions: All unchecked
Alternatively, open PowerShell as administrator and run the following command (after editing the path to your script):
Register-ScheduledTask `
-TaskName 'Disable device ejection' `
-User SYSTEM `
-Trigger (New-ScheduledTaskTrigger -AtStartup) `
-Settings ( `
New-ScheduledTaskSettingsSet `
-AllowStartIfOnBatteries `
-DontStopIfGoingOnBatteries `
-ExecutionTimeLimit (New-TimeSpan -Minutes 5) `
) `
-Action ( `
New-ScheduledTaskAction `
-Execute powershell.exe `
-Argument '-NoProfile -ExecutionPolicy Bypass -File "script.ps1"' `
)