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.
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
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.
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"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.
You want to modify or remove a property of a specific registry key.
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
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.
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.
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.exeIn 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.
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 SpywareAs 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.
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.
You have several related registry modifications, and want them to group them so that either they all apply, or none apply.
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 {}Not working on XP, please see my comment in Chapter 30.
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.
You want to add a site to a specific Internet Explorer security zone.
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
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

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.
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”.
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 1Internet 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”.
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:
Directories have items; items have content.
Registry keys have properties; properties have values.
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
}
}
}
Why not use hash for new object properties. The more it will be visible the more people will use it.
For more information about running scripts, see the section called “Run Programs, Scripts, and Existing Tools”.
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 ....
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”.
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 .
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”.
You want to work with the registry keys and values of a remote computer.
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
---------------
RemoteSignedAlthough 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”.
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”.
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”.
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”.
You want to automate the configuration of a program, but that program does not document its registry configuration settings.
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.
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.
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

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

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.
Click OK, Apply, or whatever action it takes to actually complete the program's configuration. For the PowerShell example, this means pressing Enter.
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.
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.
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

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
No comments yet
Add a comment