POLL: POWERSHELL VS. GUI - DO YOU WANT TO BE A DEVOP OR AN ADMIN?

Retrieve the registry keys from remote computers via PowerShell

In this article, I am going to talk about a PowerShell script that displays details of a given registry key. The script can retrieve the registry key not only from a local computer but also from a remote computer.

A picture of Sitaram Pamarthi By Sitaram Pamarthi - Mon, July 9, 2012 - 10 comments

Sitaram Pamarthi is working as a Windows Engineer and his special fields of interest are PowerShell, Active Directory, Exchange, and virtualization.

The Registry is very handy for administrators. For example, if you want to prevent an Outlook plug-in from starting, you can achieve this by setting a registry key. But you can do much more, including manage IE settings, display the installed software, and perform many other administrative tasks. In light of the Registry’s many benefits, I have written a PowerShell script that queries the given registry values from a list of computers.

You can control the script with three parameters. Two of them (RegistryKey and KeyProperty) are mandatory. The third (ComputerName) is optional.

RegistryKey is the path to the registry key where the required registry key properties are located. For example, consider the following registry key:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\AutoAdminLogon.

The key decides if automatic logon is active, and it has two possible values (enabled/disabled). The “HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\” part is the RegistryKey; the remaining part, “AutoAdminLogon,” is the KeyProperty.

If you want to query the value of AutoAdminLogon, you have to submit both parts as parameters to the script. If you want to retrieve the registry key of a remote computer, you also have to provide a value to the –ComputerName parameter. If the parameter is not set, the script will operate on the local computer.

Split the registry key

After processing the parameters, I use a regular expression to separate basekey and subkey. I need both values in my script later. A switch statement processes the basekey value and generates the equivalent string that the [Microsoft.Win32.RegistryKey] class can understand.

$RegistryKey -match “(?<BaseKey>\w+)\\(?<SubKey>.+)” | Out-Null

switch($Matches.BaseKey) {

“HKEY_LOCAL_MACHINE” {$BaseKey = “LocalMachine”}

“HKEY_USERS” {$BaseKey = “Users”}

“HKEY_CLASSES_ROOT” {$BaseKey = “ClassesRoot”}

“HKEY_CURRENT_USER” {$BaseKey = “CurrentUser”}

“HKEY_CURRENT_CONFIG” {$BaseKey = “CurrentConfig”}

default {

write-host “Unable to determine base key type. Exiting”

exit(1)

}

}

Connect to the remote computer and retrieve the key

Now let us enter the main part of the script. This part of the script connects to the remote base registry and navigates to the required sub registry key. I am using the [Microsoft.Win32.RegistryKey] base class for connecting to the remote registry. When the connection initializes, we need to provide two variables: the computer name and the base key (for example, LocalMachine or LocalUser). After connection has been established successfully, we can directly navigate to the sub registry key that stores the value we are looking for. After obtaining the object of the registry subkey, we need to query all the key properties inside the subkey to find out if the key we are querying is present. When it is found, the variable $flag is set to $true and the following code queries the value of the registry key property using the GetValue method. It also determines the type of the key by using the GetValueKind method. The type indicates whether the value is STRING, DWORD, or BINARY.

Once these details are collected, a custom object is created with the properties ComptuerName, PropertyName, PropertyValue, PropertyType, and IsPresent and the values are assigned to these properties accordingly. Though all properties are self-explanatory, I want to specifically mention something about IsPresent; this parameter indicates if the registry key we are querying for is present or not. If the key exists, the other properties of the object are populated with the corresponding values; otherwise, they will be empty.

