PERL script problem

Hi all, i wrote this script and the code appears to work except i cannot connect to the WMI interface on Windows XP boxes. The listing is printed for testing purposes so i know that part works. When it tries to connect to WMI, the script dies. Should echo these properties to me. I think the problem is in the array, but not sure how to fix it. Can you all help?

use Win32::OLE('in');
use constant wbemFlagReturnImmediately => 0x10;
use constant wbemFlagForwardOnly => 0x20;
#use Win32::AdminMisc;

#Read from your selected file, make sure the path is right; you must use \\ or UNC \\\\
$computer="c:\\list\\hosts.txt \n";
open(DATA,$computer) or die "Could not open File!, check the path! \n";
@raw_list=<DATA>;
print @raw_list;
close(DATA)

foreach($computer, @raw_list); 
$objWMIService = Win32::OLE->GetObject
    ("winmgmts:\\\\$computer\\root\\CIMV2") or die "WMI connection failed.\n";
$colItems = $objWMIService->ExecQuery
    ("SELECT * FROM Win32_OperatingSystem","WQL",wbemFlagReturnImmediately | wbemFlagForwardOnly);

foreach my $objItem (in $colItems)
{
      print "Caption: $objItem->{Caption}\n";
      print "CSD Version: $objItem->{CSDVersion}\n";
      print "CS Name: $objItem->{CSName}\n";
      print "Name: $objItem->{Name}\n";
      print "Service Pack Major Version: $objItem->{ServicePackMajorVersion}\n";
      print "System Directory: $objItem->{SystemDirectory}\n";
      print "Windows Directory: $objItem->{WindowsDirectory}\n";
      print "\n";
}

thanks for whatever help you can provide.

dont beat me to profusely with a stick; its not under my control that they are all Windows boxes :smiley:

foreach($computer, @raw_list)
{
   $objWMIService = Win32::OLE->GetObject
       ("winmgmts:\\\\$computer\\root\\CIMV2") or die "WMI connection failed.\n";
   $colItems = $objWMIService->ExecQuery
       ("SELECT * FROM Win32_OperatingSystem","WQL",wbemFlagReturnImmediately | wbemFlagForwardOnly);

   foreach my $objItem (in $colItems)
   {
         print "Caption: $objItem->{Caption}\n";
         print "CSD Version: $objItem->{CSDVersion}\n";
         print "CS Name: $objItem->{CSName}\n";
         print "Name: $objItem->{Name}\n";
         print "Service Pack Major Version: $objItem->{ServicePackMajorVersion}\n";
         print "System Directory: $objItem->{SystemDirectory}\n";
         print "Windows Directory: $objItem->{WindowsDirectory}\n";
         print "\n";
   }
}

Perl doesn't have the foreach() loop syntax like that, I think. It looks more like Javascript or PHP than Perl. I guess you should try to quote any error messages if any, and indicate which line the error exists. The segment you posted does not appear to be a correct Perl program.

I tried that and get a 255 error.

if i change it to foreach(@raw_list) or foreach($computer) i get an error 9

here is the error, substitute 255 for the 9

WMI connection failed.
host1
host2
host3
Exit code: 9 , 0009h

I'm sure it is with the array, but damn if i can figure it out! :slight_smile: Where do i find the system error codes such as 9 or 255?

EDIT: ok, i ran the script with perl -w and this is what i received

Odd number of elements in hash assignment at retina.pl line 21, <DATA> line 3.
Win32::OLE(0.1707) error 0x80041021
after character 0 in "winmgmts:\\c:\list\hosts.txt
\root\CIMV2" at retina.pl line 30
eval {...} called at retina.pl line 30
WMI connection failed.

so basically, what i gather from this is that it may not even be connecting to the WMI service to begin with? And for some reason it is reading what is supposed to be a hostname as the literal filename and path. Am i on the right track here?

thank you

Hi, cbkihong.

An aside.

I thought so at first also, so I wrote a short script to see what happened:

#!/usr/bin/perl

# @(#) perl-basic       Template for common usage.

# use warnings;
# use strict;

my($debug);
$debug = 0;
$debug = 1;

my(@a) = qw/ a b c d e /;
my($a) = @a;

foreach my $i ( in $a ) {
        print " i is :$i:\n";
}

exit(0);

which produced:

% ./p1
Can't locate object method "in" via package "a" (perhaps you forgot to load "a"?) at ./p1 line 15.

That seems to be something to do with the OO features of perl, with which I am not sufficiently familiar to be able to provide an explanation. I perused Schwartz' Intermediate perl, but found nothing on-point so far.

I think we both looked at this and saw a corruption of the foreach with syntax from some other language. However, almost anything seems to be legal in perl. So, at least from my perspective, I was led to the wrong conclusion by assuming a syntax infraction.

Even if one enables strict and warnings, the same message is produced ... cheers, drl

thanks for the help on this; i actually used that particular foreach example from a PERL book i had gotten. Bear in mind i am NOT much of a PERL programmer but definitely trying to learn.

here is the final script that at least goes all the way through the script without erroring except RPC server not available. Strange, i think i need to add some DNS checking or something to resolve the hostname or NBT.

use Win32::OLE;
use Win32::OLE('in');
use constant wbemFlagReturnImmediately => 0x10;
use constant wbemFlagForwardOnly => 0x20;
#use Win32::AdminMisc;

#Read from your selected file, make sure the path is right; you must use \\ or UNC \\\\
#$computer="gws-379txt1337";
open(DATA,"<hosts.txt \n") || die "Could not open File!, check the path! \n";

while( my $computer = <DATA>)
{
print $computer;
foreach $computer(in(<DATA>))
{
$objWMIService = Win32::OLE->GetObject
("winmgmts:\\\\$computer\\root\\CIMV2") || die "WMI connection failed.\n";
$colItems = $objWMIService->ExecQuery
("SELECT * FROM Win32_OperatingSystem","WQL",wbemFlagReturnImmediately | wbemFlagForwardOnly);

foreach my $objItem (in $colItems)
{
print "Caption: $objItem->{Caption}\n";
print "CSD Version: $objItem->{CSDVersion}\n";
print "CS Name: $objItem->{CSName}\n";
print "Name: $objItem->{Name}\n";
print "Service Pack Major Version: $objItem->{ServicePackMajorVersion}\n";
print "System Directory: $objItem->{SystemDirectory}\n";
print "Windows Directory: $objItem->{WindowsDirectory}\n";
print "\n";
}
}
}
close(DATA)

as i mentioned above, i get an RPC error and also another strange thing;

the hostnames are listed like :

the-999the-9999
the-thisis5678
th-999www9087

those are of course exampled of the format...but should i build some checking for dashes too? the computer name DOES get read into the script, i just get the RPC error on most except the example the-999the-9999.

thanks