#
#	Script to detail Services on al NT Services on all PCs.
#	CJL 17/06/02
#
#	use strict;
use Win32::TieRegistry( Delimiter=>"/");
use Win32::NetAdmin;
use Win32::Lanman;
use Win32API::Net;
use Net::Ping;$p = Net::Ping->new("icmp",1);
use MIME::QuotedPrint;
use MIME::Base64;
use Mail::Sendmail 0.75; # doesn't work with v. 0.74!

system("cls");

$domain = Win32::DomainName;
$frommail="scripts\@davy.ie";
$tomail="conor\@davy.ie";

#	Form and Print Log file name
print "Running $0\n\n";
$logdir="\\\\firbolg\\c\$\\admin\\csvfiles\\";
my ($log, $garbage)=split(/\./, $0);
$logfile="$logdir$log.csv";
unlink($logfile);
print "Log is $logfile\n\n";
logger("Operating System,Server,Type of Service,Service Display Name,Service System Name,Status,Startup,NT Security Context\n");

@standards=qw(Alerter Browser ClipSrv DHCP EventLog LanmanServer LanmanWorkstation LicenseService LmHosts Messenger NetDDE NetDDEdsdm Netlogon NtLmSsp PlugPlay ProtectedStorage Replicator RPCLOCATOR RpcSs Schedule Spooler TapiSrv UPS);


my @servers;
$domain = Win32::DomainName();
Win32::NetAdmin::GetDomainController("", $domain, $PDC) || logger("Unable to obtain the PDC name for $domain.");
$filter=FILTER_WORKSTATION_TRUST_ACCOUNT;
Win32API::Net::UserEnum($PDC, \@servers, $filter) || die "Error enumerating workstations on $pdc\n\n\n";
my(@state) = ("","Stopped","Start_Pending","Stop_Pending", "Running","Continue_Pending","Pause_Pending","Paused");
my(@startup) = ("","","Automatic","Manual","Disabled");

my $counter=0;
foreach $server(sort @servers)
{
	chop($server);
	$server=uc($server);
	if($p->ping($server))
	{
		\&Services($server);
	}
	else 
	{
#		print "\-$server\-";
		push (@cantping,$server);
	}
}

logger ("\n\nThese computers were NOT audited\nReason,PC Name\n");
foreach my $PC(sort @cantping){logger("Not pingable,$PC\n");}
print "\nOutput listed to $logfile\n";

#	THE END OF EXECUTION

sub Services 
{
my($server) = @_;
my($err,@services,$service,%info);
my $type=IsWinNT($server);
if (!Win32::Lanman::EnumServicesStatus("\\\\$server","",&SERVICE_WIN32,&SERVICE_STATE_ALL,\@services)) 
	{
	print '-';
	}
else
	{
	foreach $service (@services)
	{
		if (Win32::Lanman::QueryServiceConfig("\\\\$server","",${$service}{name},\%info)) 
			{
			if (grep /${$service}{name}/i, @standards)
			{
				next;
			}
			else 
			{
				logger ("$type,$server,Non standard Service,${$service}{display},${$service}{name},$state[${$service}{state}],$startup[$info{start}],$info{account}\n")
			}
		}
	}
}
}
$msg="The attachment details all NT workstations & servers, and their services, for any Windows based PCs connected to the domain at ".gmtime().", and distinguishes workstations from servers by the first column\n\nTo clarify, an NT Server in the spreadsheet refers to a server operating system, not specifically NT4 server.\n\n\nSelect Autoformat in excel for maximum readability\n\n";
mailer("$frommail","$tomail","NT Services","$msg","$logfile");

sub logger
{
open (LOGFILE, ">>$logfile") || die "Could not open log file : $!\n";	
$date=gmtime();
print LOGFILE "$_[0]" || die "Print failed : $!\n";
print ".";
close(LOGFILE);
}


sub IsWinNT
{
if (my $key = $Registry->Open("//$server/LMachine/SYSTEM/CurrentControlSet/Control/ProductOptions//"))
	{
		my $ostype=$key->GetValue("ProductType") || print "%server error ***** Could not enumerate type from Registry\n";
		if($ostype eq "WinNT"){return ("NT Workstation");}
		if($ostype eq "ServerNT"){return ("NT Server")}
	}
	else {$ostype="Unavailable";}
return($ostype);
}

sub mailer
{
	%mail = 
	(
		SMTP => "exchange.davy.ie",
		from => "$_[0]",
		to => "$_[1]",
		bcc => "conor\@davy.ie",
		subject => "$_[2]"
	);

$boundary = "====" . time() . "====";
$mail{'content-type'} = "multipart/mixed; boundary=\"$boundary\"";
$message = encode_qp( "$_[3]" );
open (F, $_[4]) or die "Cannot read $_[4]: $!";
binmode F; undef $/;
$mail{body} = encode_base64(<F>);
close F;

$boundary = '--'.$boundary;
$mail{body} = <<END_OF_BODY;
$boundary
Content-Type: text/plain; charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

$message
$boundary
Content-Type: application/octet-stream; name="$_[4]"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="$_[4]"

$mail{body}
$boundary--
END_OF_BODY

sendmail(%mail) || print "Error: $Mail::Sendmail::error\n";
}

