Shade has asked for the wisdom of the Perl Monks concerning the following question:

I'm trying to query the registry of 2 remote machines: one is XPSP2 and the other is Vista. The following code works okay on the XPSP2 box, after tweaking some of the security settings, but I'm not getting it to work with the Vista box.
#! c:\perl use strict; use warnings; my $Registry; use Win32::TieRegistry 0.24 ( TiedRef => \$Registry, Delimiter=>"/", ArrayValues => 1, SplitMult +is => 1, AllowLoad => 1, qw( REG_SZ REG_EXPAND_SZ REG_DWORD REG_BINARY REG_MULTI_SZ KEY_READ +KEY_WRITE KEY_ALL_ACCESS ), ); # ... $pc = remote machine name ... my $regKeyName = 'HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows/Curren +tVersion/Uninstall/'; print STDERR "Checking the registry on $pc.\n"; my $remKey= $Registry->Connect( $pc, $regKeyName, { Access=>Win32::TieRegistry::KEY_READ() } ) or Carp::croak("!! Couldn't connect to $pc or can't open reg key ($r +egKeyName).\n". "!! - Is File and Printer Sharing enabled?\n$^E\n");
I get the following message:
The system could not find the environment option that was entered

It doesn't seem to currently be a problem with Windows Firewall, as I turned it off and got the same message. At least the firewall is not the only problem. I've also added read permissions to HKEY_LOCAL_MACHINE\SOFTWARE\ on the Vista machine for Guest and Everyone, just in case this was the issue. I'm running out of ideas of how to get this to work.

Does anyone have suggestions? Ideally I'd only open up the permissions in Vista just enough to allow this to work.

I'm using ActivePerl 5.8.8 Build 819 and Win32::TieRegistry 0.24

Thanks much,
Jonathan

Replies are listed 'Best First'.
Re: Win32::TieRegistry and Vista (stabs)
by tye (Sage) on Jan 23, 2007 at 04:58 UTC

    My first guess would be that you aren't using $^E fast enough and its value is getting overwritten before you report it. This can happen quite quickly. However, if your code is exactly as written, then you are copying the string value of $^E to be part of the string you pass to croak() very quickly, so that seems unlikely. Just in case the unlikely isn't impossible, you might instead add the following code and replace your use of $^E with regLastError():

    use Win32API::Registry qw( regLastError KEY_READ );

    (which also means that you can use KEY_READ() without having to prepend the lengthy Win32::TieRegistry:: to it.) regLastError() doesn't get overwritten by random Perl actions unlike $^E does.

    More likely, Vista disables remote access to the Registry. Can you remotely access the Registry from regedt32/regedit ? I have vague memories of having to turn on this access but I don't recall the details at this time. Hmm, actually that was probably for an old system... but I wouldn't be surprised if something similar were required for Vista as MicroSoft has been disabling a growing number of features in the name of security. This is supported by this item turned up by google: http://www.tabletquestions.com/windows-vista/10066-unable-access-hklm-registry-key-remotely.html

    Just to throw out some other ideas that occurred to me but that likely aren't the problem...

    Another consideration is the credentials used to connect to the system. Using a command like "net use \\pcname /user:domain\username *" (enter your password when prompted) before running your script can resolve some security issues, especially if you have a more privileged login for use on that machine than the one you are currently using.

    I'd also consider looking at the "advanced" privileges associated with your username on that system. I rather expect that Vista doesn't give admins access to remotely access the registry by default. The tools used to control these individual privleges have been shifting so I doubt what works in Vista is what I've used (and I'd have to go look up what I use anyway). But I'd expect that this problem would give a cleared "permission denied" type of error reason.

    - tye        

      I added the reference to Win32API::Registry and updated the connect call:
      my $remKey= $Registry->Connect( $pc, $regKeyName, { Access=>Win32::TieRegistry::KEY_READ() } ) or Carp::croak("!! Couldn't connect to $pc or can't open reg key ($r +egKeyName).\n". "!! - Is File and Printer Sharing enabled?\n". Win32API::Registry::regLastError(). "\n");

      Please forgive the package names in the code. This is actually part of my first Perl program (tm), and I applied a package name to my code, so I've been fully qualifying variables from config files, etc.)

      I'm now getting a more explicable error message, Access is denied. I tried using regedit to connect remotely to the Vista box, and was denied access, so this appears to be the root cause, and gives me a quick reality check.

      I will reply once I figure out how to fix the permission issue.

      --- Update 1/23, 13:26 ---

      On the Vista box, I started the Remote Registry Service and set it to Automatic. Now I can connect to the Vista registry remotely, using regedit; however...

      I only have access to HKEY_USERS/ and its subkeys. Frustratingly, HKEY_LOCAL_MACHINE is visible, but presents the following error when I try to access it, Cannot open HKEY_LOCAL_MACHINE: Error while opening key. I've tried tweaking various local security policy settings. I guess this is more of a Windows question at this point. I will try pursuing it further on a Windows forum.

Re: Win32::TieRegistry and Vista
by almut (Canon) on Jan 23, 2007 at 00:08 UTC

    Not that I really know...   just something to ponder over, until other monks are going to come up with better suggestions :)

    "The system could not find the environment option that was entered" is the system error message #203, aka ERROR_ENVVAR_NOT_FOUND (personally, I find the latter short form easier to understand - but that's another issue). So, maybe you're trying to access (directly or indirectly) some environment variable, which doesn't exist in that context... for example, how do you construct your $pc?   Or something like that.

    OTOH, I've also occasionally seen this message show up under the most ridiculous circumstances, so I could be entirely off-base...

    Good luck anyway.

      Good suggestions...

      I define the machine names within a config file, in an array of hashes. I'm calling $Registry->Connect from within a subroutine, which is called from a loop that pulls the names out of the array. I went back and doubled checked the machine names, and they are correct. I also just double checked that the registry key name didn't change between XPSP2 and Vista, and the key names are the same.

      Fortunately, neither was the issue, and I don't feel too dumb, yet. :) However, that eliminates a really easy fix.