Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

cleanest/most efficient way to do this

by RayRay459 (Pilgrim)
on Jan 26, 2002 at 00:32 UTC ( [id://141632]=perlquestion: print w/replies, xml ) Need Help??

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

Fellow Monks,
i am in need of your assistance. I want to write a script that will need to do multiple tasks, not all at once.
  • I am going to connect to a pdc and get it to dump a list of machines it has as memebers of the domain.
  • for each machine it has listed in the domain i am then going to do a ip address lookup and pipe the results to a text file.
  • From there i want to ping the machines to see if they are still alive. and pipe the results to a text file. (we have gone through about 200 old machine names as we recycle hardware from production to qa and also introduce new machines to production.)

    So with all that in mind, would it make more sense and also be cleaner if i created a module with all the work that i wanted done and call on it from the script? i have scripts that will do everything that i want to do except for the pinging hosts. I will research and try to impliment Net::Ping. Any advice would be greatly appreciated. I have never created a module, so any advice on how to get it started would be great appreicated also. I will post final code once i figure out the best way to do this. Thnx in advance
    Ray
  • Replies are listed 'Best First'.
    Re: cleanest/most efficient way to do this
    by tradez (Pilgrim) on Jan 26, 2002 at 00:39 UTC
      Well I think that setting up simple methods to grab the info from the pdc would be the best manner. As for doing the name lookups and pinging the host. Why not be simple and just
      $ping = `ping $host`; $nslookup = `nslookup $host`;
      Then you can printout the return, regex it, parse it, do whatever you want. No need to use Net::Ping or anything on a task as simple as this. Simple fill and array with all the hosts form the dumpfile, then
      foreach my $host (@hosts) { $ping = `ping $host`; $nslookup = `nslookup $host'; print "Ping result is $ping \n"; print "Nslookup result is $nslookup for host $host \n"; }
      Hopefully I helped some.
      P.S. Make sure you are using ` and not ' around those system commands, to pipe it to the system and not just assing a var.
      Tradez
      "Never underestimate the power of stupidity"
      - Bullet Tooth Tony, Snatch (2001)
        Tradez
        Thank you for taking the time to answer my posting. Your advice is very much appreciated. since i would consider myself an almost middle tier Perl hack, i want to try to stay away from using system calls. i too think that would be the quickest and easiest way to complete this, but i am trying to use this as a means to grow my Perl skills. hence possibly trying to create my own module with scripts i already have made... :-) (maybe).
        Thnx again though for the advice.
        Ray
    Re: cleanest/most efficient way to do this
    by Necos (Friar) on Jan 26, 2002 at 01:09 UTC
      To add to the last comment, if you are not using perl 5.6 or higher, the Win32::AdminMisc module written by Dave Roth (which you can get here), as well as the Win32::NetAdmin module have about 90% of the functions you'll need. The only thing either will not do is ping the machines for you, but that's what qx() or the backticks are for (personally, I like qx() more).

      Hope that helps some...

      Theodore Charles III
      Network Administrator
      Los Angeles Senior High
      4650 W. Olympic Blvd.
      Los Angeles, CA 90019
      323-937-3210 ext. 224
      email->secon_kun@hotmail.com

        but that's what qx() or the backticks are for (personally, I like qx() more).

        I understand what you're trying to say, but some beginners reading this might think backticks and qx() are two different things. Backticks and qx() are the same. qx() is an operator, `` is its shorthand. In fact, any non-whitespace character can be used as a delimiter (if it's alphanumeric, whitespace before the delimiter is required). qx() is not a function - my $dir = qx("ls -l") will probably not do what you want.

        `ls -l` qx(ls -l) qx[ls -l] qx`ls -l` qx$ls -l$ qx!ls -l! qx nls -ln
        More info: perlop

        2;0 juerd@ouranos:~$ perl -e'undef christmas' Segmentation fault 2;139 juerd@ouranos:~$

        Necos,
        Thank you for answering my posting. Since i work for a large company and this is for our production environment, they will not let me add a module to the machines with out it being in QA for a month. and even that gets pushed off. here's some of the code i have been using for the pdc dump and ipaddress lookup :
        #!D:\Perl\bin -w use strict; use Win32::NetAdmin; open (OUT,">list.txt") || die "Cannot create machine list. :$!"; # This will get the list of machine names from the PDC my @users; Win32::NetAdmin::GetUsers("\\\\Weasel",'',\@users); my @computers = grep { /\$$/ } @users; foreach my $box (@computers) { chop $box; # removes terminal char, must be $ from grep print OUT "$box\n"; # print each $box on a newline } close OUT;

        # this will take a file and read it in and resolve hostname # to ip address ##################################################################### print "What file do you want to read?"; chomp($InFile = <STDIN>); open(IN,$InFile) || die "Cannot open $InFile: $!"; open(OUT,">results.txt") || die "Cannot create results.txt: $!"; while (<IN>) { my $hostname = $_; chomp $hostname; @addr = gethostbyname($hostname); # note: an array now splice(@addr, 0, 4); # get rid of other stuff foreach (@addr) { print OUT join('.', unpack('C4', $_)) ."\t" . $hostname . "\n" +; } } close(IN); close(OUT);
    Re: cleanest/most efficient way to do this
    by Necos (Friar) on Jan 26, 2002 at 02:19 UTC
      Well, if you really want to get into some Win32 Perl hacking, you can use Win32::Registry to get at some nice tidbits in the registry concerning the ip number and all. I don't remember if the Browser service dumps a list of computernames to the registry, so I'll have to double-check that. I'll cook you up a script or module in a few hours (once I finish some module rebuilding for my own project). Unfortunately, I found out one of the small quirks of Win32::Registry (which is one of the reasons why people advocate Win32::TieRegistry instead). In the module, GSar hardwires all of the registry objects into the main space (or main symbol table). So, if you do write a module you'll have to do:

      my $HKLM = Win32::Registry::_new(&HKEY_LOCAL_MACHINE); # _new is a pri +vate constructor defined in the module
      You'll have to do this for every root registry object. Instead of pinging the machine, you can do a remote connection with Connect method and write the results to file. Also, if you really want to get into the registry without using Win32::Registry, you can use Win32API and load the win32.dll file, which contains all of the functions in the Win32::Registry module. The only bad thing is that you'll have to look up the registry calls in the MSDN library to know what structure to throw at win32.dll.

      On another note, I should have made it clear that qx() and backticks are, in fact, the same thing. I just like to use qx(), with parens as the normal delimiters, because it's usually the easiest to read. Of course, you can do qx##, qx**, qx$$, or whatever (so long as the delimiters match... also, you might want to stay away from certain delimiters since you might confuse them with variables/typeglobs/etc.). They will do exactly the same thing. Thanks Juerd for pointing out that little error.

      Theodore Charles III
      Network Administrator
      Los Angeles Senior High
      4650 W. Olympic Blvd.
      Los Angeles, CA 90019
      323-937-3210 ext. 224
      email->secon_kun@hotmail.com
    Re: cleanest/most efficient way to do this
    by Necos (Friar) on Jan 27, 2002 at 02:59 UTC
      Sorry for taking so long to get back to you on your code. My job got the best of me yesterday and I didn't get home until 1AM. But, without further ado, here's the updated code.
      use strict; use Win32::NetAdmin; use Win32::Registry; #Yes, I know it's obsolete, but it's so darn cool +! #This is part of the original code... No need to edit this part. open (OUT,">list.txt") || die "Cannot create machine list. :$!"; # This will get the list of machine names from the PDC my @users; Win32::NetAdmin::GetUsers("\\\\Weasel",'',\@users); my @computers = grep { /\$$/ } @users; foreach my $box (@computers) { chop $box; # removes terminal char, must be $ from grep print OUT "$box\n"; # print each $box on a newline } close OUT; #This is the get-ip routine using Win32::Registry #(included in libwin32, so you shouldn't have any problems with instal +ling it). #The logic is: If you can connect to machine remotely, and snag it's i +p, #it's alive and running. In other words, it's a different kind of "pin +g" print "What file do you want to read?"; chomp($InFile = <STDIN>); open(IN,$InFile) || die "Cannot open $InFile: $!"; open(OUT,">results.txt") || die "Cannot create results.txt: $!"; while (<IN>) { chomp; my $remote_obj; my $host = $_; #We need a copy of $_ to log the hostname $main::HKEY_LOCAL_MACHINE->Connect($_, $remote_obj); #Hardwired in +to main:: namespace my $ip_obj; $remote_obj->Open('SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Par +ameters\\Interfaces' , $ip_obj) || print "open key failed\n"; my $regkeys = []; $ip_obj->GetKeys($regkeys); foreach (@$regkeys) { my $temp_obj; my $ip; $ip_obj->Open( "$_", $temp_obj); $temp_obj->QueryValueEx( 'IPAddress' , REG_MULTI_SZ, $ip ); $ip =~ s/^\s//; #Strip out leading whitespace (if at all) $ip =~ s/\s$//; #Strip out trailing whitespace (if at all) print OUT "$ip\t$host\n" if ( not ($ip =~ /^[0]/) ); } } close(IN); close(OUT);
      This goes to show you one of the perks of working on a Win32 system: everything is in the registry if you look hard enough. I tested the code to work under strict, so everyone is happy. Not only that, but I combined finding out the ip and the ping into one step with the registry calls. I've only tested it with one computer, but it should work for you without much tweaking (if at all).

      Theodore Charles III
      Network Administrator
      Los Angeles Senior High
      4650 W. Olympic Blvd.
      Los Angeles, CA 90019
      323-937-3210 ext. 224
      email->secon_kun@hotmail.com
        Necos,
        Thnx for taking the time to write the code. It is greatly appreciated. That's a cool way to get ip info and check to see if its alive. i would have never thought to do that. Guess that's one of the coolest things about Perl..... there are so many ways to do something. :)
        Thnx again.
        Ray

    Log In?
    Username:
    Password:

    What's my password?
    Create A New User
    Domain Nodelet?
    Node Status?
    node history
    Node Type: perlquestion [id://141632]
    Approved by root
    help
    Chatterbox?
    and the web crawler heard nothing...

    How do I use this?Last hourOther CB clients
    Other Users?
    Others cooling their heels in the Monastery: (8)
    As of 2024-04-25 10:58 GMT
    Sections?
    Information?
    Find Nodes?
    Leftovers?
      Voting Booth?

      No recent polls found