Hide Installed Programs - 夜莺博客

Hide Installed Programs

原文:Hide Installed Programs — theDXT (Daniel Keer)

Have you ever wanted to be sneaky and hide a program that’s installed on your computer from Programs and Features and the Apps & features list? Well search no more, I have all the answers you seek. It’s shockingly simple.

Proper programs will list their uninstall info directly in the registry all we have to do is tweak that slightly.

Where Windows Gets the Installed Programs List

“Programs and Features” in Control Panel and “Apps & features” in Settings are two views of the same underlying data: the Uninstall registry keys. Windows enumerates the subkeys under three locations and displays any key that has a DisplayName value.

  • HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall — 64-bit machine-wide programs.
  • HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall — 32-bit machine-wide programs on 64-bit Windows.
  • HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall — per-user installers, which only appear for the user who installed them.

If the program is 64 bit it will show up in the registry in HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall and it will have a key for it’s program sometimes listed by its program ID or the actual program. You may need to search for the application you want to hide.

If the program is 32 bit it will show up in the registry in HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall just like 64 bit it will have a key for the program.

The process is the exact same for 32 bit or 64 bit programs. Anything without a DisplayName is already invisible to the Control Panel, which is why some driver packages and helper components never appear in the list in the first place.

The Values That Control How an Entry Behaves

Before hiding anything, it helps to know what the other values in the key do, because they are what an administrator would normally use instead of hiding the entry:

  • DisplayName — the name shown in the list. Delete it or rename it and the entry stops being displayed at all.
  • UninstallString / QuietUninstallString — the command Windows runs when a user clicks Uninstall.
  • NoRemove — set to 1, preserves the listing but removes the Uninstall button.
  • NoModify / NoRepair — hides the Change and Repair buttons for MSI products.
  • SystemComponent — set to 1, the entry is treated as an internal OS component and is not displayed at all. This is the value this article is about.
  • EstimatedSize, DisplayVersion, Publisher, InstallLocation, DisplayIcon — cosmetic metadata used by the list view. Nothing here is a security boundary; all of it is readable and writable by an administrator.

Hiding a Program with Registry Editor

Once you’ve located the registry entry for the program. Create a new DWORD with the name SystemComponent and a value of 1.

Boom just like that your program has vanished from Programs and Features along with Apps & features.

Example: this is the registry entry for Google Chrome on my system

Image 1
here it is listed in Programs and Features

Image 2
here it is listed in Apps & features

Image 3
Now I’ve created the DWORD named SystemComponent and gave it a value of 1

Image 4
Now when I refresh Programs and Features it’s missing

Image 5
The same is true in Apps & features

Image 6
The program is still fully installed it’s just hidden. If you change the value to 0 or delete the DWORD``SystemComponent it will show up again.

Work on a copy of the key rather than a live one when you can: right-click the application key, choose Export, and save the .reg file somewhere you will find it later. Restoring the exported key takes seconds and avoids hunting for the GUID of a program whose name you have already forgotten.

Doing It with PowerShell

Here’s a command to do it with PowerShell

Set-ItemProperty -Path "HKLM:SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{09D53CC6-0A7A-3BE2-B558-542159936402}" -Name "SystemComponent" -Value 1

Code language:PowerShell(powershell)

Tweak as needed and have fun!

Hard-coding a GUID is fine for a one-off, but a parameterised script is far more useful, because it also has to find the right hive. The function below searches both the 64-bit and 32-bit uninstall locations, matches on the DisplayName, and sets the value for you:

