2

All of a sudden my mouse appeared in the "Safely Remove Hardware" list after 6 years of usage. I'm wondering why did this behavior suddenly happen overnight. There was no update to the windows version from before this happen to the current date.

I have explored and went through these solutions already: For the regedit solution, the value was "160" and reducing it to "154" did nothing.

How to remove (not hide) the "Safely Remove Hardware" icon

Remove hardware from "safely remove hardware" list on Windows 7

I have also seen the bat file alternative.

The initial problem:

enter image description here

The properties of the mouse does not have a policy tab so there was no "Quick removal" option to trial with. enter image description here

Running "rundll32.exe shell32.dll,Control_RunDLL hotplug.dll" did not display the mouse device either.

enter image description here

6
  • 1
    Why do you care that it is listed?
    – Gantendo
    Sep 15, 2021 at 0:55
  • 1
    I don't want another icon in my tray and I like I had it minimalistic for years.
    – tosh
    Sep 15, 2021 at 1:12
  • Did you check superuser.com/a/241032/1482432 ?
    – Gantendo
    Sep 15, 2021 at 1:14
  • If you read the entire the post, you can see that is one of the links I included as part of solution searching.
    – tosh
    Sep 15, 2021 at 1:19
  • 1
    It's late. Try the value 128. "surprise removal ok".
    – Gantendo
    Sep 15, 2021 at 1:23

3 Answers 3

3

If you already seen this question, you know that you have to change the Capabilities key from the device in Registry.

The hexadecimal number you put in that key defines the "capabilities" of that device. Here you can see what number defines every "capability".

I had that same problem time ago, I found this article, but it didn't work for me. After I tweaked some keys, I finally got it to work. I'm sharing my solution instead, it worked for me, hope this works for you.


Hiding the device

If you want to hide a device from the "Safely Remove Hardware":

Before you do anything, make sure to make a Restore point, or make a backup of the registry keys you are about to edit. Just in case.

  1. Find your device ID from Device Manager, in "Events" tab. You only need the VID_XXXX&PID_XXXX part.

    Image1

  2. Locate that ID in HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB\.

    Image2

  3. Open that key and you will find another folder, enter there and change the Capabilities key to 60 hexadecimal.

    Image3

    If there are more folders, enter in every one and change the Capabilities key in the same way.

After that, if you open the "Safely Remove Hardware" list, you should notice that the device is no longer there.

Image4

The menu stays there until you reboot your PC. HOWEVER, changes made in HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB are reverted after reboot. If you want to make that change permanent, you have to create a task in Task Scheduler to apply that change every time you boot your PC.


Make it permanent

  1. You still have the Registry Editor open? Export the key(s) you edited, save it somewhere.

    Image5

  2. Open the .reg file you've exported with Notepad, and delete everything except the Capabilities key. It has to be something like this (in my case):

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB\VID_0458&PID_5010\5&2fecf0fe&0&4]
"Capabilities"=dword:00000060
  1. Save it somewhere, in my case, I saved it on a folder C:\hide\hide.reg

  2. Open Task Scheduler, and create a new basic task:

    • Name it like you want.
    • Start the task when the computer starts.
    • The action is start a program.
      • Program or script: regedit

      • Arguments: /S "<location of your reg file>"

        (in my case should be /S "C:\hide\hide.reg")

        This command will merge the .reg file into the Registry.

  3. Once you've created the task, open it's properties, and change the Security options, should be like this:

    Image6

    • Run whether user is logged on or not
    • Do not store password
    • Run with highest privileges

Now, everytime you boot your PC, before you log on, this task will run, and hide your device from the "Safely Remove Hardware" list.

Reboot your PC, and that "Safely Remove Hardware" icon should be gone.

enter image description here

Don't worry, it will work for normal USB and other devices as usual!


But...

This will work as long as you don't disconnect or change your hidden device, even if your PC is turned off. If you do that, Windows will re-register that device and it will appear again in the "Safely Remove Hardware" list. You will need to do all these steps again.

2
  • No luck. When rebooting for the permanent solution, the "Safely Remove Hardware" would still be there but the device is listed as "...". That tells me that the reg file has been applied via task scheduler but the icon still remains.
    – tosh
    Sep 15, 2021 at 14:00
  • @tosh That can happen because somewhat "you logged on more fast before the task ran". it happens sometimes. If you want to avoid that, disable "Use sign-in info to auto finish after Update or Restart".
    – moxwel
    Sep 15, 2021 at 16:11
2

I solved the issue of improper devices showing up under Safely Remove Hardware and Eject Media in the taskbar via the following:


SetDeviceProperties_NonRemovableFingerprintScanners.verbose.ps1

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 = "Biometric";
  $PnP_FriendlyName = "*Fingerprint*";
  # 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)) {
        Write-Host "`nInfo:  (Skipped) Registry key `"$(${RegEdit}.Path)`"'s property `"$(${RegEdit}.Name)`" is already set to value `"$(${RegEdit}.Value)`"`n";
      } Else {
        Write-Host "`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);
      }
      Write-Host "`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)) {
          Write-Host "`nInfo:  (Skipped) Registry key `"$(${RegEditParent}.Path)`"'s property `"$(${RegEditParent}.Name)`" is already set to value `"$(${RegEditParent}.Value)`"`n";
        } Else {
          Write-Host "`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);
        }
        Write-Host "`nInfo:  Confirming value for Registry key `"$(${RegEditParent}.Path)`"'s property `"$(${RegEditParent}.Name)`"...";
        Get-ItemProperty -LiteralPath (${RegEditParent}.Path) -Name (${RegEditParent}.Name);
      } Else {
        Write-Host "`nInfo:  (Skipped) Registry key `"$(${RegEditParent}.Path)`" not found to exist`n";
      }
      # End of parent device handling
      # ------------------------------
    } Else {
      Write-Host "`nInfo:  (Skipped) Registry key `"$(${RegEdit}.Path)`" not found to exist`n";
    }
  }
}

