Search code examples
.netwindowspowershellregistry

Reading registry on a remote computer using its IP address -- strange behavior of OpenRemoteBaseKey


I'm trying to write an application that will get some registry values from a remote computer. The user can provide a hostname or IP in a string and should be getting a registry value displayed on their screen. When I was debugging the program, it turned out that it gives an error whenever the input I provide is either "localhost" or "127.0.0.1", but it works when I provide "mxcz", which is my computer name.

The application uses the OpenRemoteRegistryKey method in Microsoft.Win32.RegistryKey. I decided to isolate this line and just run it in PowerShell. You can see what happens in the picture below. These two PowerShell lines work:

[Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey([Microsoft.Win32.RegistryHive]::LocalMachine,127.0.0.1)

[Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey([Microsoft.Win32.RegistryHive]::LocalMachine,"mxcz")

These don't work:

[Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey([Microsoft.Win32.RegistryHive]::LocalMachine,"127.0.0.1")

[Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey([Microsoft.Win32.RegistryHive]::LocalMachine,localhost)

[Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey([Microsoft.Win32.RegistryHive]::LocalMachine,"localhost")

Using my actual LAN IP address 192.168.0.136 instead of 127.0.0.1 gives the exact same behavior. It works without the quotes and doesn't work in quotes.

It's clear to me, I think, why the second line works and why the fourth line doesn't. But I can't figure out why the first line works and why the third and the fifth don't. The Microsoft webpage for the OpenRemoteRegistryKey method clearly says that the second argument is supposed to be a string. Why doesn't "localhost" in quotes work then? Why does 127.0.0.1 without quotes work? I don't understand how the method interprets this value. Why doesn't "127.0.0.1" in quotes work?

And most importantly, how can I pass whatever the method needs to it, when the user input is a string, either "hostname" or "ipaddress" (preferably using the same variable regardless of which one the user decides to use)? Simply feeding it a string with the value "127.0.0.1" clearly doesn't work. Or should I use a different way of accessing a remote registry altogether?

This is on Windows 8.1, x64.

enter image description here

EDIT

In C# neither the quoted nor the unquoted version works. With the quotes, it will give the same error, "network path not found", and without them it won't compile, see below.

enter image description here


Solution

  • I think your issue is the error is misleading. One of the prerequisites of this working is that the remote registry service needs to be running.

    In order for a key to be opened remotely, both the server and client machines must be running the remote registry service, and have remote administration enabled.

    I would suggest on your own machine and target machines that you verify that service is running. I was able to replicate the issue by toggling the service off and on. When the method assumes localhost it works by accessing locally it seems. When it is explicitly stated it appears to attempt to use the service.

    Also you have to quote those string. Else PowerShell will attempt to evaluate the text as an exe/function/cmdlet etc. Just type in localhost or 127.0.0.1 and you will get errors from the parser. In the case of the latter:

    The property '0.1' cannot be found on this object. Verify that the property exists.
    

    This is the same error I get for one of your working examples... which unfortunately doesnt seem to help

    PS D:\temp> [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey([Microsoft.Win32.RegistryHive]::LocalMachine,127.0.0.1)
    The property '0.1' cannot be found on this object. Verify that the property exists.
    At line:1 char:1
    + [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey([Microsoft.Win32.RegistryHive]: ...
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : NotSpecified: (:) [], PropertyNotFoundException
        + FullyQualifiedErrorId : PropertyNotFoundStrict