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

OK, what I am trying to do is check for a registry value on a remote machine via WMI.

The problem I am having is that if the value is not present my script will just exit, with no error (or I am just not catching it).

For example, I am looking in HKLM\\CurrentControlSet\\Services\\SNMP\\Parameters\\TrapConfiguration\\public for the key "1" and then checking what the value of the key is to make sure SNMP is setup and working correctly. Now if the path I mentioned above exists, the script is happy and continues doing its thing but if the above path does not exist,things don't work out so well... And by exist I mean there is no folder called "public" under "TrapConfiguration" in the current server registry

Here is my code

use strict; use Win32::OLE; use Win32::OLE::Variant; use Net::Ping; use Date::EzDate; use Spreadsheet::WriteExcel; use warnings; use Win32::OLE qw(in with); sub regCheck { my $server = $_[0]; my $exists = 0; my $refRegistry = Win32::OLE->GetObject("winMgmts://$server/root/d +efault:StdRegProv" ) or die "cannot get object\n"; my @search = ('\\xxxxx','\\public'); my $HKEY_LOCAL_MACHINE = 0x80000002; my $strSKPath="SYSTEM\\CurrentControlSet\\Services\\SNMP\\Paramete +rs\\TrapConfiguration"; my $strValueName="1"; my $count = 1; foreach(@search) { my $value = Variant(VT_BSTR | VT_BYREF, ""); my $newPath = $strSKPath . $_; $refRegistry->GetStringValue($HKEY_LOCAL_MACHINE, $newPath,$strValueNa +me, $value); #Ignore this part #if($value != 0) #{ # print OUTFILE "Regvalue is null\n"; #} #else #{ #if($value =~ m/^*xxxxxx.com*+/) #{ # $exists = 1; #} #} $count++; } return $exists; }

Also to be clear, I am searching two places in the registry for the value I want. That is the reason for the foreach in the middle of the sub. In addition, the part commented out I have not worked on because I was trying to figure out why my script was failing at the specific line mentioned below.

What I have discovered is my script is stopping at this line if the path to the registry does not exist

$refRegistry->GetStringValue($HKEY_LOCAL_MACHINE, $newPath,$strValueName, $value);

I have learned that this line will return 0 if it is successful. And according to Microsoft this line will return either a null value or a value other than 0 if it fails. See here->http://msdn.microsoft.com/en-us/library/aa390788%28v=vs.85%29.aspx

What happens is it will return 0 if the path to search in the registry exists, which is what its suppose to do. But, if it cant find the path in the registry, it will just fail without seeming to return any error,or *anything* for that matter, and my script will terminate.

I have tried all different things to try and retrieve what this problem line is returning but I have been unsuccessful.

Does anyone have any idea whats happening and why my script would just exit? Also, im sorry if what I am trying to do is a little confusing I tried my best to explain everything but if you have any questions let me know. Thanks in advance for any suggestions!

-Matt

Replies are listed 'Best First'.
Re: Win32::OLE lookup registry value on remote machine via WMI
by dasgar (Priest) on Jun 16, 2011 at 16:21 UTC

    Are you sure that the code posted is the code that you ran? The reason for asking is that I see your posted code is doing two things: a) loading modules and pragmas; and b) defining a subroutine. Unless I missed it somewhere, you didn't call the subroutine in your posted code.

    Assuming that your actual code is calling the subroutine and it really is crashing the script, you might try encasing the call of the subroutine and/or that particular line of code checking the registry path inside an eval block to help trap the error and possibly get more details on the error.

    One more thought. You mentioned that you wanted to "check for a registry value on a remote machine via WMI". I personally haven't done much with WMI, but generally speaking you need to provide credentials to access a remote system. If two Windows systems have local user accounts with identical username and password, you might be able to get by without supplying credentials since Windows will try you're logged in with on the local machine when accessing remote systems. Anyways, I'm not seeing credential information in your posted code, which might be a contributing factor.

    One other thing that I'd check is to see if the remote registry service on the remote system is running. (Not sure if WMI utilizes that service or not.) Also, you might want to check firewall settings on the remote system.

      I only posted this sub with the modules I was using for reference, I am using it later in my script but I didn't want to post 300 lines of code.

      I did try using eval

      eval{$refRegistry->GetStringValue($HKEY_LOCAL_MACHINE, $newPath,$strVa +lueName, $value);}; print $@ if $@;

      But I still don't get any output :(

      I do have credentials to log into the machine because if the path to the registry value exists the sub works and returns a value. Also, if I don't call this sub the script works, I am also dumping services via WMI and that works

      if (my $oWMIService = Win32::OLE->GetObject("winmgmts:\\\\$computer\\r +oot\\CIMV2") or warn "Unable to open $computer\n" && next OUTER){ .. +do stuff ..} if(my $colItems = $oWMIService->ExecQuery ( "Select * from Win32_Servi +ce")) {..do stuff..}

      There really isint much info about using WMI in Perl out there and I appreciate your suggestions.

      -Matt