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.

Although command-line tools (such as reg.exe) exist to help you work with the registry, their interfaces are usually inconsistent and confusing. The Registry Editor graphical user interface is easy to use, but 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.

Navigate the Registry

Problem

You want to navigate and explore the Windows Registry.

Solution

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

PS > Set-Location HKCU:
PS > Set-Location SoftwareMicrosoftWindowsCurrentVersionRun
PS > Get-Location

Path
----
HKCU:SoftwareMicrosoftWindowsCurrentVersionRun

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 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.

Example 21-1. Retrieving properties of a registry key

PS > Set-Location HKCU:
PS > Set-Location SoftwareMicrosoftWindowsCurrentVersionRun
PS > Get-ItemProperty .

PSPath                : Microsoft.PowerShell.CoreRegistry::HKEY_CURRENT_U
                        SERSoftwareMicrosoftWindowsCurrentVersionRun
PSParentPath          : Microsoft.PowerShell.CoreRegistry::HKEY_CURRENT_U
                        SERSoftwareMicrosoftWindowsCurrentVersion
PSChildName           : Run
PSDrive               : HKCU
PSProvider            : Microsoft.PowerShell.CoreRegistry
FolderShare           : "C:Program FilesFolderShareFolderShare.exe" /
                        background
TaskSwitchXP          : d:lee	oolsTaskSwitchXP.exe
ctfmon.exe            : C:WINDOWSsystem32ctfmon.exe
Ditto                 : C:Program FilesDittoDitto.exe
QuickTime Task        : "C:Program FilesQuickTime Alternativeqttask.exe
                        " -atboottime
H/PC Connection Agent : "C:Program FilesMicrosoft ActiveSyncwcescomm.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 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	oolsTaskSwitchXP.exe

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

PS > $runKey = "HKCU:SoftwareMicrosoftWindowsCurrentVersionRun"
PS > (Get-ItemProperty $runKey).TaskSwitchXp
d:lee	oolsTaskSwitchXP.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:	empMyProgram.exe
PS > Set-ItemProperty . MyProgram d:Lee	oolsMyProgram.exe
PS > (Get-ItemProperty .).MyProgram
d:Lee	oolsMyProgram.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.

Warning

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 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:SoftwareMicrosoftWindowsCurrentVersionRun
PS > New-ItemProperty . -Name MyProgram -Value c:	empMyProgram.exe

PSPath       : Microsoft.PowerShell.CoreRegistry::HKEY_CURRENT_USER
               SoftwareMicrosoftWindowsCurrentVersionRun
PSParentPath : Microsoft.PowerShell.CoreRegistry::HKEY_CURRENT_USER
               SoftwareMicrosoftWindowsCurrentVersion
PSChildName  : Run
PSDrive      : HKCU
PSProvider   : Microsoft.PowerShell.CoreRegistry
MyProgram    : c:	empMyProgram.exe

PS > Get-ItemProperty .

PSPath                : Microsoft.PowerShell.CoreRegistry::HKEY_CURRENT_
                        USERSoftwareMicrosoftWindowsCurrentVersionRun
PSParentPath          : Microsoft.PowerShell.CoreRegistry::HKEY_CURRENT_
                        USERSoftwareMicrosoftWindowsCurrentVersion
PSChildName           : Run
PSDrive               : HKCU
PSProvider            : Microsoft.PowerShell.CoreRegistry
FolderShare           : "C:Program FilesFolderShareFolderShare.exe" 
                        /background
TaskSwitchXP          : d:lee	oolsTaskSwitchXP.exe
ctfmon.exe            : C:WINDOWSsystem32ctfmon.exe
Ditto                 : C:Program FilesDittoDitto.exe
QuickTime Task        : "C:Program FilesQuickTime Alternativeqttask.exe"
                        -atboottime
H/PC Connection Agent : "C:Program FilesMicrosoft ActiveSyncwcescomm.exe"
MyProgram             : c:	empMyProgram.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_USERSoftwareMicrosoftWindowsCurrentVersionRun

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

PS > Remove-Item Spyware

Discussion

As mentioned in 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.

Warning

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 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.

Safely Combine Related Registry Modifications

Problem

You have several related registry modifications, and you want 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
that get called with the -UseTransaction flag become part of that transaction.
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_USERTempKey


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


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

PS > Complete-Transaction
PS > Get-ChildItem TempKey


    Hive: HKEY_CURRENT_USERTempKey


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

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, the user gets 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.

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 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:SoftwareMicrosoftWindowsCurrentVersionInternet Settings"
Set-Location ZoneMapDomains
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:SoftwareMicrosoftWindowsCurrentVersionInternet SettingsoneMapDomains. 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). In the host key, Explorer stores a property (such as http) with a DWORD value that corresponds to the zone identifier.

Internet Explorer zone configuration

Figure 21-1. 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:SoftwareMicrosoftWindows"
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_USERSoftware…Internet SettingsoneMapDomains

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 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:SoftwareMicrosoftWindowsCurrentVersionInternet 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:SoftwareMicrosoftWindowsCurrentVersionInternet 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:SoftwareMicrosoftWindowsCurrentVersionInternet Settingsones<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 they are 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 Modify or Remove a Registry Key Value.

