# Program name - WSCLEAN.PL written by Paul Popour 02/2000
# Perl Win32 Script tested with AS Perl version 5.005_02
# Purpose - Reports and optionally purges dead workstations accounts
#
# This script was written by Paul Popour (ppopour@infoave.net) in 2000.
# It is released into the public domain. You may use it freely, however,
# if you make any modifications and redistribute, please list your name
# and describe the changes. This script is distributed without any warranty,
# express or implied.
#
# SYNTAX - perl wsclean.pl {numberofdays}
#
# Workstations in an NT domain are basically a hidden user account. These
# accounts negotiate a new passord with the domain every 7 days. If an
# account never changes its password it has probably been removed from
# use in the domain.
#
# perl wsclean.pl Produces a report of workstation accounts and the
# number of days since they authenticated in the domain.
#
# perl wsclean.pl 45 Removes all workstations that have not authenticated
# in the over 45 days.
#
# Note: Always run a report before attempting to clean workstations. In
# this way you will avoid unexpected results due to incorrect time
# settings or other factors.
#
use Win32::AdminMisc;
use Win32::NetAdmin;
use Win32::Lanman;
$output = "C:\\temp\\wsclean.txt";
if ($ARGV[0] eq "")
{
print "Proceeding in lookup mode, output will be placed in $output\n";
&report;
exit 1;
}
if (($ARGV[0]/1) ne $ARGV[0])
{
&syntax;
exit 1;
}
if ($ARGV[0] < 30)
{
print "\n\n\tMinimum number of days is 30 (you entered $ARGV[0])";
&syntax;
exit 1;
}
&wsnames;
open(OUTPUT, ">$output") || die "Can't open $output";
foreach $ws (@wslist)
{
unless (Win32::Lanman::NetUserGetInfo("$PDC", "$ws", \%H1))
{
print "Unable to obtain information on $user from $PDC\n";
next;
}
$days = int ($H1{'password_age'}/86400);
if ($days > $ARGV[0])
{
unless(Win32::NetAdmin::UserDelete("$PDC", "$ws"))
{
print OUTPUT "Failed to remove $ws.\n";
next;
}
chop $ws;
print OUTPUT "$ws\t$days - removed\n";
print "$ws\t$days - removed\n";
}
else
{
chop $ws;
print OUTPUT "$ws\t$days\n";
print "$ws\t$days\n";
}
}
close OUTPUT;
sub report
{
&wsnames;
open(OUTPUT, ">$output") || die "Can't open $output";
foreach $ws (@wslist)
{
unless (Win32::Lanman::NetUserGetInfo("$PDC", "$ws", \%H1))
{
print "Unable to obtain information on $user from $PDC\n";
next;
}
$days = int ($H1{'password_age'}/86400);
chop $ws;
$wsnames{$ws} = $days;
}
@keys = sort {$wsnames{$b} <=> $wsnames{$a} || length($b) <=> length($a) || $a
cmp $b} keys %wsnames;
foreach $key (@keys)
{
print OUTPUT "$key\t$wsnames{$key}\n";
}
close OUTPUT;
}
sub wsnames
{
unless ($domain = Win32::DomainName)
{
die "Unable to obtain the domain name";
}
unless (Win32::NetAdmin::GetDomainController("", $domain, $PDC))
{
die "Unable to obtain the PDC name for $domain.";
}
unless (Win32::NetAdmin::GetServers($PDC, $domain, 0x00000010, \@BDC))
{
die "Unable to obtain the BDC names for $domain.";
}
print "Obtaining workstation names from $PDC.....please wait.\n";
unless (Win32::AdminMisc::GetMachines($PDC, UF_WORKSTATION_TRUST_ACCOUNT,
\@wslist, ""))
{
die "Unable to obtain users from $PDC";
}
print "\tWorkstation names obtained\n\t\tProcessing workstations\n";
}
sub syntax
{
print "\n\n\n
WSCLEAN.PL - Used to either report and/or purge dead workstation
domain accounts. NT requires workstations to accept a new
password every seven(7) days. The number of days since the last
password change plus up to six additional days is the length
of time since the workstation has authenticated to the domain.\n\n
SYNTAX - perl wsclean.pl [number of days]\n\n
Minimum number of days is 30\n\n
If no number of days is passed to the program
it creates a report of accounts and the number
of days since there last authentication in
$output\n\n";
}
.