# getLogonserver.pl reports authenticating server for remote workstations # in an NT domain. # Written 21-dec-2001 by frank brown # # NB: # -- # 1. No report file option; redirect stdout to capture to a file. # 2. Retrieves LOGONSERVER value from "HKEY_USERS\'CUSID'\Volatile Environment" use Net::Ping; use Socket; use Win32::AdminMisc; use Win32::Registry; # evil globals: my $sAppName = "getLogonserver"; $sDate = localtime(); $sMachine = ""; ### all-important, oft-referenced global variable! $sMachineList = ""; $bSingleMachine = 0; my $sVersion = "1.0"; _main: &ParseCmdArgs(); if ($bSingleMachine) { if (&IsVisibleOnNet()) { &getInfo(); } goto _fin; } elsif ($sMachineList ne "") { open(FPCLIST,$sMachineList) || die "Can't open file $sMachineList: $^E\n"; while () { if (!/^[\!\#;]/) { # skip comments chop $_; s/\s(.*)//; # remove whitespace s/^\\\\//; # remove leading '\\' $sMachine = $_; if (&IsVisibleOnNet()) { &getInfo(); } } } close(FPCLIST); goto _fin; } # no args; check all workstations on domain: if (Win32::AdminMisc::GetMachines("", UF_WORKSTATION_TRUST_ACCOUNT, \@List, "")) { print "$sAppName $sVersion report $sDate:\n\n"; foreach $sMachine (@List) { $sMachine =~ s/\$$//; # strip trailing '$' if (&IsVisibleOnNet()) { &getInfo(); } } } _fin: print "Complete.\n"; ### end of execution ### subroutines: sub getInfo { my $hk; my $hkr; my $sKeyToFind = "\\Volatile Environment"; my $sKey = ""; my $sEntry = "LOGONSERVER"; my $sVal = ""; my $nRet = 0; if (!$HKEY_USERS->Connect($sServer,$hkr)) { print "can't connect to $sServer: $^E"; return $nRet; } local @subkeys = (); local $pSubkeys = \@subkeys; # reference (ptr) to subkeys list $hkr->GetKeys($pSubkeys); # get subkeys in USERS hive local $nCount = scalar @subkeys; if (0 == $nCount) { # no subkeys (?!) so no current user $hkr->Close(); return $nRet; } else { # iterate thru each subkey: foreach (@subkeys) { if (/\.DEFAULT/) { next; } $sKey = $_ . $sKeyToFind; if ($bVerbose) { print "checking $sKey\n"; } if ($hkr->Open($sKey,$hk)) { if (!$hk->QueryValueEx($sEntry,REG_SZ,$sVal)) { print "error getting value $sEntry\n"; } else { print "$sMachine: $sVal\n"; $nRet = 1; } $hk->Close(); last; } } } $hkr->Close(); return $nRet; } sub Help { printf("%s ver %s lists authenticating server for workstation(s)\n",$sAppName,$sVersion); print "\nusage: $sAppName [\\\\machine || /list=machines.lis]\n"; print "\nIf no arg supplied, all workstations in the default domain are checked\n"; } sub IsVisibleOnNet { $p = Net::Ping->new("icmp"); return ($p->ping($sMachine,1)); } sub ParseCmdArgs { while (@ARGV) { $_ = shift @ARGV; if (/^[\/\-]/) { # is arg a switch? $arg = lc(substr($_,1,3)); # parse 1st 3 chars: if ($arg eq "lis") { $i = index($_,"="); $i++; $sMachineList = sprintf("%s",substr($_,$i)); } if (($arg eq "hel") || ($arg eq "-he") || (substr($arg,0,1) eq "?")) { &Help(); exit; } } else { # not a switch if (/^[\\]/) { # single machine (UNC) s/\s(.*)//; # remove whitespace s/^\\\\//; # remove leading \\ $sMachine = $_; $bSingleMachine = 1; } else { $sMachineList = $_; } } } } __END__