Per User Install



Many software products, e.g Google Chrome, can be installed on a per-user basis. This typically means that a non-privileged user can install the product, with all executable and data files being placed in the user’s profile folder (typically).

However, most software inventory tools, e.g SCCM, cannot pick up per-user installs. This is because, although they are properly recorded in the uninstall registry keyspace, this is not part of the registry HKLM hive. Instead, when a user logs on, a file, NTUSER.DAT, which is typically hidden, is loaded from the user profile directory (typically c:\users\<username>) and mapped to HKEY_USERS in the registry. As such, the user SID is the subkey for each user.

Because they are not easily detected, per-user software installs represent a potentially unaudited threat. As a consequence, being able to track these installs, along with the user(s) associated with them, can be very useful.

Product Pack notes:



  • Inventory: Show per-user installs
  • Uninstall any per-user Chrome installs on next user logon


Show per-user installs

For each user, the following information is returned

  • The user name
  • The publisher
  • The display name
  • The display version

This information is read from the uninstall registry hive and should be consistent with the information SCCM would pick up for the same product if installed for the entire device.

Where the user is logged on, we recover this information from the HKEY_USERS hive, which is enumerated for each user SID present.

Where the user is not logged on, there will be no subkey in HKEY_USERS. In this case we dynamically load the NTUSER.DAT file into the HKLM\1E\Software tree as the subkey UserHive. We then adjust the permissions on this registry tree to allow us to delete the subkey when we are finished analysing that user. Then, having loaded the hive, we scan it as we would for an entry in HKEY_USERS.

Note that attempting to read NTUSER.DAT for a logged-in user results in a sharing violation (which is trapped). Therefore duplicate entries will not occur since only one of the two reading paths can succeed.


Depending on the method of retrieval (HKEY_USERS for a logged in user or c:\users\\ntuser.dat for a non-logged in user), the display format for the user name may differ. For a logged in user the SID is translated to the normal domain\user syntax, with a local user being reported as device\user.

For a non-logged-in user, the name of the users folder is used. Unfortunately this typically only has the account portion of the user name. Therefore this is what is reported.

When a user name clashes locally e.g domain\joe.smith and device\joe.smith, Windows uses a naming convention to distinguish the two user profile folders. This is to name one of the accounts joe.smith.SUFFIX where the value of SUFFIX depends on the order in which the two accounts first logged on to the endpoint.

If the first account to log on was a local account, then the domain account folder will be named joe.smith.DOMAIN (where DOMAIN is the domain name).

If the first account to log on was a domain account, then the local account folder will be named joe.smith.DEVICE (where DEVICE is the device name)

Thus, folder names can be kept unique. However this is also how user names for non-logged-in users will be reported when running this question. This is because at this stage I do not know how to retrieve the user SID from the loaded registry hive.


Uninstall any per-user Chrome installs on next user logon

This instruction is currently tagged as a question but probably should be relabelled as an action. This is obviously trivial to do by loading it into TIMS and changing its type


This instruction creates a scheduled task which is triggered by any user logon on the endpoint(s) targetted. The scheduled task is called UninstallChrome.

Each time a user logs on, the task attempts to impersonate the user and then read the appropriate registry key for the uninstall command for Chrome. If it finds the registry key, it then immediately executes the uninstall command, adding an option to ensure the uninstall is silent. This immediately removes the per-user installation of Chrome from the endpoint.

The scheduled task remains active indefinitely and will therefore remove any subsequent per-user installations of Chrome, without having to re-run the Tachyon instruction again.

Note that per-device installations are not affected by this scheduled task.

The approach used is extensible to other per-user installations provided that they record an uninstall command in the users HKCU registry tree; in this case, simply modify the ‘chromebgone.ps1’ script accordingly. It’s possible to create a general-purpose version of this script that would search for any per-user installation information and execute the appropriate uninstall commands, by enumerating the appropriate registry keys.

You must log in to submit a review. Click here to login.