if(Test-Connection -ComputerName $Computer -count 1 -ea 0) {

$flag = $false

$BaseKeyObj = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey($BaseKey, $computer)

$KeyObj = $BaseKeyObj.OpenSubKey($Matches.SubKey)

if($KeyObj) {

foreach ($Property in $KeyObj.GetValueNames()) {

if($KeyProperty -contains $Property) {

$flag = $true

}

 

}

} else {

Write-Warning “$($Matches.SubKey) not found on $Computer”

}

if($flag) {

$PropertyType = $KeyObj.GetValueKind($KeyProperty)

$PropertyValue = $KeyObj.GetValue($KeyProperty)

}

$OutputObj = New-Object PSObject -Prop (

@{

ComputerName = $Computer.ToUpper()

PropertyName = $KeyProperty

PropertyValue = $PropertyValue

PropertyType = $PropertyType

IsPresent = $flag

})

At the end of script, I print the custom object we just generated.

If you have a list of remote computers and you want to feed them to the script, you just need to execute the following command:

Get-Content c:\scripts\Computers.txt | .\Get-RemoteRegistry.ps1 -RegistryKey “HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon” -KeyProperty AutoAdminLogon

If you want to send the output of the script to a text file, you need to use the pipe and Out-File as shown below:

Get-Content c:\scripts\Computers.txt | .\Get-RemoteRegistry.ps1 -RegistryKey “HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon” -KeyProperty AutoAdminLogon | Out-File C:\scripts\RegistryKeyOutput.txt

Retrieve the registry keys from remote computers via PowerShell - Get-RemoteRegistry

Output of PowerShell script to retrieve a remote registry key

It is simple to get the value of a registry key, but modifying it is more complex. In my next post, I will provide a script that you can use to change the value of a registry key on remote computers. I hope this script is helpful to you, and I hope you enjoy learning PowerShell.

Download the PowerShell script to read registry keys

Your question wasn't answered? Ask in the new 4sysops forum!

10 Comments - Leave a Reply

  1. George E says:

    It’s a great way, but how can I edit Windows Registry?
    I found a solution: Remote Registry Manager, a part of AdminToys Suite softwaer.

  2. George E says:

    Ops, my fault ) Awaiting for further articles regarding how to edit the registry… Thanks for a great article!

  3. techibee.com says:

    George, the article regarding how to edit the registry is online now.
    http://4sysops.com/archives/create-and-modify-registry-keys-in-remote-computers-using-powershell/

    Thanks,
    Sitaram

  4. Ben M. says:

    When I use Get-Content and supply my servers.txt file, the script only reads the first line of the file and will not continue to the rest of the list.

  5. techibee.com says:

    Ben, please post the complete command you are using, so that I will be able to comment better.

  6. techibee.com says:

    Ben, I understood where the problem is. I will get it corrected.

    Meantime you can use the below to process all computers in servers.txt

    get-content c:\servers.txt | % { .\Get-RemoteRegistry.ps1 -ComputerName $_ -RegistryKey “HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon” -KeyProperty AutoAdminLogon | Out-File C:\scripts\RegistryKeyOutput.txt -Append }

  7. techibee.com says:

    Ben, I got the correction made to the script. Try out the latest one by using the download link in the post.

  8. Ben M. says:

    Hey… thanks for the quick turn around! =) That did the trick on your post.

    I’ve been playing around with various scripts all morning, but I’d like to be able to share my code with you. My end goal is to be able to query sets of machines for all keys below a reg path and output to CSV for filtering. I have the main part working but I can only send the output to the console. I am having trouble with properly sending to CSV.

    Building off poshcode.org/615 – I get-content from servers.txt and want to have a table like the following that has dynamic number of columns depending upon the included registry keys in that path:

    Example path = HKLM\SYSTEM\CurrentControlSet\Control\Power\

    Example CSV output =
    Hostname | Subkeys | CustomizeDuringSetup | HiberFileSize
    —————————————————-
    server1 | (ListAllSubkeys)| Value1 | Value2
    server2 | (subkey1,subkey2…

  9. Ben M. says:

    Thanks for your advice! I posted the similar script to yours here – powershellcommunity.org/Forums/tabid/54/aft/8120/Default.aspx

  10. techibee.com says:

    In case somebody is looking for a way to read default registry values(one looks like (default)in regedit) of a registry key, please take a look at http://techibee.com/powershell/read-remote-registry-key-default-values-using-powershell/1913

===Leave a Comment===