function Hide-InstalledProgram {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory)][string]$DisplayName,
        [ValidateSet(1,0)][int]$SystemComponent = 1
    )
    $roots = @(
        'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall',
        'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall',
        'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
    )
    $hit = $false
    foreach ($root in $roots) {
        if (-not (Test-Path $root)) { continue }
        Get-ChildItem $root | ForEach-Object {
            $p = Get-ItemProperty $_.PSPath -ErrorAction SilentlyContinue
            if ($p.DisplayName -like "*$DisplayName*") {
                New-ItemProperty -Path $_.PSPath -Name 'SystemComponent' `
                    -PropertyType DWord -Value $SystemComponent -Force | Out-Null
                Write-Host ("{0,-10} {1}" -f 'Updated:', $p.DisplayName)
                $hit = $true
            }
        }
    }
    if (-not $hit) { Write-Warning "No uninstall entry matched '$DisplayName'." }
}

Hide-InstalledProgram -DisplayName 'Chrome' -SystemComponent 1

Run it from an elevated PowerShell session for the HKLM hives; per-user keys under HKCU do not need elevation and are the ones that silently hide entries from a single login only.

Doing It from the Command Line

When you only need a single key and you already know its path, reg.exe is the shortest route, and it works inside deployment scripts where PowerShell execution policy is an obstacle:

reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{09D53CC6-0A7A-3BE2-B558-542159936402}" /v SystemComponent /t REG_DWORD /d 1 /f

To reverse it, write a value of zero or delete the value outright — both make the entry visible again:

reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{09D53CC6-0A7A-3BE2-B558-542159936402}" /v SystemComponent /t REG_DWORD /d 0 /f
reg delete "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{09D53CC6-0A7A-3BE2-B558-542159936402}" /v SystemComponent /f

Finding Programs That Are Already Hidden

Because Programs and Features is only a view, hidden programs are still perfectly visible from the registry — nothing is encrypted and nothing is protected. The following lists every installed program whose entry is flagged as a system component, which is a useful audit both for finding deliberate hides and for spotting legitimate entries that ship this way (Visual C++ redistributables are the classic example):

Get-ChildItem 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall',
              'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall' |
    ForEach-Object { Get-ItemProperty $_.PSPath } |
    Where-Object { $_.SystemComponent -eq 1 } |
    Select-Object DisplayName, DisplayVersion, Publisher, SystemComponent |
    Sort-Object DisplayName | Format-Table -AutoSize

Compare the result with what the Control Panel shows. Any name that appears in the first list and not in the second was hidden deliberately rather than by design.

Why the Trick Sometimes Does Not Stick

  • MSI products repair themselves. Windows Installer occasionally rewrites its own registration data during a repair, an upgrade or a patch, and the SystemComponent flag can be reverted with it. The same applies after a feature update.
  • Store and MSIX apps are elsewhere. Apps installed from the Microsoft Store or as MSIX packages live under HKCU\Software\Classes\Local Settings\...\AppModel and in Get-AppxPackage; the Uninstall key trick does not hide them.
  • The wrong hive silently does nothing. Editing the 64-bit path for a 32-bit application (or the other way around) leaves the visible entry untouched, which is the most common reason “it didn’t work”.
  • Third-party inventory tools read different sources. WMI, Get-Package, Get-CimInstance Win32_Product, Configuration Manager and Intune each build their own list, and several of them ignore SystemComponent entirely. Hiding an entry from a user does not hide it from an inventory system.
  • Uninstallers can drop the flag back. Some applications rewrite their own key on every launch, which quietly undoes your change.

Caveats, Ethics and Detection

A few honest points that most tutorials skip. Hiding a program does not uninstall it, does not stop its service, does not disable a driver and does not prevent it from starting, updating or phoning home — it only removes a line from a user interface. It is a cosmetic change with real administrative consequences, so:

  • Only do this on computers you own or are authorised to administer. On a managed corporate device, hiding software can be a policy and licensing violation, and it can interfere with software asset management.
  • Back up the key first with an export. Restoring is a two-click operation if you have the .reg file.
  • Log the change for yourself. In six months you will not remember which entries you hid, and the audit query above is the only thing that will tell you.
  • Security tooling treats this as a registry modification. Editing these keys maps to “Modify Registry” and “Hide Artifacts” in the MITRE ATT&CK framework, and endpoint detection products may raise an alert when an uninstall key gains a SystemComponent value — which is entirely reasonable, since this technique is also used to hide unwanted software from the person sitting at the keyboard.

Applying It Across Multiple Machines

The same registry value is deployable at scale if you have a legitimate reason — a lab image, a training room, a kiosk, or suppressing components your users should not be tempted to remove. A Group Policy Preferences Registry item can push the value to a whole OU, an Intune or Configuration Manager PowerShell script can run the function above, and an MDT or an image-build task sequence can bake it into the reference image so that no post-deployment change is needed at all. Keep the value in configuration management rather than in a hand-edited registry so the next person to rebuild the machine gets the same result.

Testing the Change Safely

Do the first attempt in a virtual machine or on a spare build, not on your daily driver. A quick and honest test cycle looks like this: open the Control Panel and note exactly which entries you intend to change; export the keys; apply the SystemComponent value; close and reopen the Control Panel window (the list is not refreshed live, so an open window keeps showing the old contents); confirm the entry is gone from both Control Panel and Settings; then confirm that the program itself still launches, still appears in Get-Package, and still updates. Reboot once before you trust the result — some uninstallers rewrite their own registry key at startup, and a value that survives a reboot is a value you can rely on. Only then apply the same change to the machines that matter, and record every key you touched in your change log.

reg export "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{09D53CC6-0A7A-3BE2-B558-542159936402}" C:\backup\chrome-uninstall-key.reg

Should You Hide It or Uninstall It?

If the goal is to stop users removing something they need — a VPN client, an agent, a certificate helper — the better-natured options are NoRemove, which keeps the entry visible but takes the Uninstall button away, or a policy that prevents removal. If the goal is to reduce clutter in the list, uninstalling unused software is usually the honest answer. Hiding is the right tool when the entry itself is misleading or when a component is deliberately managed by something other than the user, and it should be the exception rather than the house style.

Related Reading

For the neighbouring administrative tasks on the same machines, see GPO Export and Import, Disable Auto Windows Updates, and Find Files and Folders from the Command Line. If you are pushing settings to a fleet, Intune Device Filters explains how to target only the machines you mean.