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.

Sitaram Pamarthi

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

Win the monthly 4sysops member prize for IT pros

Share
1+

Related Posts

14 Comments
  1. George E 5 years ago

    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.

    0

  2. George E 5 years ago

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

    0

  3. Author
    techibee.com 5 years ago

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

    Thanks,
    Sitaram

    0

  4. Ben M. 5 years ago

    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.

    0

  5. Author
    techibee.com 5 years ago

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

    0

  6. Author
    techibee.com 5 years ago

    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 }

    0

  7. Author
    techibee.com 5 years ago

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

    0

  8. Ben M. 5 years ago

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

    0

  9. Ben M. 5 years ago

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

    0

  10. Author
    techibee.com 5 years ago

    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

    0

  11. rusty 4 years ago

    Guys:
    I know this is an old post but... so I am using powershell with foreach on list of machines and i need to query remote base key on the ones in list. The problem is I want to invoke diffrent credentials for elevated rights.

    $Details = @()
    $vmCount = 0
    $remCreds = Get-Credential -Credential naipaper\ -ErrorAction Stop
    foreach ($fieldVc in $fieldVcs)
    {
    $vmCount++
    Write-Host "Getting DB $vmCount for host $($fieldVc.srvName)" -foregroundcolor red -backgroundcolor yellow

    $vcdbprops = @{
    VC_Name = $fieldVc.srvName
    DB_Server = ""
    DB_Instance = ""
    DSN_Name = ""
    }
    $props = New-Object psobject -Property $vcdbprops

    $hklm = invoke-command [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $fieldVc.srvName) -Credential $remCreds

    $vcReg = $hklm.OpenSubKey("SOFTWARE\\VMware, Inc.\\VMware VirtualCenter")
    $vcRegDB = $hklm.OpenSubKey("SOFTWARE\\VMware, Inc.\\VMware VirtualCenter\\DB")
    $odbcReg = $hklm.OpenSubKey("SOFTWARE\\ODBC\\ODBC.INI\\" + $vcRegDB.GetValue(1))

    $props.DB_Server = $odbcReg.GetValue("Server")
    $props.DB_Instance = $vcReg.GetValue("DBInstanceName")
    $props.DSN_Name = $vcRegDB.GetValue(1)

    $Details += $props

    Can someone help me to invoke elevated rights in my foreach?

    0

  12. swati 3 years ago

    hi,

    i need to get the value of "ScreenSaveTimeOut" from the below registry path across multiple computers:
    HKCU:\Software\Policies\Microsoft\Windows\Control Panel\Desktop\

    can you please help with it?

    thanks.

    0

  13. Slawek 11 months ago

    Hey,

     

    You've mentioned in your script: ".\Get-RemoteRegistry.ps1" what's that and what that script contain??

    0

  14. Harish 2 weeks ago

    Works like Charm..Superb Script..Saved My Job. 🙂

    0

Leave a reply

Your email address will not be published. Required fields are marked *

*

CONTACT US

Please ask IT administration questions in the forum. Any other messages are welcome.

Sending
© 4sysops 2006 - 2017

Log in with your credentials

or    

Forgot your details?

Create Account