Downloads
141799.zip

Anyone who has been responsible for managing Windows machines for any length of time will be familiar with the registry. The registry was originally created as a way for the OS to store information about file types. But starting in Windows NT 3.1 and Windows 95, the registry became the standard place in which the OS and applications can quickly store and retrieve configuration information. Windows 95 introduced regedit, the standard GUI registry-editing tool; Windows NT provided another GUI registry editor, regedt32, which supported more registry types than regedit did. Windows NT 4.0 and Windows 2000 provided both editors. Starting in Windows XP, Microsoft upgraded regedit to support the same data types as regedt32, making the latter editor obsolete.

Regedit is an extremely useful tool, but searching for data isn't one of its strong suits. Regedit's Find feature, which Figure 1 shows, is basic: Press Ctrl+F, enter a text string, select any of the four check boxes, and click Find Next. Pressing F3 to repeat the search quickly becomes tedious when there are many matches.

Figure 1: Regedit Find dialog box
Figure 1: Regedit Find dialog box 

I decided to rectify this weakness by writing a Windows PowerShell script, Search-Registry.ps1, which can search the registry more flexibly than regedit. (You can download the script by clicking the download link at the top of this page.) Search-Registry.ps1 improves on regedit's Find feature in four ways:

  • The script searches by using regular expressions.
  • It can search the registry on remote computers.
  • It can limit the number of returned search results.
  • It outputs objects than can be filtered, sorted, exported to comma-separated value (CSV) files, and so on.

Many PowerShell-savvy readers will note that PowerShell provides registry "drives" (e.g., HKLM) for accessing the registry. However, these drives work only on the local computer, not on remote systems. I also considered PowerShell remoting. But remoting requires that PowerShell 2.0 or later be installed and enabled on all remote machines-a scenario that doesn't occur by default.

Introducing Search-Registry.ps1

The Search-Registry.ps1 script's command-line syntax is as follows:

Search-Registry [-StartKey] <String> [-Pattern] <String> [-MatchKey] [-MatchValue]
[-MatchData] [-MaximumMatches <n>] [-ComputerName <String[]>]

The -StartKey parameter specifies the registry key location from which to start searching. This is equivalent to selecting a starting location in regedit's left pane before pressing Ctrl+F. The -StartKey parameter string uses the format

subtree:\key

where subtree is either the abbreviated PowerShell drive name or the full subtree name, as seen in regedit:

  • HKCR or HKEY_CLASSES_ROOT
  • HKCU or HKEY_CURRENT_USER
  • HKLM or HKEY_LOCAL_MACHINE
  • HKU or HKEY_USERS

The colon (:) after the subtree name is optional. The key specifies where to start searching. If you omit the key or use a single backslash character (\), the script searches the entire subtree. For example, the following strings are all equivalent when used with the -StartKey parameter:

HKLM\SOFTWARE
HKLM:\SOFTWARE
HKEY_LOCAL_MACHINE\SOFTWARE