Note that variables $PnP_Class and $PnP_FriendlyName (at the top of the script) are intended to be set on a case-by-case basis to ensure the script only targets devices which shouldn't be removable/ejectable


Here's a thinned down version of the above script (intended for automation - to be ran through Task Scheduler)

SetDeviceProperties_NonRemovableFingerprintScanners.ps1

If ($True) {
  Get-PnpDevice -Class 'Biometric' -FriendlyName '*Fingerprint*' -Status 'OK' -EA:0 | ForEach-Object {
    $InstanceId = (${_}.InstanceId);
    $RegEdit = @{ Path="Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\${InstanceId}"; Name="Capabilities"; };
    If ((Test-Path -Path (${RegEdit}.Path)) -Eq $True) {
      $GetEachItemProp = (Get-ItemPropertyValue -LiteralPath (${RegEdit}.Path) -Name (${RegEdit}.Name) -ErrorAction ("Stop"));
      ${RegEdit}.Value = ($GetEachItemProp);
      $(0x00000002, 0x00000004) | ForEach-Object {
        ${RegEdit}.Value = ((${Regedit}.Value) - ((${Regedit}.Value) -band ${_}));
      }
      If ((${GetEachItemProp}) -NE (${RegEdit}.Value)) {
        Set-ItemProperty -LiteralPath (${RegEdit}.Path) -Name (${RegEdit}.Name) -Value (${RegEdit}.Value);
      }
      $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"; };
      If ((Test-Path -Path (${RegEditParent}.Path)) -Eq $True) {
        $GetEachParentItemProp = (Get-ItemPropertyValue -LiteralPath (${RegEditParent}.Path) -Name (${RegEditParent}.Name) -ErrorAction ("Stop"));
        ${RegEditParent}.Value = $GetEachItemProp;
        $(0x00000002, 0x00000004) | ForEach-Object {
          ${RegEditParent}.Value = ((${RegEditParent}.Value) - ((${RegEditParent}.Value) -band ${_}));
        }
        If ((${GetEachParentItemProp}) -NE (${RegEditParent}.Value)) {
          Set-ItemProperty -LiteralPath (${RegEditParent}.Path) -Name (${RegEditParent}.Name) -Value (${RegEditParent}.Value);
        }
      }
    }
  }
}

Here's a general workflow for the above script(s)...

  1. Use PowerShell's Get-PnpDevice cmdlet to target the device(s) you wish to no longer show as removable/ejectable media. For each PnpDevice acquired:

  2. Append the device's InstanceId property onto the static USB devices registry path, such as: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\${InstanceId}

  3. Perform a Bitwise AND (-band) between the device's Capability value and each of the undesired capabilities (namely CM_DEVCAP_EJECTSUPPORTED (0x2) and CM_DEVCAP_REMOVABLE (0x4)), then subtract the resultant value coming out of the -band from the Capability value.

    • If the Capability value DID contain either 0x2 or 0x4, then the -band resultant value will contain the exact differential to subtract off of the Capability to remove only the functionality which isnt needed.

    • If the Capability value DIDN'T contain either 0x2 or 0x4, then the -band will result in a value of 0, and we will subtract nothing (e.g. no changes to be made)

      • The above script also takes this final subtracted value and compares it against the original Capability value to see if it actually should perform a registry update (and skips it if not)
  4. Repeat step 2 & 3 for each device's parent device (and its associated InstanceId)

    • ⚠️ This behavior is 'fun', in that the parents device can have a Capability including 0x2 or 0x4 and that will cause the child device to continue to show up as ejectable/removable

    • Use PowerShell's Get-PnpDeviceProperty cmdlet targeting each device (from step 2)'s InstanceId along with the KeyName DEVPKEY_Device_Parent and expand the property Data (from the returned object)
      • This Data field will yield the InstanceId of the parent element (such as a USB dock), which requires performing steps 2 & 3 for in the same manner as the original device itself

3
  • You should inline the PowerShell scripts into your answer so in the event your repository is ever deleted, this community, does lose potentially helpful information. Please don’t revert the community standards edit back. You had an unnecessary quote block and “hope it helps” is just unnecessary noise.
    – Ramhound
    Aug 2, 2023 at 0:40
  • Ramhound, indeed! Alright, I'll get the code block up here. I do, however, disagree with the removal of the banged point about making sure to get the parent element. It's pretty obfuscated in this scenario. Appreciate your input either way
    – Cavallo
    Aug 2, 2023 at 1:19
  • @Ramhound Also I was just writing the markdown for this in a local IDE and pasting it up and into SuperUser as I went, so I apologize about not noticing your changes going up inbetween
    – Cavallo
    Aug 2, 2023 at 1:37
0

Easier method: Paste this line into notepad (triple click and ctrl+c , than ctrl+v):

reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Applets\SysTray" /f /v "Services" /t reg_dword /d 29

On the 2nd line in notepad write:

systray

You want systray on a seperate line as it's actually a command in windows that causes the systray to refresh, checking those registry values you entered, which are removed each reboot so:

Save the file named hide_sr_icons.cmd You can run it now to hide the icon right now, And put it in either shell:startup for it to run on startup on your account. or shell:common startup For it to run for all users.

Note it'll hide the icon always, not just for your mouse. However given the default for USB drives in windows 10/11 is quick removal, it's not really an important icon anymore. And you can still access the same functionality in the devices and printers panel anyways if needed.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .