Created
November 16, 2024 00:49
-
-
Save emabrey/60ced7bd66e6bc3f44a83abba7bb46a9 to your computer and use it in GitHub Desktop.
Script to remove TP-Link Wireless USB Device from Eject Hardware Menu
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
param([switch]$Elevated) | |
function Test-Admin { | |
$currentUser = New-Object Security.Principal.WindowsPrincipal $([Security.Principal.WindowsIdentity]::GetCurrent()) | |
$currentUser.IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator) | |
} | |
function Log-Info ($msg, $color = "Blue") { | |
if($host.UI.RawUI.ForegroundColor -ne $null) { | |
Write-Host "`n[$([datetime]::Now.ToLongTimeString())] $msg" -ForegroundColor $color -BackgroundColor "Gray" | |
} else { | |
#Write-Output "`r`n[$([datetime]::Now.ToLongTimeString())] $msg" | |
} | |
} | |
if ((Test-Admin) -eq $false) { | |
if ($elevated) { | |
# tried to elevate, did not work, aborting | |
} else { | |
Start-Process powershell.exe -Verb RunAs -ArgumentList ('-noprofile -noninteractive -windowstyle Hidden -file "{0}" -elevated' -f ($myinvocation.MyCommand.Definition)) | |
} | |
exit | |
} | |
If ($True) { | |
# | |
# Disable the 'Safely Remove Hardware and Eject Media' capability for target Plug and Play (PnP) devices | |
# | |
# Set the class/friendlyname of devices to update | |
$PnP_Class = "Net"; | |
$PnP_FriendlyName = "TP-Link Wireless USB Adapter"; | |
# Set the list of capabilities to remove (additional "capabilities bits" listed at the bottom of this script) | |
$RemoveCapabilities = @() | |
$RemoveCapabilities += 0x00000002; # CM_DEVCAP_EJECTSUPPORTED (flags the device as ejectable) | |
$RemoveCapabilities += 0x00000004; # CM_DEVCAP_REMOVABLE (flags the device as removable) | |
# Get the list of devices to remove capabilities from | |
Get-PnpDevice -Class "${PnP_Class}" -FriendlyName "${PnP_FriendlyName}" -Status 'OK' -EA:0 | ForEach-Object { | |
$InstanceId = (${_}.InstanceId); | |
$RegEdit = @{ | |
Path="Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\${InstanceId}"; | |
Name="Capabilities"; | |
Type="DWord"; | |
Description="Defines the capabilities for a given device. Citation [ https://github.com/tpn/winsdk-10/blob/master/Include/10.0.10240.0/um/cfgmgr32.h#L1067-L1076 ]"; | |
}; | |
# ------------------------------ | |
# Parse each device in question | |
Write-Host "------------------------------------------------------------"; | |
If ((Test-Path -Path (${RegEdit}.Path)) -Eq $True) { | |
$GetEachItemProp = (Get-ItemPropertyValue -LiteralPath (${RegEdit}.Path) -Name (${RegEdit}.Name) -ErrorAction ("Stop")); | |
${RegEdit}.Value = $GetEachItemProp; | |
# Bitwise slice off any instances of the Capability to-remove | |
${RemoveCapabilities} | ForEach-Object { | |
# Note that the bitwise AND will be zero if the value doesn't include the value to remove - it will only modify values which require an update. | |
${RegEdit}.Value = ((${RegEdit}.Value) - ((${RegEdit}.Value) -band ${_})); | |
} | |
If ((${GetEachItemProp}) -Eq (${RegEdit}.Value)) { | |
Log-Info "`nInfo: (Skipped) Registry key `"$(${RegEdit}.Path)`"'s property `"$(${RegEdit}.Name)`" is already set to value `"$(${RegEdit}.Value)`"`n"; | |
} Else { | |
Log-Info "`nInfo: Setting Registry key `"$(${RegEdit}.Path)`"'s property `"$(${RegEdit}.Name)`" to value `"$(${RegEdit}.Value)`"...`n"; | |
Set-ItemProperty -LiteralPath (${RegEdit}.Path) -Name (${RegEdit}.Name) -Value (${RegEdit}.Value); | |
} | |
Log-Info "`nInfo: Confirming value for Registry key `"$(${RegEdit}.Path)`"'s property `"$(${RegEdit}.Name)`"..."; | |
Get-ItemProperty -LiteralPath (${RegEdit}.Path) -Name (${RegEdit}.Name); | |
# ------------------------------ | |
# Repeat this process for the parent device | |
Write-Host "------------------------------------------------------------"; | |
$ParentInstanceId = (Get-PnpDeviceProperty -KeyName 'DEVPKEY_Device_Parent' -InstanceId "${InstanceId}" | Select-Object -ExpandProperty "Data" -EA:0); | |
$RegEditParent = @{ | |
Path="Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\${ParentInstanceId}"; | |
Name="Capabilities"; | |
Type="DWord"; | |
Description="Defines the capabilities for a given device. Citation [ https://github.com/tpn/winsdk-10/blob/master/Include/10.0.10240.0/um/cfgmgr32.h#L1067-L1076 ]"; | |
}; | |
If ((Test-Path -Path (${RegEditParent}.Path)) -Eq $True) { | |
$GetEachParentItemProp = (Get-ItemPropertyValue -LiteralPath (${RegEditParent}.Path) -Name (${RegEditParent}.Name) -ErrorAction ("Stop")); | |
${RegEditParent}.Value = $GetEachItemProp; | |
# Bitwise slice off any instances of the Capability to-remove | |
${RemoveCapabilities} | ForEach-Object { | |
# Note that the bitwise AND will be zero if the value doesn't include the value to remove - it will only modify values which require an update. | |
${RegEditParent}.Value = ((${RegEditParent}.Value) - ((${RegEditParent}.Value) -band ${_})); | |
} | |
If ((${GetEachParentItemProp}) -Eq (${RegEditParent}.Value)) { | |
Log-Info "`nInfo: (Skipped) Registry key `"$(${RegEditParent}.Path)`"'s property `"$(${RegEditParent}.Name)`" is already set to value `"$(${RegEditParent}.Value)`"`n"; | |
} Else { | |
Log-Info "`nInfo: Setting Registry key `"$(${RegEditParent}.Path)`"'s property `"$(${RegEditParent}.Name)`" to value `"$(${RegEditParent}.Value)`"...`n"; | |
Set-ItemProperty -LiteralPath (${RegEditParent}.Path) -Name (${RegEditParent}.Name) -Value (${RegEditParent}.Value); | |
} | |
Log-Info "`nInfo: Confirming value for Registry key `"$(${RegEditParent}.Path)`"'s property `"$(${RegEditParent}.Name)`"..."; | |
Get-ItemProperty -LiteralPath (${RegEditParent}.Path) -Name (${RegEditParent}.Name); | |
} Else { | |
Log-Info "`nInfo: (Skipped) Registry key `"$(${RegEditParent}.Path)`" not found to exist`n"; | |
} | |
# End of parent device handling | |
# ------------------------------ | |
} Else { | |
Log-Info "`nInfo: (Skipped) Registry key `"$(${RegEdit}.Path)`" not found to exist`n"; | |
} | |
} | |
} | |
#Restart explorer | |
$class = [wmiclass]"\root\cimv2:win32_process" | |
Get-WmiObject -Class Win32_Process -Filter "Name='explorer.exe'" -OutVariable Process | | |
Where-Object { $_.GetOwner().User -ne 'Administrator' } | | |
Foreach-Object { $_.Terminate()} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment