Chapter 21. The Windows Registry

Introduction

As the configuration store for the vast majority of applications, the registry plays a central role in system administration. It is also generally hard to manage.

While command-line tools (such as reg.exe) exist to help you work with the registry, their interfaces are usually inconsistent and confusing. While the Registry Editor graphical user interface is easy to use, it does not support scripted administration.

PowerShell tackles this problem by exposing the Windows Registry as a navigation provider: a data source that you navigate and manage in exactly the same way that you work with the filesystem.

Problem

You want to navigate and explore the Windows Registry.

Solution

Use the Set-Location cmdlet just as you would navigate the filesystem to navigate the registry:

PS > Set-Location HKCU:
PS > Set-Location \Software\Microsoft\Windows\CurrentVersion\Run
PS > Get-Location

Path
----
HKCU:\Software\Microsoft\Windows\CurrentVersion\Run

Discussion

PowerShell lets you navigate the Windows Registry in exactly the same way that you navigate the filesystem, certificate drives, and other navigation-based providers. Like these other providers, the registry provider supports the Set-Location cmdlet (with the standard aliases of sl, cd, and chdir), Push-Location (with the standard alias pushd), Pop-Location (with the standard alias popd), and more.

For information about how to change registry keys once you get to a registry location, see the section called “Modify or Remove a Registry Key Value”. For more information about the registry provider, type Get-Help Registry.

View a Registry Key

Problem

You want to view the value of a specific registry key.

Solution

To retrieve the value(s) of a registry key, use the Get-ItemProperty cmdlet, as shown in Example 21.1, “Retrieving properties of a registry key”.

Example 21.1. Retrieving properties of a registry key

PS > Set-Location HKCU:
PS > Set-Location \Software\Microsoft\Windows\CurrentVersion\Run
PS > Get-ItemProperty .

PSPath                : Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_U
                        SER\Software\Microsoft\Windows\CurrentVersion\Run
PSParentPath          : Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_U
                        SER\Software\Microsoft\Windows\CurrentVersion
PSChildName           : Run
PSDrive               : HKCU
PSProvider            : Microsoft.PowerShell.Core\Registry
FolderShare           : "C:\Program Files\FolderShare\FolderShare.exe" /ba
                        ckground
TaskSwitchXP          : d:\lee\tools\TaskSwitchXP.exe
ctfmon.exe            : C:\WINDOWS\system32\ctfmon.exe
Ditto                 : C:\Program Files\Ditto\Ditto.exe
QuickTime Task        : "C:\Program Files\QuickTime Alternative\qttask.exe
                        " -atboottime
H/PC Connection Agent : "C:\Program Files\Microsoft ActiveSync\wcescomm.exe"

Discussion

In the registry provider, PowerShell treats registry keys as items and key values as properties of those items. To get the properties of an item, use the Get-ItemProperty cmdlet. The Get-ItemProperty cmdlet has the standard alias, gp.

Example 21.1, “Retrieving properties of a registry key” lists all property values associated with that specific key. To retrieve the value of a specific item, access it as you would access a property on a .NET object, or anywhere else in PowerShell:

PS > $item = Get-ItemProperty .
PS > $item.TaskSwitchXp
d:\lee\tools\TaskSwitchXP.exe

If you want to do this all at once, the command looks like:

PS > $runKey = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Run"
PS > (Get-ItemProperty $runKey).TaskSwitchXp
d:\lee\tools\TaskSwitchXP.exe

For more information about the Get-ItemProperty cmdlet, type Get-Help Get-ItemProperty. For more information about the registry provider, type Get-Help Registry.

Modify or Remove a Registry Key Value

Problem

You want to modify or remove a property of a specific registry key.

Solution

To set the value of a registry key, use the Set-ItemProperty cmdlet:

PS > (Get-ItemProperty .).MyProgram
c:\temp\MyProgram.exe
PS > Set-ItemProperty . MyProgram d:\Lee\tools\MyProgram.exe
PS > (Get-ItemProperty .).MyProgram
d:\Lee\tools\MyProgram.exe

To remove the value of a registry key, use the Remove-ItemProperty cmdlet:

PS > Remove-ItemProperty . MyProgram
PS > (Get-ItemProperty .).MyProgram

Discussion

In the registry provider, PowerShell treats registry keys as items and key values as properties of those items. To change the value of a key property, use the Set-ItemProperty cmdlet. The Set-ItemProperty cmdlet has the standard alias, sp. To remove a key property altogether, use the Remove–ItemProperty cmdlet.

Note

As always, use caution when changing information in the registry. Deleting or changing the wrong item can easily render your system unbootable.

For more information about the Get-ItemProperty cmdlet, type Get-Help Get-ItemProperty. For information about the Set-ItemProperty and Remove-ItemProperty cmdlets, type Get-Help Set-ItemProperty or Get-Help Remove-ItemProperty, respectively. For more information about the registry provider, type Get-Help Registry.

Create a Registry Key Value

Problem

You want to add a new key value to an existing registry key.

Solution

To add a value to a registry key, use the New-ItemProperty cmdlet. Example 21.2, “Creating new properties on a registry key” adds MyProgram.exe to the list of programs that start when the current user logs in.

Example 21.2. Creating new properties on a registry key

PS > Set-Location HKCU:\Software\Microsoft\Windows\CurrentVersion\Run
PS > New-ItemProperty . -Name MyProgram -Value c:\temp\MyProgram.exe

PSPath       : Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER\Softw
               are\Microsoft\Windows\CurrentVersion\Run
PSParentPath : Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER\Softw
               are\Microsoft\Windows\CurrentVersion
PSChildName  : Run
PSDrive      : HKCU
PSProvider   : Microsoft.PowerShell.Core\Registry
MyProgram    : c:\temp\MyProgram.exe

PS > Get-ItemProperty .

PSPath                : Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_U
                        SER\Software\Microsoft\Windows\CurrentVersion\Run
PSParentPath          : Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_U
                        SER\Software\Microsoft\Windows\CurrentVersion
PSChildName           : Run
PSDrive               : HKCU
PSProvider            : Microsoft.PowerShell.Core\Registry
FolderShare           : "C:\Program Files\FolderShare\FolderShare.exe" /ba
                        ckground
TaskSwitchXP          : d:\lee\tools\TaskSwitchXP.exe
ctfmon.exe            : C:\WINDOWS\system32\ctfmon.exe
Ditto                 : C:\Program Files\Ditto\Ditto.exe
QuickTime Task        : "C:\Program Files\QuickTime Alternative\qttask.exe
                        " -atboottime
H/PC Connection Agent : "C:\Program Files\Microsoft ActiveSync\wcescomm.ex
                        e"
MyProgram             : c:\temp\MyProgram.exe

Discussion

In the registry provider, PowerShell treats registry keys as items and key values as properties of those items. To create a key property, use the New-ItemProperty cmdlet.

For more information about the New-ItemProperty cmdlet, type Get-Help New-ItemProperty. For more information about the registry provider, type Get-Help Registry.

Remove a Registry Key

Problem

You want to remove a registry key and all its properties.

Solution

To remove a registry key, use the Remove-Item cmdlet:

PS > dir

   Hive: HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run

SKC  VC Name                            Property
---  -- ----                            --------
  0   0 Spyware                         {}

PS > Remove-Item Spyware

Discussion

As mentioned in the section called “Create a Registry Key Value”, the registry provider lets you remove items and containers with the Remove-Item cmdlet. The Remove-Item cmdlet has the standard aliases rm, rmdir, del, erase, and rd.

Note

As always, use caution when changing information in the registry. Deleting or changing the wrong item can easily render your system unbootable.

As in the filesystem, the Remove-Item cmdlet lets you specify multiple files through its Path, Include, Exclude, and Filter parameters. For information on how to use these parameters effectively, see the section called “Find Files That Match a Pattern”.

For more information about the Remove-Item cmdlet, type Get-Help Remove-Item. For more information about the registry provider, type Get-Help Registry.

Problem

You have several related registry modifications, and want them to group them so that either they all apply, or none apply.

Solution

Use the Start-Transaction cmdlet to start a transaction, and make your registry modifications within it. Use the Complete-Transaction cmdlet to make the registry modifications permanent:

PS > Set-Location HKCU:
PS > Start-Transaction

Suggestion [1,Transactions]: Once a transaction is started, only commands t
hat get called with the -UseTransaction flag become part of that transactio
n.
PS > mkdir TempKey -UseTransaction


    Hive: HKEY_CURRENT_USER


SKC  VC Name                           Property
---  -- ----                           --------
  0   0 TempKey                        {}


PS > Set-Location TempKey -UseTransaction
PS > New-Item TempKey2 -UseTransaction


    Hive: HKEY_CURRENT_USER\TempKey


SKC  VC Name                           Property
---  -- ----                           --------
  0   0 TempKey2                       {}


PS > Set-Location PS > Get-ChildItem TempKey
Get-ChildItem : Cannot find path 'HKEY_CURRENT_USER\TempKey' because it do
es not exist.
At line:1 char:14
+ Get-ChildItem <<<<  TempKey
    + CategoryInfo          : ObjectNotFound: (HKEY_CURRENT_USER\TempKey:
   String) [Get-ChildItem], ItemNotFoundException
    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.
   GetChildItemCommand

PS > Complete-Transaction
PS > Get-ChildItem TempKey


    Hive: HKEY_CURRENT_USER\TempKey


SKC  VC Name                           Property
---  -- ----                           --------
  0   0 TempKey2                       {}

1 comment

  1. David "Makovec" Moravec Posted 6 days and 9 hours ago

    Not working on XP, please see my comment in Chapter 30.

Add a comment

Discussion

When working in the registry, you might sometimes want to chain a set of related changes and be sure that they all get applied as a single unit. These are goals known as atomicity and consistency: the desire to avoid situations where an error during any step of the operation could cause an inconsistent system state if the other operations are not also successful.

To support this type of management task, PowerShell supports a change management strategy known as transactions. On Windows Vista and later, PowerShell's registry provider fully supports transactions.

When you start a transaction, any commands in that transaction are virtual and don't actually apply to the system until you complete the transaction. Within the context of the transaction, through, each participating command sees the system as though the state really had changed. Once you complete a transaction, changes are applied as a single unit.

Some systems that support transactions (such as databases) put locks on any resources that are being changed by a transaction. If another user tries to modify the locked resources, they get an error message. This is not supported in the Windows registry. If something alters a resource that your transaction depends on, the changes contained in your transaction will be abandoned and you will receive an error message when you try to complete that transaction.

For more information about transactions, see Chapter 30, Transactions.

Add a Site to an Internet Explorer Security Zone

Problem

You want to add a site to a specific Internet Explorer security zone.

Solution

To create the registry keys and properties required to add a site to a specific security zone, use the New-Item and New-ItemProperty cmdlets. Example 21.3, “Adding www.example.com to the list of trusted sites in Internet Explorer” adds www.example.com to the list of sites trusted by Internet Explorer.

Example 21.3. Adding www.example.com to the list of trusted sites in Internet Explorer

Set-Location "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings"
Set-Location ZoneMap\Domains
New-Item example.com
Set-Location example.com
New-Item www
Set-Location www
New-ItemProperty . -Name http -Value 2 -Type DWORD

Discussion

One task that requires modifying data in the registry is working with Internet Explorer to add and remove sites from its different security zones.

Internet Explorer stores its zone mapping information in the registry at HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMap\Domains. Below that key, Explorer stores the domain name (such as leeholmes.com) with the hostname (such as www) as a subkey of that one (see Figure 21.1, “Internet Explorer zone configuration”). In the host key, Explorer stores a property (such as http) with a DWORD value that corresponds to the zone identifier.

Figure 21.1. Internet Explorer zone configuration

Internet Explorer zone configuration

The Internet Explorer zone identifiers are:

My Computer
Local intranet
Trusted sites
Internet
Restricted sites

When Internet Explorer is configured in its Enhanced Security Configuration mode, you must also update entries under the EscDomains key.

Note

Once a machine has enabled Internet Explorer's Enhanced Security Configuration, those settings persist even after removing Enhanced Security Configuration. The following commands let your machine trust UNC paths again:

Set-Location "HKCU:\Software\Microsoft\Windows\"
Set-Location "CurrentVersion"
Set-Location "Internet Settings"
Set-ItemProperty ZoneMap UNCAsIntranet -Type DWORD 1
Set-ItemProperty ZoneMap IntranetName -Type DWORD 1

To remove the zone mapping for a specific domain, use the Remove-Item cmdlet:

PS > Get-ChildItem

   Hive: HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMap\Domains

SKC VC Name                            Property
--- -- ----                            --------
  1  0 example.com                     {}

PS > Remove-Item -Recurse example.com
PS > Get-ChildItem
PS > 

For more information about using the Internet Explorer registry entries to configure security zones, see the Microsoft KB article "Description of Internet Explorer Security Zones Registry Entries" at http://support.microsoft.com/kb/182569. For more information about managing Internet Explorer's Enhanced Security Configuration, search for it on http://technet.microsoft.com.

For more information about modifying data in the registry, see the section called “Modify or Remove a Registry Key Value”.

Modify Internet Explorer Settings

Problem

You want to modify Internet Explorer's configuration options.

Solution

To modify the Internet Explorer configuration registry keys, use the Set-ItemProperty cmdlet. For example, to update the proxy:

Set-Location "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings"
Set-ItemProperty . -Name ProxyServer -Value http://proxy.example.com
Set-ItemProperty . -Name ProxyEnable -Value 1

Discussion

Internet Explorer stores its main configuration information as properties on the registry key HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings. To change these properties, use the Set-ItemProperty cmdlet as demonstrated in the solution.

Another common set of properties to tweak are the configuration parameters that define a security zone. An example of this is to prevent scripts from running in the Restricted Sites zone. For each zone, Internet Explorer stores this information as properties of the registry key HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\<Zone>, where <Zone> represents the zone identifier (0, 1, 2, 3, or 4) to manage.

The Internet Explorer zone identifiers are:

My Computer
Local intranet
Trusted sites
Internet
Restricted sites

The names of the properties in this key are not designed for human consumption, as they carry illuminating titles such as 1A04 and 1809. While not well-named, you can still script them.

For more information about using the Internet Explorer registry settings to configure security zones, see the Microsoft KB article "Description of Internet Explorer Security Zones Registry Entries" at http://support.microsoft.com/kb/182569.

For more information about modifying data in the registry, see the section called “Modify or Remove a Registry Key Value”.

Program: Search the Windows Registry

Discussion

While the Windows Registry Editor is useful for searching the registry, it sometimes may not provide the power you need. For example, the registry editor does not support searches with wildcards or regular expressions.

In the filesystem, we have the Select-String cmdlet to search files for content. PowerShell does not have that for other stores, but we can write a script to do it. The key here is to think of registry key values like you think of content in a file:

Example 21.4, “Search-Registry.ps1” goes through all registry keys (and their values) for a search term and returns information about the match.

Example 21.4. Search-Registry.ps1

##############################################################################

param([string] $searchText = $(throw "Please specify text to search for."))

function New-RegistryMatch
{
    param( $matchType, $keyName, $propertyName, $line )

    $registryMatch = New-Object PsObject -Property @{
        MatchType = $matchType;
        KeyName = $keyName;
        PropertyName = $propertyName;
        Line = $line
    }

    $registryMatch
}

foreach($item in Get-ChildItem -Recurse -ErrorAction SilentlyContinue)
{
    if($item.Name -match $searchText)
    {
        New-RegistryMatch "Key" $item.Name $null $item.Name
    }

    foreach($property in (Get-ItemProperty $item.PsPath).PsObject.Properties)
    {
        if(($property.Name -eq "PSPath") -or ($property.Name -eq "PSChildName"))
        {
            continue
        }

        $propertyText = "$($property.Name)=$($property.Value)"
        if($propertyText -match $searchText)
        {
            New-RegistryMatch "Property" $item.Name $property.Name $propertyText
        }
    } 
}
      

1 comment

  1. David "Makovec" Moravec Posted 6 days and 9 hours ago

    Why not use hash for new object properties. The more it will be visible the more people will use it.

Add a comment


For more information about running scripts, see the section called “Run Programs, Scripts, and Existing Tools”.

Get the ACL of a Registry Key

Problem

You want to retrieve the ACL of a registry key.

Solution

To retrieve the ACL of a registry key, use the Get-Acl cmdlet:

PS > Get-Acl HKLM:\Software

Path                     Owner                   Access
----                     -----                   ------
Microsoft.PowerShell.... BUILTIN\Administrators  CREATOR OWNER Allow ....

Discussion

As mentioned in the section called “Get the ACL of a File or Directory”, the Get-Acl cmdlet retrieves the security descriptor of an item. This cmdlet doesn't only work against the registry, however. Any provider (for example, the filesystem provider) that supports the concept of security descriptors also supports the Get-Acl cmdlet.

The Get-Acl cmdlet returns an object that represents the security descriptor of the item and is specific to the provider that contains the item. In the registry provider, this returns a .NET System.Security.AccessControl.RegistrySecurity object that you can explore for further information. For an example of changing the ACL of a registry key with this result, see the section called “Set the ACL of a Registry Key”. For an example of a script that works with ACLs, see the section called “Get the ACL of a File or Directory”.

For more information about the Get-Acl command, type Get-Help Get-Acl. For more information about working with classes from the .NET Framework, see the section called “Work with .NET Objects”.

Set the ACL of a Registry Key

Problem

You want to change the ACL of a registry key.

Solution

To set the ACL on a registry key, use the Set-Acl cmdlet. This example grants an account write access to a registry key under HKLM:\Software. This is especially useful for programs that write to administrator-only regions of the registry, which prevents them from running under a non-administrator account.

cd HKLM:\Software\MyProgram
$acl = Get-Acl .
$arguments = "LEE-DESK\Lee","FullControl","Allow"
$accessRule = New-Object System.Security.AccessControl.RegistryAccessRule $arguments
$acl.SetAccessRule($accessRule)
$acl | Set-Acl .

Discussion

As mentioned in the section called “Set the ACL of a File or Directory”, the Set-Acl cmdlet sets the security descriptor of an item. This cmdlet doesn't only work against the registry, however. Any provider (for example, the filesystem provider) that supports the concept of security descriptors also supports the Set-Acl cmdlet.

The Set-Acl cmdlet requires that you provide it with an ACL to apply to the item. While it is possible to construct the ACL from scratch, it is usually easiest to retrieve it from the item beforehand (as demonstrated in the solution). To retrieve the ACL, use the Get-Acl cmdlet. Once you've modified the access control rules on the ACL, simply pipe them to the Set-Acl cmdlet to make them permanent.

In the solution, the $arguments list that we provide to the RegistryAccessRule constructor explicitly sets an Allow rule on the Lee account of the LEE-DESK computer for FullControl permission. For more information about working with classes (such as the RegistryAccessRule class) from the .NET Framework, see the section called “Work with .NET Objects”.

Although the Set-Acl command is powerful, you may already be familiar with command-line tools that offer similar functionality (such as SubInAcl.exe). You can of course continue to use these tools from PowerShell.

For more information about the Set-Acl cmdlet, type Get-Help Set-Acl. For more information about the Get-Acl cmdlet, see the section called “Get the ACL of a Registry Key”.

Work with the Registry of a Remote Computer

Problem

You want to work with the registry keys and values of a remote computer.

Solution

To work with the registry of a remote computer, use the scripts provided in this chapter: Get-RemoteRegistryChildItem, Get-RemoteRegistryProperty, and Set-RemoteRegistryProperty. These scripts require that the remote computer has the remote registry service enabled and running. Example 21.5, “Setting the PowerShell execution policy of a remote machine” updates the PowerShell execution policy of a remote machine.