The -StartKey parameter is designated to be in position 1, so as long as you specify its argument first on the command line, the -StartKey parameter name is optional. If the -StartKey parameter argument string contains spaces, then surround the string with quotation marks (").

The -Pattern parameter specifies the regular expression pattern that you want to find. The -Pattern parameter is designated to be in position 2, so as long as you specify its argument second on the command line, the -Pattern parameter name is optional. If the -Pattern parameter argument string contains spaces, use quotation marks as appropriate. The regular expression pattern is not case-sensitive. For more information about constructing a regular expression pattern, enter the command

help about_Regular_Expressions

at the PowerShell command prompt.

The -MatchKey, -MatchValue, and -MatchData parameters specify the kinds of matches that the script should find. These parameters correspond to the Keys, Values, and Data check boxes in regedit's Find dialog box, as Figure 1 shows. Figure 2 illustrates how these items correspond to items in the registry. I decided to stick with these names instead of the new names (i.e., path, property, value) that PowerShell uses in its registry provider so that the script uses the same terms that the regedit Find dialog box uses. You must specify at least one of these three parameters, although you can specify more than one. -MatchKey matches subkey names, -MatchValue matches registry value names, and -MatchData matches the values' data.

Figure 2: How items in the script correspond with items in the registry
Figure 2: How items in the script correspond with items in the registry 

The -MaximumMatches parameter specifies the maximum number of results per searched computer. The default value is 0, which returns the maximum number of possible matches. This parameter is useful when searching the registry on remote computers; you can use it to minimize the amount of network traffic.

The -ComputerName parameter searches the registry on the specified computer or list of computers. You can specify one computer name or an array of names. This parameter supports pipeline input. The default is to search the local computer's registry.

Search-Registry.ps1 outputs objects that contain the properties that Table 1 lists. Figure 3 shows a sample Search-Registry.ps1 command in a PowerShell console window. The script that Figure 3 shows sends its output to Select-Object to select only the Key, Value, and Data properties (the ComputerName property isn't needed because this command searches the local computer's registry). Select-Object then sends this output to Format-List. The list contains only two matches because of the specified -MaximumMatches parameter.

Figure 3: Running Search-Registry.ps1
Figure 3: Running Search-Registry.ps1 

Depending on the OS, some registry locations might be inaccessible (e.g., because of insufficient permissions). These registry locations will output errors when Search-Registry.ps1 tries to access them. To ignore these errors, specify the -ErrorAction SilentlyContinue parameter in the script's command.

How Does It Work?

Search-Registry.ps1 uses the begin and process scriptblocks because it supports pipeline input. The begin scriptblock contains the script's initialization code: global variable declarations, parameter validations, and function definitions. The process scriptblock iterates each computer name that's passed to the script and passes the computer name to the search-registry2 function. The search-registry2 function uses the OpenRemoteBaseKey static method of the .NET Microsoft.Win32.RegistryKey class to open the subtree that you request at the command line, and then passes each computer name to the search-registrykey function. The search-registrykey function searches recursively for the regular expression pattern in a registry location (i.e., it starts at a specified key and also searches in all subkeys of that key).

Sample Commands

Let's take a look at some real-world examples of how you might use Search-Registry.ps1.

Search-Registry -StartKey HKCR -Pattern
"Word\.Document\.\d" -MatchKey

This command searches the local computer's registry, starting at HKEY_CLASSES_ROOT, for the pattern "Word\.Document\.\d". In regular expressions, a period (.) matches any character; a backslash (\) means "interpret the next character literally." Therefore, "\." means ".". A backslash followed by the letter d (\d) indicates "any decimal digit," so this search finds registry subkeys that are named Word.Document.n (where n is a number). If this command returns a match, then there's probably an application on the local system that can open Microsoft Word documents.

Search-Registry -StartKey HKLM -Pattern
$ENV:USERNAME -MatchData

This command searches HKEY_LOCAL_MACHINE on the local computer for any registry data that contains the current user name.

Search-Registry -StartKey HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System
-Pattern EnableLinkedConnections -MatchValue

This command determines whether the EnableLinkedConnections registry value is configured on the local computer. (To find out why you might want to search for this value, see the Microsoft article "Programs may be unable to access some network locations after you turn on User Account Control inWindows Vista or in Windows 7.")

Get-Content Computers.txt |
Search-Registry HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System
-Pattern EnableLinkedConnections -MatchValue |
Export-CSV C:\Reports\EnableLinkedConnections.csv
-NoTypeInformation

This command is the same as the previous one, except that Search-Registry.ps1 searches for the registry value on the computers that are listed in the file Computers.txt and creates a CSV report.

Hassle-Free Registry Searching

Searching for information in the registry no longer needs to be a tedious exercise. Hitting F3 a couple hundred times in regedit can be a thing of the past. The next time you need to search the registry, open a PowerShell command window and use Search-Registry.ps1 instead.