I run subsequent reg queries and this takes quite a time:
reg query HKLM\SOFTWARE\Classes /s /f "foo"
reg query HKLM\SOFTWARE\Classes /s /f "bar"
Is there any way to search by multiple values at once with reg query
?
No, unfortunately reg query /s /f
accepts only a single filter expression.
The filter expression:Tip of the hat to aschipfl for his help.
is matched against all registry entities by default: key names, value names and data.
(OR-ed combinations of) options /k
(keys), /v
(values) and /d
(data) can be used to narrow the scope.
/v
can also be used without /f
, in which case it requires a value-name search term (e.g., /v foo
) that is matched in full (see below); /ve
returns only default values (the values whose name is the empty string) if they contain data./f
with /v <valueNameSearchTerm>
or /ve
, only combining key search (/k
) via /f
is supported to narrow down the matches; that is, the only combinations that make sense are:
/f <keySearchTerm> /k /v <valueNameSearchTerm>
/f <keySearchTerm> /k /ve
/v <valueNameSearchTerm>
/ /ve
matching is limited to those keys that match /f <keySearchTerm>
, amounting to AND logic./k
, adding /d
, using just /d
- effectively causes the /f
search term to be ignored./t REG_*
can be used to narrow matching to specified value types, such as REG_SZ
performs case-insensitive substring matching by default.
supports wildcard characters *
(any number of chars., including none) and ?
(exactly 1 char.) - though note that something like foo*
still only performs substring matching; there is seemingly no way to anchor substrings.
/v
directly with a value-name search term (e.g., /v foo
, it must match in full; e.g., to find a value name that contains substring foo
, you then must use *foo*
./e
performs whole-string matching, without wildcard support.
/c
uses case-sensitive matching.
numeric data such as REG_DWORD
is matched in its decimal string representation
REG_BINARY
) is matched as a "byte string": a list of 2-hex-digit byte values without separators.Run reg query /?
to see all options or consult the documentation.
You can use the following PowerShell command to provide multiple filters:
Note:
The command is limited to the following search logic - though it could be adapted to support all reg query
options, at which point creating a function wrapper would definitely be called for:
A regular expression (with -match
) rather than wildcard matching (with -like
) is used, which both simplifies the command and makes it more flexible (it wouldn't be hard to adapt the solution to use wildcard matching instead).
Only registry data is searched, not also key names and value names.
Get-ChildItem HKLM:\SOFTWARE\Classes -Recurse |
Where-Object { $_.PSChildName -match 'foo|bar' }
Unlike with reg.exe
, binary data is matched byte by byte, based on their decimal string representation.
Only the sub-keys of the target key are examined, not the target key itself.
With a single filter, the command is slower than reg.exe
, but with multiple filters it is eventually likely faster than multiple reg.exe
calls; for the OP it took 4-5 - YMMV.
Replacing the Get-ChildItem
call with direct use of the .NET framework for recursive key enumeration will likely bring speed improvements, though I have no sense of how much. A purpose-built native binary such as reg.exe
will always be faster than custom PowerShell code.
Generally, the main advantages of a PowerShell solution are:
# The two filters to use, combined into a single regex.
$regex = 'foo|bar'
Get-ChildItem HKLM:\SOFTWARE\Classes -Recurse | ForEach-Object {
foreach ($value in $_.GetValueNames()) {
if (($data = $_.GetValue($value)) -match $regex) {
[PSCustomObject]@{
Key = $_.Name
Value = if ($value) { $value } else { '(default)' }
Data = $data
}
}
}
}
The output is something like the following, with the Data
column containing the matches (scroll to the right; alternatively, pipe the above to Format-List
for a one-property-per-line view):
Key Value Data
--- ----- ----
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\AllSyncRootObjects StatusBar prop:~System.StatusBarViewItemCount;~System.StatusBarSelectedItemCount...
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{0002E132-0000-0000-C000-000000000046}\InprocServer32 Class Microsoft.Vbe.Interop.CommandBarEventsClass
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{0002E132-0000-0000-C000-000000000046}\InprocServe... Class Microsoft.Vbe.Interop.CommandBarEventsClass
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{0006F054-0000-0000-C000-000000000046} (default) Microsoft Outlook InfoBar Control
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{0006F054-0000-0000-C000-000000000046}\InprocServer32 Class Microsoft.Office.Interop.Outlook.OlkInfoBarClass
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{0006F054-0000-0000-C000-000000000046}\InprocServe... Class Microsoft.Office.Interop.Outlook.OlkInfoBarClass
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{0006F054-0000-0000-C000-000000000046}\ProgID (default) Outlook.OlkInfoBar.1
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{0006F054-0000-0000-C000-000000000046}\VersionInde... (default) Outlook.OlkInfoBar
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{056440FD-8568-48e7-A632-72157243B55B} (default) Explorer Navigation Bar
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{05d7b0f4-2121-4eff-bf6b-ed3f69b894d7} (default) Taskbar Control Panel
...