Example 21.5. Setting the PowerShell execution policy of a remote machine

PS > $registryPath = "HKLM:\Software\Microsoft\PowerShell\1"
PS > Get-RemoteRegistryChildItem LEE-DESK $registryPath

SKC  VC Name                           Property
---  -- ----                           --------
  0   1 1033                           {Install}
  0   5 PowerShellEngine               {ApplicationBase, ConsoleHostAss...
  2   0 PowerShellSnapIns              {}
  1   0 ShellIds                       {}

PS > Get-RemoteRegistryChildItem LEE-DESK $registryPath\ShellIds

SKC  VC Name                           Property
---  -- ----                           --------
  0   2 Microsoft.PowerShell           {Path, ExecutionPolicy}

PS > $registryPath = "HKLM:\Software\Microsoft\PowerShell\1\" +
>>     "ShellIds\Microsoft.PowerShell"
>>
PS > Get-RemoteRegistryKeyProperty LEE-DESK $registryPath ExecutionPolicy

ExecutionPolicy
---------------
Unrestricted

PS > Set-RemoteRegistryKeyProperty LEE-DESK $registryPath `
>>     "ExecutionPolicy" "RemoteSigned"
>>
PS > Get-RemoteRegistryKeyProperty LEE-DESK $registryPath ExecutionPolicy


ExecutionPolicy
---------------
RemoteSigned

Discussion

Although this specific task is perhaps better solved through PowerShell's Group Policy support, it demonstrates a useful scenario that includes both remote registry exploration and modification.

If the remote computer does not have the Remote Registry service running (but does have WMI enabled), you can use WMI's StdRegProv class to work with the registry as well. The following example demonstrates how to get and set the registry key that controls Remote Desktop:

$HKEY_CLASSES_ROOT = [Convert]::ToUInt32(80000000, 16)
$HKEY_CURRENT_USER = [Convert]::ToUInt32(80000001, 16)
$HKEY_LOCAL_MACHINE = [Convert]::ToUInt32(80000002, 16)
$HKEY_USERS = [Convert]::ToUInt32(80000003, 16)
$HKEY_CURRENT_CONFIG = [Convert]::ToUInt32(80000005, 16)

$reg = Get-WmiObject -ComputerName LEE-DESK `
    -Namespace root\default StdRegProv -List

$reg.GetDWORDValue($HKEY_LOCAL_MACHINE,
    "SYSTEM\CurrentControlSet\Control\Terminal Server",
    "fDenyTSConnections")

$reg.SetDWORDValue($HKEY_LOCAL_MACHINE,
    "SYSTEM\CurrentControlSet\Control\Terminal Server",
    "fDenyTSConnections", 0)

For more information about the Get-RemoteRegistryChildItem, Get-RemoteRegistryProperty, and Set-RemoteRegistryProperty scripts, see the section called “Program: Get Registry Items from Remote Machines”, the section called “Program: Get Properties of Remote Registry Keys”, and the section called “Program: Set Properties of Remote Registry Keys”.

Program: Get Registry Items from Remote Machines

Discussion

Although PowerShell does not directly let you access and manipulate the registry of a remote computer, it still supports this by working with the .NET Framework. The functionality exposed by the .NET Framework is a bit more developer-oriented than we want, so we can instead use a script to make it easier to work with.

Example 21.6, “Get-RemoteRegistryChildItem.ps1” lets you list child items in a remote registry key, much like you do on the local computer. In order for this script to succeed, the target computer must have the remote registry service enabled and running.

Example 21.6. Get-RemoteRegistryChildItem.ps1

##############################################################################

param(
  $computer = $(throw "Please specify a computer name."),
  $path = $(throw "Please specify a registry path")
  )

if($path -match "^HKLM:\\(.*)")
{
    $baseKey = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey(
        "LocalMachine", $computer)
}
elseif($path -match "^HKCU:\\(.*)")
{
    $baseKey = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey(
        "LocalMachine", $computer)
}
else
{
    Write-Error ("Please specify a fully-qualified registry path " +
        "(i.e.: HKLM:\Software) of the registry key to open.")
    return
}

$key = $baseKey.OpenSubKey($matches[1])

foreach($subkeyName in $key.GetSubKeyNames())
{
    $subkey = $key.OpenSubKey($subkeyName)

    $returnObject = [PsObject] $subKey
    $returnObject | Add-Member NoteProperty PsChildName $subkeyName
    $returnObject | Add-Member NoteProperty Property $subkey.GetValueNames()

    $returnObject

    $subkey.Close()
}

$key.Close()
$baseKey.Close()

      

For more information about running scripts, see the section called “Run Programs, Scripts, and Existing Tools”.

Program: Get Properties of Remote Registry Keys

Discussion

Although PowerShell does not directly let you access and manipulate the registry of a remote computer, it still supports this by working with the .NET Framework. The functionality exposed by the .NET Framework is a bit more developer-oriented than we want, so we can instead use a script to make it easier to work with.

Example 21.7, “Get-RemoteRegistryKeyProperty.ps1” lets you get the properties (or a specific property) from a given remote registry key. In order for this script to succeed, the target computer must have the remote registry service enabled and running.

Example 21.7. Get-RemoteRegistryKeyProperty.ps1

##############################################################################

param(
  $computer = $(throw "Please specify a computer name."),
  $path = $(throw "Please specify a registry path"),
  $property = "*"
  )

if($path -match "^HKLM:\\(.*)")
{
    $baseKey = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey(
        "LocalMachine", $computer)
}
elseif($path -match "^HKCU:\\(.*)")
{
    $baseKey = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey(
        "LocalMachine", $computer)
}
else
{
    Write-Error ("Please specify a fully-qualified registry path " +
        "(i.e.: HKLM:\Software) of the registry key to open.")
    return
}

$key = $baseKey.OpenSubKey($matches[1])
$returnObject = New-Object PsObject

foreach($keyProperty in $key.GetValueNames())
{
    if($keyProperty -like $property)
    {
        $returnObject | 
            Add-Member NoteProperty $keyProperty $key.GetValue($keyProperty)
    }
}

$returnObject

$key.Close()
$baseKey.Close()


For more information about running scripts, see the section called “Run Programs, Scripts, and Existing Tools”.

Program: Set Properties of Remote Registry Keys

Discussion

Although PowerShell does not directly let you access and manipulate the registry of a remote computer, it still supports this by working with the .NET Framework. The functionality exposed by the .NET Framework is a bit more developer-oriented than we want, so we can instead use a script to make it easier to work with.

Example 21.8, “Set-RemoteRegistryKeyProperty.ps1” lets you set the value of a property on a given remote registry key. In order for this script to succeed, the target computer must have the remote registry service enabled and running.

Example 21.8. Set-RemoteRegistryKeyProperty.ps1

##############################################################################

param(
  $computer = $(throw "Please specify a computer name."),
  $path = $(throw "Please specify a registry path"),
  $property = $(throw "Please specify a property name"),
  $propertyValue = $(throw "Please specify a property value")
  )

if($path -match "^HKLM:\\(.*)")
{
    $baseKey = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey(
        "LocalMachine", $computer)
}
elseif($path -match "^HKCU:\\(.*)")
{
    $baseKey = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey(
        "LocalMachine", $computer)
}
else
{
    Write-Error ("Please specify a fully-qualified registry path " +
        "(i.e.: HKLM:\Software) of the registry key to open.")
    return
}

$key = $baseKey.OpenSubKey($matches[1], $true)
$key.SetValue($property, $propertyValue)

$key.Close()
$baseKey.Close()

For more information about running scripts, see the section called “Run Programs, Scripts, and Existing Tools”.

Discover Registry Settings for Programs

Problem

You want to automate the configuration of a program, but that program does not document its registry configuration settings.

Solution

To discover a registry setting for a program, use Sysinternals' Process Monitor to observe registry access by that program. Process Monitor is available from http://www.microsoft.com/technet/sysinternals/FileAndDisk/processmonitor.mspx.

Discussion

In an ideal world, all programs would fully support command-line administration and configuration through PowerShell cmdlets. Many programs do not, however, so the solution is to look through their documentation in the hope that they list the registry keys and properties that control their settings. While many programs document their registry configuration settings, many still do not.

Although these programs may not document their registry settings, you can usually observe their registry access activity to determine the registry paths they use. To illustrate this, we will use the Sysinternals' Process Monitor to discover PowerShell's execution policy configuration keys. Although PowerShell documents these keys and makes its automated configuration a breeze, it illustrates the general technique.

Launch and configure Process Monitor

Once you've downloaded Process Monitor, the first step is to filter its output to include only the program you are interested in. By default, Process Monitor logs almost all registry and file activity on the system.

First, launch Process Monitor, and then press Ctrl-E (or click the magnifying glass icon) to temporarily prevent it from capturing any data (see Figure 21.2, “Process Monitor ready to capture”). Next, press Ctrl-X (or click the white sheet with an eraser icon) to clear the extra information that it captured automatically. Finally, drag the target icon and drop it on top of the application in question. You can press Ctrl-L (or click the funnel icon) to see the filter that Process Monitor now applies to its output.

Figure 21.2. Process Monitor ready to capture

Process Monitor ready to capture

Prepare to manually set the configuration option

Next, prepare to manually set the program's configuration option. Usually, this means typing and clicking all the property settings, but just not clicking OK or Apply. For this PowerShell example, type the Set-ExecutionPolicy command line, but do not press Enter (see Figure 21.3, “Preparing to apply the configuration option”).

Figure 21.3. Preparing to apply the configuration option

Preparing to apply the configuration option

Tell Process Monitor to begin capturing information

Switch to the Process Monitor window, and then press Ctrl-E (or click the magnifying glass icon). Process Monitor now captures all registry access for the program in question.

Manually set the configuration option

Click OK, Apply, or whatever action it takes to actually complete the program's configuration. For the PowerShell example, this means pressing Enter.

Tell Process Monitor to stop capturing information

Switch again to the Process Monitor window, and then press Ctrl-E (or click the magnifying glass icon). Process Monitor now no longer captures the application's activity.

Review the capture logs for registry modification

The Process Monitor window now shows all registry keys that the application interacted with when it applied its configuration setting.

Press Ctrl-F (or click the binoculars icon); then search for RegSetValue. Process Monitor highlights the first modification to a registry key, as shown in Figure 21.4, “Process Monitor's registry access detail”.

Press Enter (or double-click the highlighted row) to see the details about this specific registry modification. In this example, we can see that PowerShell changed the value of the ExecutionPolicy property (under HKLM:\Software\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell) to RemoteSigned. Press F3 to see the next entry that corresponds to a registry modification.

Automate these registry writes

Now that you know all registry writes that the application performed when it updated its settings, judgment and experimentation will help you determine which modifications actually represent this setting. Since PowerShell only performed one registry write (to a key that very obviously represents the execution policy), the choice is pretty clear in this example.

Once you've discovered the registry keys, properties, and values that the application uses to store its configuration data, you can use the techniques discussed in the section called “Modify or Remove a Registry Key Value” to automate these configuration settings. For example:

Figure 21.4. Process Monitor's registry access detail

Process Monitor's registry access detail

PS > $key = "HKLM:\Software\Microsoft\PowerShell\1\" +
>>     "ShellIds\Microsoft.PowerShell"
>>
PS > Set-ItemProperty $key ExecutionPolicy AllSigned
PS > Get-ExecutionPolicy
AllSigned
PS > Set-ItemProperty $key ExecutionPolicy RemoteSigned
PS > Get-ExecutionPolicy
RemoteSigned
You must sign in or register before commenting
*
*
*
*
*

Atom Icon Comments on this page or Comments on the whole book.