Program: Search the Windows Registry

Although the Windows Registry Editor is useful for searching the registry, sometimes it might 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 offer that ability 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:

  • Directories have items; items have content.

  • Registry keys have properties; properties have values.

Example 21-4 goes through all registry keys (and their values) for a search term and returns information about the match.

Example 21-4. Search-Registry.ps1

##############################################################################
##
## Search-Registry
##
## From Windows PowerShell Cookbook (O'Reilly)
## by Lee Holmes (http://www.leeholmes.com/guide)
##
##############################################################################

<#

.SYNOPSIS

Search the registry for keys or properties that match a specific value.

.EXAMPLE

PS >Set-Location HKCU:SoftwareMicrosoft
PS >Search-Registry Run

#>

param(
    ## The text to search for
    [Parameter(Mandatory = $true)]
    [string] $Pattern
)

Set-StrictMode -Off

## Helper function to create a new object that represents
## a registry match from this script
function New-RegistryMatch
{
    param( $matchType, $keyName, $propertyName, $line )

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

    $registryMatch
}

## Go through each item in the registry
foreach($item in Get-ChildItem -Recurse -ErrorAction SilentlyContinue)
{
    ## Check if the key name matches
    if($item.Name -match $pattern)
    {
        New-RegistryMatch "Key" $item.Name $null $item.Name
    }

    ## Check if a key property matches
    foreach($property in (Get-ItemProperty $item.PsPath).PsObject.Properties)
    {
        ## Skip the property if it was one PowerShell added
        if(($property.Name -eq "PSPath") -or
            ($property.Name -eq "PSChildName"))
        {
            continue
        }

        ## Search the text of the property
        $propertyText = "$($property.Name)=$($property.Value)"
        if($propertyText -match $pattern)
        {
            New-RegistryMatch "Property" $item.Name `
                property.Name $propertyText
        }
    }
}

For more information about running scripts, see 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.... BUILTINAdministrators  CREATOR OWNER Allow ....

Discussion

As mentioned in Get the ACL of a File or Directory, the Get-Acl cmdlet retrieves the security descriptor of an item. This cmdlet doesn’t work against only 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 Set the ACL of a Registry Key. For an example of a script that works with ACLs, see 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 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 nonadministrator account.

##############################################################################
##
## Grant-RegistryAccessFullControl
##
## From Windows PowerShell Cookbook (O'Reilly)
## by Lee Holmes (http://www.leeholmes.com/guide)
##
##############################################################################

<#

.SYNOPSIS

Grants full control access to a user for the specified registry key.

.EXAMPLE

PS >$registryPath = "HKLM:SoftwareMyProgram"
PS >Grant-RegistryAccessFullControl "LEE-DESKLEE" $registryPath

#>

param(
    ## The user to grant full control
    [Parameter(Mandatory = $true)]
    $User,

    ## The registry path that should have its permissions modified
    [Parameter(Mandatory = $true)]
    $RegistryPath
)

Set-StrictMode -Version Latest

Push-Location
Set-Location -LiteralPath $registryPath

## Retrieve the ACL from the registry key
$acl = Get-Acl .

## Prepare the access rule, and set the access rule
$arguments = $user,"FullControl","Allow"
$accessRule = New-Object Security.AccessControl.RegistryAccessRule $arguments
$acl.SetAccessRule($accessRule)

## Apply the modified ACL to the registry key
$acl | Set-Acl  .

Pop-Location

Discussion

As mentioned in Set the ACL of a File or Directory, the Set-Acl cmdlet sets the security descriptor of an item. This cmdlet doesn’t work against only 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. Although 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 from the .NET Framework (such as the RegistryAccessRule class), see 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 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 (Program: Get Registry Items from Remote Machines), Get-RemoteRegistryKeyProperty (Program: Get Properties of Remote Registry Keys), and Set-RemoteRegistryKeyProperty (Program: Set Properties of Remote Registry Keys). These scripts require that the remote computer has the remote registry service enabled and running. Example 21-5 updates the PowerShell execution policy of a remote machine.

Example 21-5. Setting the PowerShell execution policy of a remote machine

PS > $registryPath = "HKLM:SoftwareMicrosoftPowerShell1"
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 $registryPathShellIds

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

PS > $registryPath = "HKLM:SoftwareMicrosoftPowerShell1" +
    "ShellIdsMicrosoft.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)

## Connect to the registry via WMI
$reg = Get-WmiObject -ComputerName LEE-DESK `
    -Namespace rootdefault StdRegProv -List

## Get and set DWORD values on the remote machine
$reg.GetDWORDValue($HKEY_LOCAL_MACHINE,
    "SYSTEMCurrentControlSetControlTerminal Server",
    "fDenyTSConnections")

$reg.SetDWORDValue($HKEY_LOCAL_MACHINE,
    "SYSTEMCurrentControlSetControlTerminal Server",
    "fDenyTSConnections", 0)

For more information about the Get-RemoteRegistryChildItem, Get-RemoteRegistryKeyProperty, and Set-RemoteRegistryKeyProperty scripts, see Recipes , , and .

Program: Get Registry Items from Remote Machines

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 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

##############################################################################
##
## Get-RemoteRegistryChildItem
##
## From Windows PowerShell Cookbook (O'Reilly)
## by Lee Holmes (http://www.leeholmes.com/guide)
##
##############################################################################

<#

.SYNOPSIS

Get the list of subkeys below a given key on a remote computer.

.EXAMPLE

Get-RemoteRegistryChildItem LEE-DESK HKLM:Software

#>

param(
    ## The computer that you wish to connect to
    [Parameter(Mandatory = $true)]
    $ComputerName,

    ## The path to the registry items to retrieve
    [Parameter(Mandatory = $true)]
    $Path
)

Set-StrictMode -Version Latest

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

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

## Retrieve all of its children
foreach($subkeyName in $key.GetSubKeyNames())
{
    ## Open the subkey
    $subkey = $key.OpenSubKey($subkeyName)

    ## Add information so that PowerShell displays this key like regular
    ## registry key
    $returnObject = [PsObject] $subKey
    $returnObject | Add-Member NoteProperty PsChildName $subkeyName
    $returnObject | Add-Member NoteProperty Property $subkey.GetValueNames()

    ## Output the key
    $returnObject

    ## Close the child key
    $subkey.Close()
}

## Close the key and base keys
$key.Close()
$baseKey.Close()
      

For more information about running scripts, see Run Programs, Scripts, and Existing Tools.

Program: Get Properties of Remote Registry Keys

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 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

##############################################################################
##
## Get-RemoteRegistryKeyProperty
##
## From Windows PowerShell Cookbook (O'Reilly)
## by Lee Holmes (http://www.leeholmes.com/guide)
##
##############################################################################

<#

.SYNOPSIS

Get the value of a remote registry key property

.EXAMPLE

PS >$registryPath =
     "HKLM:softwareMicrosoftPowerShell1ShellIdsMicrosoft.PowerShell"
PS >Get-RemoteRegistryKeyProperty LEE-DESK $registryPath ExecutionPolicy

#>

param(
    ## The computer that you wish to connect to
    [Parameter(Mandatory = $true)]
    $ComputerName,

    ## The path to the registry item to retrieve
    [Parameter(Mandatory = $true)]
    $Path,

    ## The specific property to retrieve
    $Property = "*"
)

Set-StrictMode -Version Latest

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

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

## Go through each of the properties in the key
foreach($keyProperty in $key.GetValueNames())
{
    ## If the property matches the search term, add it as a
    ## property to the output
    if($keyProperty -like $property)
    {
        $returnObject |
            Add-Member NoteProperty $keyProperty $key.GetValue($keyProperty)
    }
}

## Return the resulting object
$returnObject

## Close the key and base keys
$key.Close()
$baseKey.Close()

For more information about running scripts, see Run Programs, Scripts, and Existing Tools.

Program: Set Properties of Remote Registry Keys

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 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

##############################################################################
##
## Set-RemoteRegistryKeyProperty
##
## From Windows PowerShell Cookbook (O'Reilly)
## by Lee Holmes (http://www.leeholmes.com/guide)
##
##############################################################################

<#

.SYNOPSIS

Set the value of a remote registry key property

.EXAMPLE

PS >$registryPath =
    "HKLM:softwareMicrosoftPowerShell1ShellIdsMicrosoft.PowerShell"
PS >Set-RemoteRegistryKeyProperty LEE-DESK $registryPath `
      "ExecutionPolicy" "RemoteSigned"

#>

param(
    ## The computer to connect to
    [Parameter(Mandatory = $true)]
    $ComputerName,

    ## The registry path to modify
    [Parameter(Mandatory = $true)]
    $Path,

    ## The property to modify
    [Parameter(Mandatory = $true)]
    $PropertyName,

    ## The value to set on the property
    [Parameter(Mandatory = $true)]
    $PropertyValue
)

Set-StrictMode -Version Latest

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

## Open the key and set its value
$key = $baseKey.OpenSubKey($matches[1], $true)
$key.SetValue($propertyName, $propertyValue)

## Close the key and base keys
$key.Close()
$baseKey.Close()

For more information about running scripts, see 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 the 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, this example 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). 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.

Process Monitor ready to capture

Figure 21-2. 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

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), and 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

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:SoftwareMicrosoftPowerShell1ShellIdsMicrosoft.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 performed only 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 Modify or Remove a Registry Key Value to automate these configuration settings, as in the following example:

PS > $key = "HKLM:SoftwareMicrosoftPowerShell1" +
    "ShellIdsMicrosoft.PowerShell"

PS > Set-ItemProperty $key ExecutionPolicy AllSigned
PS > Get-ExecutionPolicy
AllSigned
PS > Set-ItemProperty $key ExecutionPolicy RemoteSigned
PS > Get-ExecutionPolicy
RemoteSigned
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.117.78.237