The Windows Registry is a hierarchical database that stores low-level configuration settings for the operating system, hardware drivers, and installed software. PowerShell exposes the registry as a virtual filesystem using the Registry Provider, allowing administrators to mount hives as drives (PSDrives) like HKLM: and HKCU: and navigate keys using standard filesystem commands such as Set-Location and Get-ChildItem.
The Registry as a PSDrive
A PSDrive is a data store exposed to PowerShell as a navigable drive letter or path. The PowerShell Registry Provider automatically mounts the two most frequently used registry hives at shell startup:
HKLM:points to theHKEY_LOCAL_MACHINEhive, containing machine-wide settings and system policies.HKCU:points to theHKEY_CURRENT_USERhive, containing configurations and user preferences for the currently logged-in account.
Get-PSDrive -PSProvider "Registry" |
Select-Object -Property Name, Provider, Root, Descriptionwhere:
Get-PSDrivelists active drives mapped in the current PowerShell session.-PSProvider "Registry"filters results to show only drives powered by the internal Registry provider.Nameis the drive alias used in file paths (HKLMandHKCU).Rootis the underlying Windows registry hive mapped to the drive.
./get-registry-drives.ps1Name Provider Root Description
---- -------- ---- -----------
HKCU Microsoft.PowerShell.Core\Registry HKEY_CURRENT_USER The software settings for the current user
HKLM Microsoft.PowerShell.Core\Registry HKEY_LOCAL_MACHINE The configuration settings for the local computerAvailable Registry Hives
| PSDrive | Full Hive Name | Common Use |
|---|---|---|
HKLM: |
HKEY_LOCAL_MACHINE |
System-wide settings, installed software |
HKCU: |
HKEY_CURRENT_USER |
Settings for the currently logged-in user |
HKCR: |
HKEY_CLASSES_ROOT |
File associations, COM registration |
HKU: |
HKEY_USERS |
Settings for all loaded user profiles |
HKCC: |
HKEY_CURRENT_CONFIG |
Current hardware profile |
Navigating the Registry Like a Filesystem
Because the Registry provider implements the core container navigation interface, you traverse registry keys using the same commands you use for directories in the filesystem:
| Filesystem Task | Cmdlet | Standard Alias | Registry Equivalent |
|---|---|---|---|
| Change Directory | Set-Location |
cd, chdir |
Switch active registry key |
| Show Current Path | Get-Location |
pwd |
Print current registry key path |
| List Directory Contents | Get-ChildItem |
dir, ls |
List child subkeys |
| Inspect Container | Get-Item |
gi |
Display key properties and values |
Changing Location into a Registry Hive
Set-Location -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion"where -Path is a registry path, using the same backslash-separated format as a file path.
Get-LocationPath
----
HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersionListing Registry Keys with Get-ChildItem
Get-ChildItem -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion" Hive: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion
Name Property
---- --------
AccountPicture
ActionCenter
App Management
App Paths
AppHost EnableWebContentEvaluation : 1
...Complete Navigation Example
Set-Location -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion"
Get-Location
Get-ChildItem | Select-Object -Property Name -First 3where:
Set-Locationchanges the active PowerShell location to the specified registry key path.Get-Locationemits the current working container path.Get-ChildItemlists items within the current container (in the registry, this enumerates child subkeys).-First 3restricts console output to the first three returned items.
./navigate-registry.ps1Path
----
HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion
Name : HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Accessibility
Name : HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AdaptiveDisplayBrightness
Name : HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebugRecursively Listing Subkeys
Get-ChildItem -Path "HKCU:\Software" -Recurse -ErrorAction SilentlyContinuewhere:
-Recursetraverses all nested subkeys, not just the immediate children.-ErrorAction SilentlyContinuesuppresses errors from keys with restricted access permissions.
Checking if a Key Exists with Test-Path
Test-Path -Path "HKCU:\Software\MyApp"FalseQuerying Keys Directly with Get-Item
Instead of navigating with Set-Location, you can query a registry path directly using Get-Item.
$key = Get-Item -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion"
[PSCustomObject]@{
KeyPath = $key.Name
SubKeyCount = $key.SubKeyCount
ValueCount = $key.ValueCount
SampleValues = ($key.Property | Select-Object -First 4) -join ", "
}where:
Get-Itemreturns the specific registry key container object (Microsoft.Win32.RegistryKey).-Pathspecifies the target registry path using theHKLM:PSDrive prefix.$key.SubKeyCountis the integer counter of subkeys directly beneath this key.$key.ValueCountis the integer counter of individual configuration values defined on this key.$key.Propertyis the string array containing the names of all registry values present on the key.
./inspect-key-direct.ps1KeyPath SubKeyCount ValueCount SampleValues
------- ----------- ---------- ------------
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion 97 32 SystemRoot, BaseBuildRevisionNumber, BuildBranch, BuildGUIDPractical Usage
Exploring Installed Software
A common registry task is listing installed applications by reading the Uninstall subkey, which Windows populates for most installed programs.
$uninstallPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
Get-ChildItem -Path $uninstallPath |
ForEach-Object { Get-ItemProperty -Path $_.PSPath } |
Where-Object { $_.DisplayName } |
Select-Object DisplayName, DisplayVersion, Publisher |
Sort-Object DisplayNamewhere:
$_.PSPathis the full registry path of each subkey, used to read its values.Where-Object { $_.DisplayName }filters out subkeys that don't represent a visible installed application.
./list-installed-software.ps1DisplayName DisplayVersion Publisher
----------- -------------- ---------
Git 2.53.0.2 The Git Development Community
GPL Ghostscript 10.07.0 Artifex Software Inc.
Microsoft Update Health Tools 3.74.0.0 Microsoft Corporation
Microsoft Visual C++ 2022 X64 Additional Runtime - 14.40.33816 14.40.33816 Microsoft Corporation
Microsoft Visual C++ 2022 X64 Minimum Runtime - 14.40.33816 14.40.33816 Microsoft Corporation
Update for x64-based Windows Systems (KB5001716) 8.94.0.0 Microsoft Corporation
Windows PC Health Check 3.6.2204.08001 Microsoft CorporationAuditing User Run Persistence Keys
A common system administration and security task involves checking registry "Run" keys across both machine and user hives to determine what binaries are scheduled to launch automatically at logon.
$runPaths = @(
"HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run",
"HKCU:\Software\Microsoft\Windows\CurrentVersion\Run"
)
$startupEntries = foreach ($path in $runPaths) {
if (Test-Path -Path $path) {
$key = Get-Item -Path $path
foreach ($valueName in $key.Property) {
[PSCustomObject]@{
Hive = if ($path -like "HKLM*") { "Machine" } else { "User" }
EntryName = $valueName
CommandPath = $key.GetValue($valueName)
}
}
}
}
$startupEntries | Format-Table -AutoSizewhere:
$runPathsis an array containing target startup registry paths across both system (HKLM) and user (HKCU) scopes.Test-Pathvalidates that the registry key exists before attempting to query it.$key.GetValue($valueName)is the .NET method that reads the data content stored within the specified registry value name.Format-Table -AutoSizeformats the discovered startup applications into an aligned console table.
./audit-startup-keys.ps1Hive EntryName CommandPath
---- --------- -----------
Machine SecurityHealth C:\Windows\system32\SecurityHealthSystray.exe
Machine VMware User Process "C:\Program Files\VMware\VMware Tools\vmtoolsd.exe" -n vmusr
User OneDrive "C:\Users\Tom\AppData\Local\Microsoft\OneDrive\OneDrive.exe" /background
User MyStartupScript "C:\Users\Tom\Desktop\hello.bat"