LISTING 1: The WINSer.pl Perl Script

use Win32;
require 'NT.ph';

(@ARGV) or &PrintHelp;

$primary = $ARGV[0];
$secondary = $ARGV[1];
if ($ARGV[2]) {
  if (lc($ARGV[2]) eq "remote") {
    @machines = ($ARGV[3]);
  } elsif (lc($ARGV[2]) eq "file") {
    open(FILELIST, "<$ARGV[3]") or
        die "Unable to read file $ARGV[3] for list of ".
            "computernames.\n";
    @machines = grep(/\S/, map {s/\s//g; $_} <FILELIST>);
    close FILELIST;
  } else {
    die "Third command line option $ARGV[2] illegal.\n";
  }
} else {
  @machines = ($ENV{COMPUTERNAME});
}

foreach $machine (@machines) {
  unless (Win32::RegConnectRegistry($machine,
      &HKEY_LOCAL_MACHINE, $key_LM)) {
    print "$machine: ERROR, unable to connect to ".
        "remote registry.\n";
    next;
  }
  unless (Win32::RegOpenKeyEx($key_LM,
      "SYSTEM\\CurrentControlSet\\Services\\NetBT\\Adapters",
      &NULL, &KEY_ALL_ACCESS,  $key_Adapters)) {
    print "$machine: ERROR, unable to connect to open ".
        "NetBT\\Adapters.\n";
    Win32::RegCloseKey($key_LM);
    next;
  }
  $i = 0;
  while (Win32::RegEnumKey($key_Adapters, $i++,
      $adaptername)) {
    ($adaptername =~ /NdisWan/i) and next;
    unless (Win32::RegOpenKeyEx($key_Adapters, $adaptername,
        &NULL, &KEY_ALL_ACCESS,  $key_Adapter)) {
      print "$machine: ERROR, unable to connect to open ".
          "NetBT\\Adapters\\$adaptername.\n";
      next;
    }
    unless (Win32::RegSetValueEx($key_Adapter, "NameServer",
        &NULL, &REG_SZ, $primary)) {
      print "$machine: ERROR, unable to set primary WINS ".
          "address or $adaptername.\n";
      Win32::RegCloseKey($key_Adapter);
      next;
    }
    unless (Win32::RegSetValueEx($key_Adapter,
        "NameServerBackup", &NULL, &REG_SZ, $secondary)) {
      print "$machine: ERROR, unable to set secondary WINS ".
          "address for $adaptername.\n";
      Win32::RegCloseKey($key_Adapter);
      next;
    }
    print "$machine: Set primary and secondary WINS ".
        "addresses to $primary and $secondary for ".
        "adapter $adaptername.\n";
    Win32::RegCloseKey($key_Adapters);
  }
  Win32::RegCloseKey($key_LM);
}

sub PrintHelp {
  print <<END;
This program is designed to update the WINS entries on either the 
local host, a remote host, or a list of remote hosts. In all 
cases, the first two parameters are the desired primary and 
secondary WINS server IP addresses.  In the local host case, pass 
no more parameters.  In the remote host case, pass the string 
"remote" (no quotes) followed by a space and the hostname. In the 
list of remote hosts case, pass the string "file" (no quotes) 
followed by the name of a file containing one hostname per line. 
In all cases, the program will return information about whether 
it was successful.
END
  exit;
}