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.
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
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
By
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.
Ops, my fault ) Awaiting for further articles regarding how to edit the registry… Thanks for a great article!
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
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.
Ben, please post the complete command you are using, so that I will be able to comment better.
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 }
Ben, I got the correction made to the script. Try out the latest one by using the download link in the post.
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…
Thanks for your advice! I posted the similar script to yours here – powershellcommunity.org/Forums/tabid/54/aft/8120/Default.aspx
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