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

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 "(?\w+)\\(?.+)" | 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

25 Comments
  1. Avatar
    George E 11 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.

  2. Avatar
    George E 11 years ago

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

  3. Avatar Author
    techibee.com 11 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

  4. Avatar
    Ben M. 11 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.

  5. Avatar Author
    techibee.com 11 years ago

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

  6. Avatar Author
    techibee.com 11 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 }

  7. Avatar Author
    techibee.com 11 years ago

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

  8. Avatar
    Ben M. 11 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…

    • Avatar
      Deon 4 years ago

      Hi,

       

      Did you ever get this going, I'm in the same situation, would like to retrieve the  TLS 1.2 parameters (HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2) from moultiple servers 

      and if possible the latest .net version installed?

      and output all of this to file, related to each server.

       

      D

    • Avatar
      Swapnil 3 years ago

      Did you able to do it in this way ? I am struggling to get data in table format. current out put of this file is not convenient when working on multiple computer. please let me know if you or someone made it possible.

  9. Avatar
    Ben M. 11 years ago

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

  10. Avatar Author
    techibee.com 11 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

  11. Avatar
    rusty 10 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?

  12. Avatar
    swati 9 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.

  13. Avatar
    Slawek 7 years ago

    Hey,

     

    You’ve mentioned in your script: “.\Get-RemoteRegistry.ps1″ what’s that and what that script contain??

  14. Avatar
    Harish 6 years ago

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

  15. Avatar
    Gourav Pattnaik 6 years ago

    Its the name of the powershell script where you will put the above contents and run.

  16. Avatar
    Gourav Pattnaik 6 years ago

    Hello Sitaram,

    I ran the script, but I’m getting the following error

    PS C:\Script\Registry> Get-Content C:\Script\Registry\Computers.txt | .\Registry.ps1 -RegistryKey “HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters” -KeyProperty SMB1 | Out-File C:\Script\Registry\RegistryKeyOutput.txt

    Unable to determine base key type. Exiting

    I’m not sure, why the switch is not recording what I’m passing on command. Can you please help.

  17. Avatar
    Dan 6 years ago

    When I run the following command from my PC, with the downloaded script in the correct location and the computer listed in the provided location, the only output I get in the text file relates to my computername, which isn’t even included in the list.

    PS C:\WINDOWS\system32> Get-Content c:\scripts\computers.txt | % {c:\scripts\Get-Registry.ps1 -RegistryKey “HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\SystemCertificates\AuthRoot\” -KeyProperty DisableRootAutoUpdate | Out-file c:\scripts\result.txt -Append}

    Did a miss a step, or do something incorrectly?

     

  18. Avatar
    Erwin 5 years ago

    I dont think this runs with the new powershell 5

     

    • Avatar

      @Erwin

      This is probably not how we would do it 7 years after this article has been written but it still works with PowerShell 5.1.

      • Avatar
        Erwin 5 years ago

        it does not i get

        IsPresent     : False
        PropertyType  :
        ComputerName  : *******

        PropertyValue :
        PropertyName  : Shell

  19. Avatar
    Erwin 5 years ago

    Never mind..I am a dunce 🙁

     

     

     

  20. Avatar

    Hi, Will it work in Windows server 2019?.
    I am looking for the same script with excel output.

Leave a reply

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

*

© 4sysops 2006 - 2023

CONTACT US

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

Sending

Log in with your credentials

or    

Forgot your details?

Create Account