use Win32::NetAdmin;
use Win32::AdminMisc;
use Win32::TieRegistry(Delimiter=>"/");
use POSIX;
use Win32::Lanman;
use Net::Ping;
use Win32::Service;
use Data::Dumper;
use Win32API::Net;
use Getopt::Std;
use Net::LDAP;
use Win32::EventLog;
use Win32::ODBC;

sub usage{
  print <<EOF;
  
  "$0" will search across servers and check pertinent information
  about those servers to ensure they are being included in the 
  SOP driven standards for a windows server.
  
  ex: $0 -a  -b ldapbase -r filter -d domain -c dc -m singlemachine -f file -h -g -l -o sort -s searchfilter

  Where:
    *domain:            Netbios name of domain to run against (as apposed to
    			all known to WINS).
    *a:			Process all servers in a given domain (-a will take
    			precendence over a -d or -m).  Requires domain listed
    *ldapbase:		Search base to gather list of machines from.
    			(ex. "ou=servers,ou=ah,dc=ad,dc=mathworks,dc=com")
    *searchfilter:	Optional ldap search filter
    *dc			Name of nearest Domain controller (FQDN is preferred)
    			(ex. "dc-00.ad.mathworks.com")
    *singlemachine:	Name of machine to dump configuration for.
    *file:		Name of file with machines to process.
    *sort:		Parameter to determine the sort order of the list of
    			machines (2 values "f" "r" for forward and reverse)
    *l:			Create a logfile
    *g:			Print debug info
    *s:			use MathWorks default of finding all servers.  This
    			is done by taking all server machines known to WINS
    			and AD and creating a combined list.
    *h:			Display this helpfile   
    			
    All *'s are optional but if all are left out your are not asking the'
    script to find anything on any of the machines so you will get no results
EOF
    exit( 1 );

}

getopts( 'ahlgtd:m:b:c:f:s:o:' );

my $all    		= $Getopt::Std::opt_a;
my $domain      	= $Getopt::Std::opt_d;
my $dc		      	= (length($Getopt::Std::opt_c)) ? $Getopt::Std::opt_c : "dc-00.ad.mathworks.com";
my $search	      	= $Getopt::Std::opt_s;
my $base		= $Getopt::Std::opt_b;
my $singlemachine 	= $Getopt::Std::opt_m;
my $help		= $Getopt::Std::opt_h;
my $file 		= $Getopt::Std::opt_f;
my $logfile		= $Getopt::Std::opt_l;
my $debug		= $Getopt::Std::opt_g;
my $sort		= $Getopt::Std::opt_o;
my $tmwsearch		= $Getopt::Std::opt_t;

chomp $domain;
chomp $file;
chomp $singlemachine;
chomp $base;
chomp $sort;

$sort = lc($sort);
$domain = lc($domain);
$singlemachine = lc($singlemachine);

if ($help){usage();exit( 1 );};
if ($tmwsearch) { 
	$search = "(&(objectCategory=computer)(operatingSystem=\*Server\*))";
#	$search = "(&(objectCategory=computer))";
	$base = "dc=ad,dc=mathworks,dc=com";
	};

$time = strftime "%a.%b.%Y_%H.%M.%S", localtime;
$filename = "$0.$time.txt";
if ($logfile) {open (FILE, "> $filename") || die("Can't open file $!")};


&setPing;      		#Sets the protocol and timeout for Net::Ping
&getClients;   		#Gets the list of clients
&loadExceptions; 	#Loads all exception files
&openDBs; 		#connects to all data sources
#&getBackupClients;
&getDCs;
#&getVMs;


print "Retrieving Configuration Info for\:\n";
if ($logfile) {print FILE "Retrieving Configuration Info for\:\n"};

foreach $client(@clients)
	{
	unless (grep(/$client/,@globalexceptions)) 	
		{
		if($p->ping($client) == 1)				#Client is on the network
			{                                    
			if($reg = $Registry->{"//$client/HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows NT/CurrentVersion/Network"}) #Read access to Registry HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Network
				{   
				my %Groups;
				print "\t$client\n"; 
				if ($logfile) {print FILE "\t$client\n"};
				&checkbackupclient;
	#			&checkbackuplogs;
				&checkdcapp;
				&checkwhatsup;
				&checkmom;
				&checksmsaccount;
				&checkRDP;
				&checkRILO;
				&checkdns;   
				&checkdrivespace;
				&checknamingstandard;

#				Nice to do's
	#			&checkHPSIMserver;
	#			&checkHPSIMAgent;
	#			&checksmsclient;			# May not be necessary
	#			&checklastseen;
	#			&checkdcdiag;  				#if client is a dc
	#			&checkassetmanagment	
	# on first time seen, do we notify DCO mgmt, Rack owner of change?				
	 			&cleanup;              			# undef hashes so they can be reused
				}
			}
		else
			{
			if ($debug) {print "\tCannot Ping -> $client!\n"};
			if ($logfile) {print FILE "\tCannot Ping -> $client!\n"};
			}
		}
	}
if ($logfile) { close (FILE) };
&closeDBs;

###  SUBROUTINES  ##########################################################
############################################################################

sub checkbackupclientnew
	{
		
	use Win32::OLE qw(in);
	
	$strComputer = '$client';
	
	$objWMI = Win32::OLE->GetObject('winmgmts:\\\\' . $strComputer . '\\root\\cimv2');
#	$objEvents = $objWMI->ExecQuery('Select * from Win32_NTLogEvent Where FILE = \'Application\' ' . 'and EventCode = 5778 and Type = \'Information\' ' . 'and TimeGenerated > \'2005/11/01\' ');
	$objEvents = $objWMI->ExecQuery('Select * from Win32_NTLogEvent Where FILE = \'Application\' ' . 'and EventCode = 5778 and Type = \'Information\' ' . 'and TimeGenerated > \'2005/11/01\' ');
	
	print 'Total events that match criteria: ' . $objEvents->Count, "\n";
	foreach my $objEvent (in $objEvents) {
	    print ' CategoryString: ' . $objEvent->CategoryString, "\n";
	    print ' EventType: ' . $objEvent->EventType, "\n";
	    print ' FILE: ' . $objEvent->FILE, "\n";
	    print ' Message: ' . $objEvent->Message, "\n";
	    print ' RecordNumber: ' . $objEvent->RecordNumber, "\n";
	    print ' SourceName: ' . $objEvent->SourceName, "\n";
	    print ' TimeGenerated: ' . $objEvent->TimeGenerated, "\n";
	    print ' Type: ' . $objEvent->Type, "\n";
	    print ' User: ' . $objEvent->User, "\n";
	    print "\n";
	}
	print "The script has completed successfully.\n";
	}

############################################################################

sub checkbackupclient
	{
	unless ((grep(/$client/,@backupexceptions)) || (grep(/$client/,@globalexceptions)))
		{
		if ((-e "\\\\$client\\c\$\\Program Files\\VERITAS\\NetBackup\\bin\\NbWin.exe")||(-e "\\\\$client\\d\$\\Applications\\VERITAS\\NetBackup\\bin\\NbWin.exe")) 
			{
			$backupclient = "NetBackup";
			}
		else	{
			if ($debug) { 
				print "\t\t*** Error - Netbackup agent missing on client : $client\n"; 
				if ($logfile) {print FILE "\t\t*** Error - Netbackup agent missing on client : $client\n";}
				};
			};
		if ((-e "\\\\$client\\c\$\\Program Files\\CA\\BrightStor ARCserve Backup Client Agent for Windows\\ntagent.log")||(-e "\\\\$client\\d\$\\Applications\\CA\\BrightStor ARCserve Backup Client Agent for Windows\\ntagent.log")||(-e "\\\\$client\\c\$\\Program Files\\CA\\BrightStor ARCserve Backup\\ca_backup.exe")||(-e "\\\\$client\\d\$\\applications\\CA\\BrightStor ARCserve Backup\\ca_backup.exe")||(-e "\\\\$client\\d\$\\applications\\CA\\ARCserve\\ca_backup.exe")) 
			{
			$backupclient = "Arcserve";
			}
		else	{
			if ($debug) { 
				print "\t\t*** Error - Arcserve agent missing on client : $client\n";
				if ($logfile) {print FILE "\t\t*** Error - Arcserve agent missing on client : $client\n";}
				};
			};
		if ($backupclient) { 
			if ($debug) 
				{
				print "\t\tFound $backupclient on $client\n";
				if ($logfile) {print FILE "\t\tFound $backupclient on $client\n"};
				} 
			}
		else {
			print "\t\t*** Error - No backup client found on $client\n";
			if ($logfile) {print FILE "\t\t*** Error - No backup client found on $client\n"}
			};
		}
	}


############################################################################

sub loadExceptions
	{
	open (GLOBAL, "< ServerGlobalExceptions.txt") || open (GLOBAL, "+>> ServerGlobalExceptions.txt") || die("Can't open file $!");
	@globalexceptions = <GLOBAL>;
	if ($debug) {
		print "Global Exceptions: @globalexceptions\n";
		if ($logfile) {	print FILE "Global Exceptions: @globalexceptions\n" };
		}
	close (GLOBAL);

	open (BUFILE, "< ServerBackupExceptions.txt") || open (BUFILE, "+>> ServerBackupExceptions.txt") || die("Can't open file $!");
	@backupexceptions = <BUFILE>;
	if ($debug) {
		print "Backup Exceptions: @backupexceptions\n";
		if ($logfile) {	print FILE "Backup Exceptions: @backupexceptions\n" };
		}
	close (BUFILE);

	open (DCOFILE, "< ServerDCOAppExceptions.txt") || open (DCOFILE, "+>> ServerDCOAppExceptions.txt") || die("Can't open file $!");
	@dcoexceptions = <DCOFILE>;
	if ($debug) {
		print "DCO Exceptions: @dcoexceptions\n";
		if ($logfile) {	print FILE "DCO Exceptions: @dcoexceptions\n" };
		}
	close (DCOFILE);

	open (WHATSUPFILE, "< ServerWhatsUpExceptions.txt") || open (WHATSUPFILE, "+>> ServerWhatsUpExceptions.txt") || die("Can't open file $!");
	@whatsupexceptions = <WHATSUPFILE>;
	if ($debug) {
		print "Whatsup Exceptions: @whatsupexceptions\n";
		if ($logfile) {	print FILE "Whatsup Exceptions: @whatsupexceptions\n" };
		}
	close (WHATSUPFILE);

	open (MOMFILE, "< ServerMOMExceptions.txt") || open (MOMFILE, "+>> ServerMOMExceptions.txt") || die("Can't open file $!");
	@momexceptions = <MOMFILE>;
	if ($debug) {
		print "MOM Exceptions: @momexceptions\n";
		if ($logfile) {	print FILE "MOM Exceptions: @momexceptions\n" };
		}
	close (MOMFILE);

	open (SMSFILE, "< ServerSMSExceptions.txt") || open (SMSFILE, "+>> ServerSMSExceptions.txt") || die("Can't open file $!");
	@smsexceptions = <SMSFILE>;
	if ($debug) {
		print "SMS Exceptions: @smsexceptions\n";
		if ($logfile) {	print FILE "SMS Exceptions: @smsexceptions\n" };
		}
	close (SMSFILE);

	open (RILOFILE, "< ServerRILOExceptions.txt") || open (RILOFILE, "+>> ServerRILOExceptions.txt") || die("Can't open file $!");
	@riloexceptions = <RILOFILE>;
	if ($debug) {
		print "RILO Exceptions: @riloexceptions\n";
		if ($logfile) {	print FILE "RILO Exceptions: @riloexceptions\n" };
		}
	close (RILOFILE);

	open (RDPFILE, "< ServerRDPExceptions.txt") || open (RDPFILE, "+>> ServerRDPExceptions.txt") || die("Can't open file $!");
	@rdpexceptions = <RDPFILE>;
	if ($debug) {
		print "RDP Exceptions: @rdpexceptions\n";
		if ($logfile) {	print FILE "RDP Exceptions: @rdpexceptions\n" };
		}
	close (RDPFILE);

	open (NAMINGSTANDARDFILE, "< ServerNamingStandardExceptions.txt") || open (NAMINGSTANDARDFILE, "+>> ServerNamingStandardExceptions.txt") || die("Can't open file $!");
	@namingexceptions = <NAMINGSTANDARDFILE>;
	if ($debug) {
		print "Naming Standard Exceptions: @namingexceptions\n";
		if ($logfile) {	print FILE "Naming Standard Exceptions: @namingexceptions\n" };
		}
	close (NAMINGSTANDARDFILE);

	open (DRIVESPACEFILE, "< ServerDriveSpaceExceptions.txt") || open (DRIVESPACEFILE, "+>> ServerDriveSpaceExceptions.txt") || die("Can't open file $!");
	@drivespaceexceptions = <DRIVESPACEFILE>;
	if ($debug) {
		print "Drive Space Exceptions: @drivespaceexceptions\n";
		if ($logfile) {	print FILE "Drive Space Exceptions: @drivespaceexceptions\n" };
		}
	close (DRIVESPACEFILE);
	}

############################################################################ 

sub openDBs
	{
	# Connecting to Databases via ODBC. 
	# It attempts to add the ODBC Datasource if it was not created (correct version drivers must already be installed). 
	# Most likely problem is not having MySQL ODBC driver 

	# ODBC variables
	my $DCdsn = "DCinventory";
	my $DCuid = "dcreader";
	my $DCpwd = "readonly";
	my $wudsn = "WhatsUp";
	my $wuuid = "sa";
	my $wupwd = "wug_sa";
	my $smsdsn = "SCCM";
	my $smsuid = "rosccm";
	my $smspwd = "Msh1cosmE";
	my $momdsn = "SCOM";
	my $momuid = "roscom";
	my $mompwd = "Msh1cosmE";
	my $magicdsn = "Magic";
	my $magicuid = "magic";
	my $magicpwd = "magic";

	my $cont =0; 
	my $ODBC =0;   
	my @dsns = undef;
	
	# Checking ODBC DataSources
	 
	my (%dsn,$key) = Win32::ODBC::DataSources();  	
	if ($debug) {print "\nChecking DSN's to see if this connection already exists:\n"};
	foreach $key (sort keys %dsn) 
		{
		if ($debug) {print "\tODBC:$key\n"};
		push (@dsns,$key);
		} 

	if ($debug) {print "\tDSN array:@dsns\n"};
	
	# Creating ODBC DataSource for DCInventory if it doesn't exist
	unless (grep(/$DCdsn/,@dsns))
		{
		print "The ODBC Connection to $DCdsn was not established. Creating new ODBC Connection.....\n\n";
		$DSN      = "$DCdsn";
		$Driver   = 'MySQL ODBC 5.1 Driver';
		$Desc     = 'Connection to Datacenter inventory database';
		$Server   = 'mysql5-VIF.mathworks.com'; 
		$Database = 'dcinventory';
		if (Win32::ODBC::ConfigDSN(
	        	ODBC_ADD_DSN, 
			"$Driver", 
			("DSN=$DSN", 
			"DESCRIPTION=$Desc", 
			"SERVER=$Server", 	       # server name
			"DATABASE=$Database",         # our database
			#                    "NETWORK=DBMSSOCN",        # TCP/IP Socket Lib
			))){print "DSN $dsnname created\n";}
		}
	$DCdb = new Win32::ODBC("DSN=$DCdsn;UID=$DCuid;PWD=$DCpwd");

	# Creating ODBC DataSource for Whatsup if it doesn't exist
	unless (grep(/$wudsn/,@dsns))
		{
		print "The ODBC Connection to $wudsn was not established. Creating new ODBC Connection.....\n\n";
		$DSN      = "$wudsn";
		$Driver   = 'SQL Server';
		$Desc     = 'Connection to Whatsup database';
		$Server   = 'wu-00-ah\whatsup'; 
		$Database = 'whatsup';
		if (Win32::ODBC::ConfigDSN(
	        	ODBC_ADD_DSN, 
			"$Driver", 
			("DSN=$DSN", 
			"DESCRIPTION=$Desc", 
			"SERVER=$Server", 	       # server name
			"DATABASE=$Database",         # our database
			#                    "NETWORK=DBMSSOCN",        # TCP/IP Socket Lib
			))){print "DSN $dsnname created\n";}
		}
	$wudb = new Win32::ODBC("DSN=$wudsn;UID=$wuuid;PWD=$wupwd");

	# Creating ODBC DataSource for SCCM if it doesn't exist
	unless (grep(/$smsdsn/,@dsns))
		{
		print "The ODBC Connection to $smsdsn was not established. Creating new ODBC Connection.....\n\n";
		$DSN      = "$smsdsn";
		$Driver   = 'SQL Server';
		$Desc     = 'Connection to SCCM database';
		$Server   = 'sccm-00-ah.mathworks.com'; 
		$Database = 'SMS_AH2';
		if (Win32::ODBC::ConfigDSN(
	        	ODBC_ADD_DSN, 
			"$Driver", 
			("DSN=$DSN", 
			"DESCRIPTION=$Desc", 
			"SERVER=$Server", 	       # server name
			"DATABASE=$Database",         # our database
			#                    "NETWORK=DBMSSOCN",        # TCP/IP Socket Lib
			))){print "DSN $dsnname created\n";}
		}
	$smsdb = new Win32::ODBC("DSN=$smsdsn;UID=$smsuid;PWD=$smspwd");

	# Creating ODBC DataSource for SCOM if it doesn't exist
	unless (grep(/$momdsn/,@dsns))
		{
		print "The ODBC Connection to $momdsn was not established. Creating new ODBC Connection.....\n\n";
		$DSN      = "$momdsn";
		$Driver   = 'SQL Server';
		$Desc     = 'Connection to SCOM database';
		$Server   = 'scom-00-ah.mathworks.com'; 
		$Database = 'OperationsManager';
		if (Win32::ODBC::ConfigDSN(
	        	ODBC_ADD_DSN, 
			"$Driver", 
			("DSN=$DSN", 
			"DESCRIPTION=$Desc", 
			"SERVER=$Server", 	       # server name
			"DATABASE=$Database",         # our database
			#                    "NETWORK=DBMSSOCN",        # TCP/IP Socket Lib
			))){print "DSN $dsnname created\n";}
		}
	$momdb = new Win32::ODBC("DSN=$momdsn;UID=$momuid;PWD=$mompwd");

	# Creating ODBC DataSource for MAGIC if it doesn't exist
	unless (grep(/$magicdsn/,@dsns))
		{
		print "The ODBC Connection to $momdsn was not established. Creating new ODBC Connection.....\n\n";
		$DSN      = "$magicdsn";
		$Driver   = 'SQL Server';
		$Desc     = 'Connection to Magic database';
		$Server   = 'ssgmgmt-00-ah.mathworks.com'; 
		$Database = 'Magic';
		if (Win32::ODBC::ConfigDSN(
	        	ODBC_ADD_DSN, 
			"$Driver", 
			("DSN=$DSN", 
			"DESCRIPTION=$Desc", 
			"SERVER=$Server", 	       # server name
			"DATABASE=$Database",         # our database
			#                    "NETWORK=DBMSSOCN",        # TCP/IP Socket Lib
			))){print "DSN $dsnname created\n";}
		}
	$momdb = new Win32::ODBC("DSN=$magicdsn;UID=$magicuid;PWD=$magicpwd");

	}

############################################################################

sub closeDBs
	{
	$DCdb->Close();
	$wudb->Close();
	$smsdb->Close();
	$momdb->Close();
	$magicdb->Close();
	}

############################################################################

sub setPing
	{
	$p = Net::Ping->new('icmp',2);
	}

############################################################################

sub checkdcapp {
	unless ((grep(/$client/,@dcoexceptions)) || (grep(/$client/,@globalexceptions)))
		{
		$DCdb->Sql("SELECT system_owner FROM dcinventory.host where hostname = \"$client\"");	
		while ($DCdb->FetchRow()) {
			@Data = $DCdb->Data ("system_owner");
			$owner = $Data[0];
			if ($debug) {print "\n\nowner from DC database is = $owner\n";}
			if ($owner)
				{
				if ($debug) {print "\t\t$client is in DC application database - Owner:$owner\n"};				
				if ($logfile) {print FILE "\t\t$client is in DC application database - Owner:$owner\n"};
				}
			else
				{
				print "\t\t*** Error - $client not in DC application database\n";
				if ($logfile) {print FILE "\t\t*** Error - $client not in DC application database\n"};
				}
			}
		unless ($DCdb->RowCount( ) >0) 
			{ 
			print "\t\t*** Error - $client not in DC application database\n";
			if ($logfile) {print FILE "\t\t*** Error - $client not in DC application database\n"};
			}	
		}
	}

############################################################################

sub checkwhatsup {
	unless ((grep(/$client/,@whatsupexceptions)) || (grep(/$client/,@globalexceptions)))
		{
		$wudb->Sql("SELECT * FROM dbo.NetworkInterface where sNetworkName like \'\%$client\%\'");
		$wudb->FetchRow();
		unless ($wudb->RowCount( ) >0) 
			{ 
			print "\t\t*** Error - $client not configured in whatsup\n";
			if ($logfile) {print FILE "\t\t*** Error - $client not configured in whatsup\n"};
			}	
		}
	}

############################################################################

sub checkmom {
	unless ((grep(/$client/,@momexceptions)) || (grep(/$client/,@globalexceptions)))
		{
		$momdb->Sql("SELECT * FROM dbo.MT_Computer where NetbiosComputerName = \'$client\'");
		$momdb->FetchRow();
		unless ($momdb->RowCount( ) >0) 
			{ 
			print "\t\t*** Error - $client not found in MOM\n";
			if ($logfile) {print FILE "\t\t*** Error - $client not found in MOM\n"};
			}	
		}
	}

############################################################################

sub checksmsaccount { 			# Brian's Query : select Name, SMSAssignedSites, SMSUniqueIdentifier, ResourceId, ResourceType from  SMS_R_System where Client = 0 or Client is NULL
	unless ((grep(/$client/,@smsexceptions)) || (grep(/$client/,@globalexceptions)))
		{
		$smsdb->Sql("SELECT * FROM dbo.Computer_System_DATA where Name0 = \'$client\'");
		$smsdb->FetchRow();
		unless ($smsdb->RowCount( ) >0) 
			{ 
			print "\t\t*** Error - $client not found in SMS\n";
			if ($logfile) {print FILE "\t\t*** Error - $client not found in SMS\n"};
			}	
		}
	}

############################################################################

sub checkRILO {
	unless ((grep(/$client/,@riloexceptions)) || (grep(/$client/,@globalexceptions)))
		{
		if($p->ping($client."-cs") == 1)				#Client is on the network
			{
			if ($debug)
				{
				print "\t\tRILO board is responding to a ping at the standard naming of $client"."-cs\n";	
				if ($logfile) {print FILE "\t\tRILO board is responding to a ping at the standard naming of $client"."-cs\n"};	
				}
			}
		else
			{
			print "\t\t*** Error - RILO board is not responding to a ping at the standard naming of $client"."-cs\n";	
			if ($logfile) {print FILE "\t\t*** Error - RILO board is not responding to a ping at the standard naming of $client"."-cs\n"};	
			}
		}
	}

############################################################################

sub checkdns
	{
	unless ((grep(/$client/,@dnsexceptions)) || (grep(/$client/,@globalexceptions)))
		{
		my $IP = Win32::AdminMisc::GetHostName("$client");	
		my $FQDN = Win32::AdminMisc::GetHostName("$IP");	
		if (grep(/\.ad\.mathworks\.com/i,$FQDN))
			{
			print "\t\t*** Error- AD.MATHWORKS.COM DNS registration : $FQDN\n";
			if ($logfile) {print FILE "\t\t*** Error- AD.MATHWORKS.COM DNS registration : $FQDN\n"};
			}
		elsif (grep(/\.dhcp\.mathworks\./i,$FQDN))
			{
			print "\t\t*** Error - Server with DCHP DNS registration : $FQDN\n";	
			if ($logfile) {print FILE "\t\t*** Error - Server with DCHP DNS registration : $FQDN\n"};	
			}
		elsif (grep(/\.mathworks\./i,$FQDN))
			{
			if ($debug) 
				{
				print "\t\tMATHWORKS.COM DNS registration : $FQDN\n";
				if ($logfile) {print FILE "\t\tMATHWORKS.COM DNS registration : $FQDN\n"};
				}	
			}
		else
			{
			print "\t\t*** Error - No DNS registration : $FQDN\n";	
			if ($logfile) {print FILE "\t\t*** Error - No DNS registration : $FQDN\n"};	
			}
		}
	}
	
############################################################################

sub checkRDP
	{
	unless ((grep(/$client/,@rdpexceptions)) || (grep(/$client/,@globalexceptions)))
		{
		use Win32::OLE qw(in);
		$strComputer = "$client";
		if ($objWMI = Win32::OLE->GetObject('winmgmts:\\\\' . $strComputer . '\\root\\cimv2'))
			{
			$objTSSquery = $objWMI->ExecQuery('Select * from Win32_TerminalServiceSetting');
			foreach my $objTSS (in $objTSSquery) 
				{
				if ($objTSS->AllowTSConnections eq 1)
					{
					if ($objTSS->LicensingType eq 1)
						{
						if ($debug) 
							{
							print "\t\tRemote Desktop is set for allowing connections and is in Administration mode\n";
							if ($logfile) {print FILE "\t\tRemote Desktop is set for allowing connections and is in Administration mode\n";}
							}
						}
					elsif ($objTSS->LicensingType eq 4)	
						{
						if ($debug) 
							{
							print "\t\tRemote Desktop is set for allowing connections and is in Per User Terminal Server Licensing mode\n";
							if ($logfile) {print FILE "\t\tRemote Desktop is set for allowing connections and is in Per User Terminal Server Licensing mode\n"};
							};
						}
					else 	{
						print "\t\t*** Error - Remote Desktop is set for allowing connections and is not in Administration or Per User Terminal Server Licensing mode\n";		
						if ($logfile) {print FILE "\t\t*** Error - Remote Desktop is set for allowing connections and is not in Administration or Per User Terminal Server Licensing mode\n"};		
						}
					}
				else 	{
					print "\t\t*** Error - Remote Desktop is not configured to allow connections\n";				
					if ($logfile) {print FILE "\t\t*** Error - Remote Desktop is not configured to allow connections\n"};
					}
				if ($debug) 
					{
					print "\t\t\tAllowTSConnections: " . $objTSS->AllowTSConnections, "\n";
					print "\t\t\tLogons: " . $objTSS->Logons, "\n";
					print "\t\t\tServerName: " . $objTSS->ServerName, "\n";
					print "\t\t\tLicensingType: " . $objTSS->LicensingType, "\n";
					print "\t\t\tUserPermission: " . $objTSS->UserPermission, "\n";
					print "\t\t\tUseTempFolders: " . $objTSS->UseTempFolders, "\n";
					if ($logfile) 
						{
						print FILE "\t\t\tAllowTSConnections: " . $objTSS->AllowTSConnections, "\n";
						print FILE "\t\t\tLogons: " . $objTSS->Logons, "\n";
						print FILE "\t\t\tServerName: " . $objTSS->ServerName, "\n";
						print FILE "\t\t\tLicensingType: " . $objTSS->LicensingType, "\n";
						print FILE "\t\t\tUserPermission: " . $objTSS->UserPermission, "\n";
						print FILE "\t\t\tUseTempFolders: " . $objTSS->UseTempFolders, "\n";						
						}
					}
				}
			}
		else	{
			print "\t\t*** Error - Unable to get WMI connection to verify Remote Desktop on $client\n";				
			if ($logfile) {print FILE "\t\t*** Error - Unable to get WMI connection to verify Remote Desktop on $client\n"};
			}		
		}
	}
	
############################################################################

sub checknamingstandard
	{
	unless ((grep(/$client/,@namingexceptions)) || (grep(/$client/,@globalexceptions)))
		{
		@hostname = split(/-/, $client);
		$numelements = @hostname;
		if ($debug) {print "\t\tNumber of name elements: $numelements\n"};
		if ( ($numelements eq 3 ) && (grep(/\b\d+\b/,@hostname[1])) )   # Check if 3 distinct elements to the name seperated by dashes and middle element is composed of numbers
			{
			if ($debug) 
				{
				print "\t\t$client appears to conform to standard naming convention\n";
				if ($logfile) {print FILE "\t\t$client appears to conform to standard naming convention\n"};
				}
			}
		else 	{
			print "\t\t*** Error - $client does not appear to adhere to the standard naming convention: have 3 elements seperated by a '-' with the middle element being a number\n";
			if ($logfile) {print FILE "\t\t*** Error - $client does not appear to adhere to the standard naming convention: have 3 elements seperated by a '-' with the middle element being a number\n"};
			}
		}
	}

############################################################################

sub checkdrivespace
	{
	unless ((grep(/$client/,@drivespaceexceptions)) || (grep(/$client/,@globalexceptions)))
		{
		Win32::Lanman::NetServerDiskEnum("\\\\$client",\@drives);
		foreach $drive(@drives)
			{
			$drive =~ s/://g;
			@drvinfo = Win32::AdminMisc::GetDriveSpace("\\\\$client\\$drive\$");
			$drive = $drive."\:";
			${$drive}{'CAPACITY'} = sprintf("%3.2f",($drvinfo[0]/1073741824))." GB"; #Convert to GigaBytes
			${$drive}{'SPACE'} = sprintf("%3.2f",($drvinfo[1]/1073741824))." GB";
			${$drive}{'size'} = ($drvinfo[0]/1073741824); #Convert to GigaBytes
			${$drive}{'free'} = ($drvinfo[1]/1073741824);
			}
		foreach $drive(@drives)
			{
			unless (${$drive}{'size'} < 6)	# My attempt to keep removable media from showing up (anything less than 6 gig in size - to skip DVD's in DVDrom drives)
				{ 
				if (((${$drive}{'free'}) / (${$drive}{'size'})) < 0.1)
					{
					print "\t\t*** Error - Drive $drive on $client is at : ".sprintf("%3.2f",((1-((${$drive}{'free'}) / (${$drive}{'size'})))*100))." percent full\n";
					if ($logfile) {print FILE "\t\t*** Error - Drive $drive on $client is at : ".sprintf("%3.2f",((1-((${$drive}{'free'}) / (${$drive}{'size'})))*100))." percent full\n"};
					}
				}
			}
		}
	}

############################################################################

sub getClients
	{
	if ($file)					#Get input from file if exists
		{   
		(open(INFILE,"<$file"));
		@clients = <INFILE>;
		chomp @clients;
		close INFILE;
		foreach $client(@clients)
			{
			$client =~ tr/a-z/A-Z/;
			}
		}
	elsif ($domain)					#Get all servers
		{                                    		
		Win32::NetAdmin::GetServers('',$domain,SV_TYPE_SERVER_NT|SV_TYPE_DOMAIN_CTRL|SV_TYPE_DOMAIN_BAKCTRL,\@clients);
		foreach $client(@clients)
			{
			$client =~ s/\\//g;
			}
		}
	elsif ($singlemachine)				#Get single Machine
		{                                    		
		@clients = "$singlemachine";
		foreach $client(@clients)
			{
			$client =~ s/\\//g;
			}
		}
	elsif ($base)					#Get an ldap search of machines
		{
		if ($p->ping($dc) == 1) 
			{
			unless ($search)  { my $search = "(&(objectCategory=computer))"};	
			if ($debug) {print "\nBase:$base\t\t$search\n\n"};			
			my $ldap = new Net::LDAP("$dc", port=>389) or die "$@";
			$ldap->bind(version=>3);
			my $msg = $ldap->search(
					base => "$base",
					filter=>"$search",
					callback => \&callback);
			die $msg->error if $msg->code;
			sub callback 
				{
				my ($search, $entry) = @_;
				$entry = $search->shift_entry;
				my @results=();
				if (defined $entry and $entry->get_value("cn")) 
					{
					$cn = $entry->get_value("cn");
					push @clients, "$cn";
					}
				}
			$ldap->unbind;
			}
		else { print "\n\nCannot access $dc!!!! Exiting program, dc $dc is not accessible.\n\n"; exit }
		
		if ($tmwsearch)
			{
			Win32::NetAdmin::GetServers('',$domain,SV_TYPE_SERVER_NT|SV_TYPE_DOMAIN_CTRL|SV_TYPE_DOMAIN_BAKCTRL,\@winsclients);
			if ($debug) { print "WINS database clients: @winsclients\n\n"};
			foreach $winsclient(@winsclients)
				{
				unless (grep(/$winsclient/,@clients))
					{ push (@clients, $winsclient)	};
				}
			}
				
		foreach $client(@clients)
			{
			$client =~ s/\\//g;
			}
		}
	elsif ($all)
		{
		Win32::NetAdmin::GetServers('',$domain,SV_TYPE_SERVER_NT|SV_TYPE_DOMAIN_CTRL|SV_TYPE_DOMAIN_BAKCTRL,\@clients);
		foreach $client(@clients)
			{
			$client =~ s/\\//g;
			}
		}	
	else	{					# Kick out if no correct options are selected
		usage();
		exit (1);
		};
	if ($sort eq "f")  { @clients = sort(@clients) }
	elsif ($sort eq "r") { @clients = reverse sort(@clients)};
	}

############################################################################

sub getBackupClients
	{
#	use Net::SSH::Perl;
#	my $backuphost = 'nb-ah';
#	my $backuphost = 'madmax.mathworks.com';
#	my $bucmd = 'nbclientlist';
#	my $bucmd = 'ls -lart';
#	my $user = 'jsteele';
#	my $pass = '';
#	my $ssh = Net::SSH::Perl->new($backuphost);
#	$ssh->login($user, $pass);
#	my($stdout, $stderr, $exit) = $ssh->cmd($bucmd);
#	print "\n\n ls list:\n$stdout\n";

# use Net::SSH qw(sshopen2);
#  use strict;
#  my $user = "jsteele";
#  my $host = "madmax.mathworks.com";
#  my $cmd = "ls -lart";
#  sshopen2("$user\@$host", *READER, *WRITER, "$cmd") || die "ssh: $!";
#  while (<READER>) {
#      chomp();
#      print "$_\n";
#  }
#  close(READER);
#  close(WRITER);


	}

############################################################################

sub getDCs
	{
	if ($p->ping($dc) == 1) 
		{
		my $dcsearch = "(&(objectCategory=computer))";	
		my $dcbase = "ou=Domain Controllers,dc=ad,dc=mathworks,dc=com";
		if ($debug) {print "\nDomain Controller Search Base:$dcbase\t\t$dcsearch\n\n"};			
		my $dcldap = new Net::LDAP("$dc", port=>389) or die "$@";
		$dcldap->bind(version=>3);
		my $msg = $dcldap->search(
				base => "$dcbase",
				filter=>"$dcsearch",
				callback => \&callback);
		die $msg->error if $msg->code;
		sub callback 
			{
			my ($search, $entry) = @_;
			$entry = $search->shift_entry;
			my @results=();
			if (defined $entry and $entry->get_value("cn")) 
				{
				$cn = $entry->get_value("cn");
				push @dcs, "$cn";
				}
			}
		if ($debug) {print "\nDomain Controller Search results: @dcs\n"};			
		$dcldap->unbind;
		}
	else { print "\n\nCannot access $dc!!!! Exiting program, dc $dc is not accessible.\n\n"; exit }
	}

############################################################################

sub getVMs
	{
#	use VMware::VIM2Runtime;
#	use VMware::VILib;	
#	$Util::script_version = "1.0";
#	##
#	use VMware::VIRuntime;
#	my ($url, $user_name, $password) = @ARGV; 
#	Vim::login(service_url => $url, user_name => $username, password => $password);
#	##
#	my %opts = (
#	   datacenter => {
#	      type => "=s",
#	      help => "Datacenter name",
#	      required => 1,
#	   },
#	);
#	# read/validate options and connect to the server
#	Opts::add_options(%opts);
#	Opts::parse();
#	Opts::validate();
#	Util::connect();
#	# find datacenter
#	my $datacenter = Opts::get_option('datacenter');
#	my $datacenter_view = Vim::find_entity_view(view_type => 'Datacenter',
#	                                            filter => { name => $datacenter });
#	if (!$datacenter_view) {
#	   die "Datacenter '" . $datacenter . "' not found\n";
#	}
#	# get all hosts under this datacenter
#	my $host_views = Vim::find_entity_views(view_type => 'HostSystem',
#	                                        begin_entity => $datacenter_view);
#	# print hosts
#	my $counter = 1;
#	print "Hosts found:\n";
#	foreach (@$host_views) {
#	   print "$counter: " . $_->name . "\n";
#	   $counter++;
#	}
#	# print vm's
#	$counter = 1;
#	print "\nVM's found:\n";
#	# get all VM's under this datacenter
#	my $vm_views = Vim::find_entity_views(view_type => 'VirtualMachine',
#	                                      begin_entity => $datacenter_view);
#	foreach (@$vm_views) {
#	   print "$counter: " . $_->name . "\n";
#	   $counter++;
#	}
#	# disconnect from the server
#	Util::disconnect();                                  
	}

############################################################################
	
sub getMemoryInfo
	{
	if($memkey = $Registry->{"//$client/HKEY_LOCAL_MACHINE/Hardware/ResourceMap/System Resources/Physical Memory/"})
		{
    		$mem = ceil((unpack 'L*', $memkey->GetValue('.Translated'))[-1] /1024/1024+16);   
		}    #I got this from another script.  I don't know what ceil() does, but it's from the POSIX module.
	}

############################################################################

sub getSoftInfo
	{
	$verRoot = $Registry->{"//$client/HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows NT/CurrentVersion/"};
	if($verRoot->{'CurrentVersion'} eq '5.1')
		{         #OS Version Info
		$OS = "Microsoft XP ";
		}
	elsif($verRoot->{'CurrentVersion'} eq '5.0')
		{         #OS Version Info
		$OS = "Microsoft Windows 2000 ";
		}
	elsif($verRoot->{'CurrentVersion'} eq '5.2')
		{         #OS Version Info
		$OS = "Microsoft Windows 2003 ";
		}
	elsif($verRoot->{'CurrentVersion'} eq '4.0')
		{
		$OS = "Microsoft Windows NT 4.0 ";
		}
	else
		{
		$OS = "Unknown Operating System";
		}
	$servicepack = $verRoot->{'CSDVersion'};
	$OSType = $verRoot->{'CurrentType'};
	$build = $verRoot->{'CurrentBuildNumber'};
	$uninstall = $Registry->{"//$client/HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows/CurrentVersion/Uninstall"};
	@softkeys =keys %{$uninstall};
	foreach $key(@softkeys)			#Check Uninstall keys to enumerate installed software
		{                          
		$softInfo{$key} = $uninstall->{$key}->{'DisplayName'};
		}
	undef $verRoot;
	}

############################################################################

sub getServices
	{
	Win32::Service::GetServices($client,\%svcs);
	@servlist = keys %svcs;
	@servlist = sort @servlist;
	foreach $service(@servlist)
		{
		$shortname = $svcs{$service};
		$services->{$service}->{'NAME'} = $service;
		Win32::Service::GetStatus($client,$shortname,\%srvStat);
		Win32::Lanman::QueryServiceConfig($client, '', $shortname, \%Config);
		if($srvStat{'CurrentState'} == 4)
			{
			$services->{$service}->{'STATUS'} = 'Started';
			} 
		elsif ( $srvStat{'CurrentState'} == 1 ) 
			{
			$services->{$service}->{'STATUS'} = 'Stopped';
			}
		$services->{$service}->{'start'} = $Config{'start'};

		if ($Config{'start'} == 2) { $services->{$service}->{'start'} = 'Automatic'; }
		if ($Config{'start'} == 3) { $services->{$service}->{'start'} = 'Manual'; }
		if ($Config{'start'} == 4) { $services->{$service}->{'start'} = 'Disabled'; }
		$services->{$service}->{'account'} = $Config{'account'};
		}
	undef %svcs;
	undef %srvStat;
	}

############################################################################

sub getIPInfo{
	####  WINDOWS 2000  #### 
	if($Registry->{"//$client/HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows NT/CurrentVersion/CurrentVersion"} eq "5.0"){
		$adapterRoot = $Registry->{"//$client/HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows NT/CurrentVersion/NetworkCards/"};
		$ipRoot = $Registry->{"//$client/HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/Tcpip/Parameters/Interfaces/"};
		@adapterKeys = keys %{$adapterRoot};
		foreach $key(@adapterKeys){
			$name = $adapterRoot->{$key}->{'ServiceName'};
			$service = $adapterRoot->{$key}->{'ServiceName'};
			$nics->{$name}->{'Description'} = $adapterRoot->{$key}->{'Description'};
			$nics->{$name}->{'ServiceName'} = $adapterRoot->{$key}->{'ServiceName'};
			$nics->{$name}->{'Domain'} = $ipRoot->{"$servicename/Domain"};
			$nics->{$name}->{'DNS'} = $ipRoot->{"$servicename/NameServer"};
			if($ipRoot->{"$service/EnableDHCP"} eq "0x00000000"){
				$nics->{$name}->{'IPAddress'} = $ipRoot->{"$service/IPAddress"};
				$nics->{$name}->{'Subnet'} = $ipRoot->{"$service/SubnetMask"};
				$nics->{$name}->{'DHCPEnabled'} = "No";
				$nics->{$name}->{'Gateway'} = $ipRoot->{"$service/DefaultGateway"};
			}elsif($ipRoot->{"$service/EnableDHCP"} eq "0x00000001"){
				$nics->{$name}->{'DHCPServer'} = $ipRoot->{"$service/DhcpServer"};
				$nics->{$name}->{'Subnet'} = $ipRoot->{"$service/DhcpSubnetMask"};
				$nics->{$name}->{'IPAddress'} = $ipRoot->{"$service/DhcpIPAddress"};
				$nics->{$name}->{'DHCPEnabled'} = "Yes";
				$nics->{$name}->{'Gateway'} = $ipRoot->{"$service/DhcpDefaultGateway"};
			}
		}
	####  WINDOWS NT  ####
	}elsif($Registry->{"//$client/HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows NT/CurrentVersion/CurrentVersion"} eq "4.0"){
		$adapterRoot = $Registry->{"//$client/HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows NT/CurrentVersion/NetworkCards/"};
		foreach $key(keys %{$adapterRoot}){
			$name = $adapterRoot->{$key}->{'ServiceName'};
			$service = $adapterRoot->{$key}->{'ServiceName'};
			$nics->{$name}->{'Description'} = $adapterRoot->{$key}->{'Description'};
			$nics->{$name}->{'ServiceName'} = $adapterRoot->{$key}->{'ServiceName'};
			$ipRoot = $Registry->{"//$client/HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/$service/Parameters/Tcpip/"};
			if($ipRoot->{"EnableDHCP"} eq "0x00000000"){
				$nics->{$name}->{'IPAddress'} = $ipRoot->{"IPAddress"};
				$nics->{$name}->{'Subnet'} = $ipRoot->{"SubnetMask"};
				$nics->{$name}->{'DHCPEnabled'} = "No";
				$nics->{$name}->{'Gateway'} = $ipRoot->{"DefaultGateway"};
			}elsif($ipRoot->{"EnableDHCP"} eq "0x00000001"){
				$nics->{$name}->{'DHCPServer'} = $ipRoot->{"DhcpServer"};
				$nics->{$name}->{'Subnet'} = $ipRoot->{"DhcpSubnetMask"};
				$nics->{$name}->{'IPAddress'} = $ipRoot->{"DhcpIPAddress"};
				$nics->{$name}->{'DHCPEnabled'} = "Yes";
				$nics->{$name}->{'Gateway'} = $ipRoot->{"DhcpDefaultGateway"};
			}else{
				warn "DHCP status unknown!";
			}
		}
	####  WINDOWS 2003/XP  #### 
	}elsif(($Registry->{"//$client/HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows NT/CurrentVersion/CurrentVersion"} eq "5.2") or ($Registry->{"//$client/HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows NT/CurrentVersion/CurrentVersion"} eq "5.1")){
		$adapterRoot = $Registry->{"//$client/HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows NT/CurrentVersion/NetworkCards/"};
		foreach $key(keys %{$adapterRoot}){
			$name = $adapterRoot->{$key}->{'ServiceName'};
			$service = $adapterRoot->{$key}->{'ServiceName'};
			$nics->{$name}->{'Description'} = $adapterRoot->{$key}->{'Description'};
			$nics->{$name}->{'ServiceName'} = $adapterRoot->{$key}->{'ServiceName'};
			$ipRoot = $Registry->{"//$client/HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/$service/Parameters/Tcpip/"};
			if($ipRoot->{"EnableDHCP"} eq "0x00000000"){
				$nics->{$name}->{'IPAddress'} = $ipRoot->{"IPAddress"};
				$nics->{$name}->{'Subnet'} = $ipRoot->{"SubnetMask"};
				$nics->{$name}->{'DHCPEnabled'} = "No";
				$nics->{$name}->{'Gateway'} = $ipRoot->{"DefaultGateway"};
			}elsif($ipRoot->{"EnableDHCP"} eq "0x00000001"){
				$nics->{$name}->{'DHCPServer'} = $ipRoot->{"DhcpServer"};
				$nics->{$name}->{'Subnet'} = $ipRoot->{"DhcpSubnetMask"};
				$nics->{$name}->{'IPAddress'} = $ipRoot->{"DhcpIPAddress"};
				$nics->{$name}->{'DHCPEnabled'} = "Yes";
				$nics->{$name}->{'Gateway'} = $ipRoot->{"DhcpDefaultGateway"};
			}else{
				warn "DHCP status unknown!";
			}
		}
	}
	undef $adapterRoot;
	undef $ipRoot;
}

############################################################################

sub getHotFixes 
	{
	$HFRoot = $Registry->{"//$client/HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows NT/CurrentVersion/HotFix/"};
	@hotfixes = keys(%{$HFRoot});
	foreach (@hotfixes) 
		{ 
		chop $_;
		$hotfixes{$_} = $_;
		}
	}

############################################################################

sub getLocalUsers 
	{
	Win32::NetAdmin::GetUsers($client, FILTER_NORMAL_ACCOUNT, \@tempUsers);

	foreach $user (@tempUsers) 
		{
		Win32::AdminMisc::UserGetAttributes($client, $user, $fullName, $password, $passwordAge, $priviledge, $homeDir, $comment, $Flags, $script);
		$Users{$user} = $user;
		$Users->{$user}->{'fullName'} = $fullName;
		$Users->{$user}->{'passwordAge'} = sprintf("%.0f", ($passwordAge / 86400));
		$Users->{$user}->{'privledge'} = $privledge;
		$Users->{$user}->{'homeDir'} = $homeDir;
		$Users->{$user}->{'comment'} = $comment;
		$Users->{$user}->{'script'} = $script;
		undef $privledge;
		undef $homeDir;
		undef $comment;
		undef $script;
		undef $passwordAge;
		undef $fullname;	
		}
	}

############################################################################

sub getLocalGroups 
	{
	undef @{ $Groups{$group} };
	Win32API::Net::LocalGroupEnum($client, \@tempgroups);
	foreach $group (@tempgroups) 
		{
		Win32::NetAdmin::LocalGroupGetMembersWithDomain($client, $group, \@groupMembers);
		$Groups{$group} = $group;
		@{ $Groups{$group} } = @groupMembers;
#		print "Group = ",$group, " ",@groupMembers,"\n";
		}
	}
############################################################################

sub getShares {
	# Added 3 Jan 02 Gary Rogers
	
	Win32::Lanman::NetShareEnum($client, \@Shares);

}

############################################################################

sub getHWInfo{
	$HWRoot = $Registry->{"//$client/HKEY_LOCAL_MACHINE/HARDWARE/DESCRIPTION/"};
	for($i = 0;$HWRoot->{'System/CentralProcessor/'.$i."/"};$i++){    #Processor Info
		$HWInfo{'PROCESSOR_'.($i + 1).'_SPEED'} = $HWRoot->{'System/CentralProcessor/'.$i.'/'}->{'~MHZ'};
		$HWInfo{'PROCESSOR_'.($i + 1).'_VENDOR'} = $HWRoot->{'System/CentralProcessor/'.$i.'/'}->{'VendorIdentifier'};
		$HWInfo{'PROCESSOR_'.($i + 1).'_TYPE'} = $HWRoot->{'System/CentralProcessor/'.$i.'/'}->{'Identifier'};
	}
	$HWInfo{'BIOS_DATE'} = $HWRoot->{'System/'}->{'SystemBiosDate'};  #BIOS Info -- note that the date may appear incorrectly as XX/XX/20.
	$HWInfo{'BIOS_VER'} = $HWRoot->{'System/'}->{'SystemBiosVersion'};#This is the way it shows up in the Registry...can you say Y2K Compliancy?
}

############################################################################

sub displayInfo
	{
	print "     \\\\$client...\n";   #This is the only thing I'm showing on the screen at the moment.
	}

############################################################################

sub printXMLInfo {
	open (OUTFILE, "> $client.xml") or warn "Couldn't open output $!\n";
	
	# Base System Info
	print OUTFILE "<system name='$client'>\n";
	print OUTFILE "<description>unknown</description>\n";
	print OUTFILE "<manufacturer>unknown</manufacturer>\n";
	print OUTFILE "<model>unknown</model>\n";
	print OUTFILE "<serialnumber>unknown</serialnumber>\n";

	# OS Info
	print OUTFILE "<os name='$OS'>\n";
	print OUTFILE "<type>$OSType</type>\n";
	print OUTFILE "<build>$build</build>\n";
	print OUTFILE "<servicepack>$servicepack</servicepack>\n";
	print OUTFILE "</os>\n";
	
	# BIOS Info
	print OUTFILE "<bios>\n";
	print OUTFILE "<date>$HWInfo{'BIOS_DATE'}</date>\n";
	print OUTFILE "<version>$HWInfo{'BIOS_VER'}</version>\n";
	print OUTFILE "</bios>\n";

	# Processor Info
	for ($i = 1; $HWInfo{'PROCESSOR_' . $i . '_SPEED'}; $i++) {
		print OUTFILE "<processor name='$i'>\n";
		print OUTFILE "<speed>" . hex($HWInfo{'PROCESSOR_' . $i . '_SPEED'}) . "</speed>\n";
		print OUTFILE "<vendor>$HWInfo{'PROCESSOR_' . $i . '_VENDOR'}</vendor>\n";
		print OUTFILE "<type>$HWInfo{'PROCESSOR_' . $i . '_TYPE'}</type>\n";
		print OUTFILE "</processor>\n";
	}

	# Memory Info
	print OUTFILE "<memory>\n";
	print OUTFILE "<physical>$mem</physical>\n";
	print OUTFILE "</memory>\n";

	# Logical Drive Info
	foreach $drive(@drives){
		unless(${$drive}{'SPACE'} < 0.01){
			print OUTFILE "<logicaldrive name='$drive'>\n";
			print OUTFILE "<capacity>${$drive}{'CAPACITY'}</capacity>\n";
			print OUTFILE "<freespace>${$drive}{'SPACE'}</freespace>\n";
			print OUTFILE "</logicaldrive>\n";
		}
	}


	# Software Info
	foreach $soft(sort values %softInfo){
		unless(!$soft){
			print OUTFILE "<software name='$soft' />\n";
		}
	}

	# Services
	foreach $service(@servlist){
		print OUTFILE "<service name='$services->{$service}->{'NAME'}'>\n";
		print OUTFILE "<account>$services->{$service}->{'account'}</account>\n";
		print OUTFILE "<startup>$services->{$service}->{'start'}</startup>\n";
		print OUTFILE "<status>$services->{$service}->{'STATUS'}</status>\n";
		print OUTFILE "</service>\n";
	}

	# Network Interfaces
	foreach $nic(keys %{$nics}){
		print OUTFILE "<interface name='" . $nics->{$nic}->{'Description'} . "'>\n";
		print OUTFILE "<dhcp>$nics->{$nic}->{'DHCPEnabled'}</dhcp>\n";
		print OUTFILE "<ip>$nics->{$nic}->{'IPAddress'}</ip>\n";
		print OUTFILE "<subnetmask>$nics->{$nic}->{'Subnet'}</subnetmask>\n";
		print OUTFILE "<gateway>$nics->{$nic}->{'Gateway'}</gateway>\n";
		print OUTFILE "<service>$nics->{$nic}->{'ServiceName'}</service>\n";
		print OUTFILE "<mac>$nics->{$nic}->{'MacAddress'}</mac>\n";
		print OUTFILE "</interface>\n";
	}

	# Hot Fixes section
	foreach $hf(sort values %hotfixes) {
		print OUTFILE "<hotfix name='" . $hf . "' />\n";
	}
	
	# Local Users
	foreach $user (sort values %Users) {
		print OUTFILE "<localuser name='" . $user . "'>\n";
		print OUTFILE "<fullname>$Users->{$user}->{'fullName'}</fullname>\n";
		print OUTFILE "<passwordage>$Users->{$user}->{'passwordAge'}</passwordage>\n";
		print OUTFILE "<privledge>$Users->{$user}->{'privledge'}</privledge>\n";
		print OUTFILE "<homedirectory>$Users->{$user}->{'homeDir'}</homedirectory>\n";
		print OUTFILE "<comment>$Users->{$user}->{'comment'}</comment>\n";
		print OUTFILE "<loginscript>$Users->{$user}->{'script'}</loginscript>\n";
		print OUTFILE "</localuser>\n";
	}
	
	# Local Groups
	foreach $group (sort values %Groups) {
		print OUTFILE "<localgroup name='" . $group . "'>\n";
		foreach $member ( 0 .. $#{ $Groups{$group} } ) {
			print OUTFILE "<groupmember>$Groups{$group}[$member]</groupmember>\n";
		}
		print OUTFILE "</localgroup>\n";
	}
	
	# Shares
	foreach $share (@Shares) {
		print OUTFILE "<share name='" . ${$share}{'netname'} . "'>\n";
		print OUTFILE "<path>" . ${$share}{'path'} . "</path>\n";
		print OUTFILE "</share>\n";
	}
	

	print OUTFILE "</system>\n";
}
	
############################################################################
 
sub printHTMLInfo{
	open (OUTFILE, "> $client.html") or warn "couldn't open output $!\n";
		
	print OUTFILE "<HTML><HEAD><TITLE>Server Config - $client</TITLE></HEAD>\n";
	print OUTFILE "<BODY><H1>$client</H1><TABLE CELLSPACING=0 CELLPADDING=2 WIDTH='100%'><TR><TD>\n";
	
	# OS Info

	print OUTFILE "<H2>Operating System Info<BR><HR></H2>\n";
	print OUTFILE "Operating System: $OS<BR>OS Type: $OSType<BR>Build: $build<BR>Service Pack: $servicepack<BR>\n";

	# Processor Info
	print OUTFILE "<BR><BR></TD></TR><TR><TD>\n";
	print OUTFILE "<H2>Processor Info<BR><HR></H2>\n";
	for($i = 1;$HWInfo{'PROCESSOR_'.$i.'_SPEED'};$i++){
		print OUTFILE "<B>Processor $i</B><BR>Speed: " . hex($HWInfo{'PROCESSOR_'.$i.'_SPEED'}) . "<BR>Vendor: " . $HWInfo{'PROCESSOR_'.$i.'_VENDOR'} . "<BR>Type: " . $HWInfo{'PROCESSOR_'.$i.'_TYPE'} . "<BR>\n";
	}

	# BIOS Info
	print OUTFILE "<BR><BR></TD></TR><TR><TD>\n";
	print OUTFILE "<H2>BIOS Info<BR><HR></H2>\n";
	print OUTFILE "BIOS Date: $HWInfo{'BIOS_DATE'}<BR>BIOS Version: $HWInfo{'BIOS_VER'}\n";

	# Memory Info
	print OUTFILE "<BR><BR></TD></TR><TR><TD>\n";
	print OUTFILE "<H2>Memory Info<BR><HR></H2>\n";
	print OUTFILE "Memory: $mem MB\n";

	# Drive Info
	print OUTFILE "<BR><BR></TD></TR><TR><TD>\n";
	print OUTFILE "<H2>Drive Info<BR><HR></H2>\n";
	foreach $drive(@drives){
		unless(${$drive}{'SPACE'} < 0.01){
			print OUTFILE "$drive\t Capacity: ${$drive}{'CAPACITY'}\t Free Space: ${$drive}{'SPACE'}<BR>\n";
		}
	}

	# Software Info
	print OUTFILE "<BR><BR></TD></TR><TR><TD>\n";
	print OUTFILE "<H2>Software Info<BR><HR></H2>\n";
	foreach $soft(sort values %softInfo){
		unless(!$soft){
			print OUTFILE "Installed Software: $soft<BR>\n";
		}
	}

	# Services
	print OUTFILE "<BR><BR></TD></TR><TR><TD>\n";
	print OUTFILE "<H2>Services Info<BR><HR></H2>\n";
	print OUTFILE "<TABLE>";
	foreach $service(@servlist){
		print OUTFILE "<TR><TD>Service Name: $services->{$service}->{'NAME'}</TD><TD>Status:$services->{$service}->{'STATUS'}</TD></TR>\n";
	}
	print OUTFILE "</TABLE>";

	# Hot Fixes section
	print OUTFILE "<BR><BR></TD></TR><TR><TD>\n";
	print OUTFILE "<H2>HotFix Info<BR><HR></H2>\n";
	print OUTFILE "<TABLE>";
	foreach $hf(sort values %hotfixes) {
		print OUTFILE "<TR><TD>HotFix Name: $hf<BR>\n";
	}
	print OUTFILE "</TABLE>";

	# Local Users
	print OUTFILE "<BR><BR></TD></TR><TR><TD>\n";
	print OUTFILE "<H2>Local User Info<BR><HR></H2>\n";
	print OUTFILE "<TABLE>";
	foreach $user (sort values %Users) {
		print OUTFILE "localuser name=" . $user . "<BR>\n";
		print OUTFILE "fullname $Users->{$user}->{'fullName'}<BR>\n";
		print OUTFILE "passwordage $Users->{$user}->{'passwordAge'}<BR>\n";
		print OUTFILE "privledge $Users->{$user}->{'privledge'}<BR>\n";
		print OUTFILE "homedirectory $Users->{$user}->{'homeDir'}<BR>\n";
		print OUTFILE "comment $Users->{$user}->{'comment'}<BR>\n";
		print OUTFILE "loginscript $Users->{$user}->{'script'}<BR><BR>\n\n";
	}
	print OUTFILE "</TABLE>";
	
	# Local Groups
	print OUTFILE "<BR><BR></TD></TR><TR><TD>\n";
	print OUTFILE "<H2>Local Group Info<BR><HR></H2>\n";
	print OUTFILE "<TABLE>";
	foreach $group (sort values %Groups) {
		print OUTFILE "Localgroup name = '" . $group . "'<BR>\n";
		foreach $member ( 0 .. $#{ $Groups{$group} } ) {
#		foreach $member ($Groups{$group}) {
			print OUTFILE "   Group Members : $Groups{$group}[$member]<BR>\n";
		}
		print OUTFILE "<BR>\n";
	}
	print OUTFILE "</TABLE>";
	
	# Shares
	print OUTFILE "<BR><BR></TD></TR><TR><TD>\n";
	print OUTFILE "<H2>Share Info<BR><HR></H2>\n";
	print OUTFILE "<TABLE>";
	foreach $share (sort @Shares) {
		print OUTFILE "Share name = '" . ${$share}{'netname'} . "'<BR>\n";
		print OUTFILE "Path = " . ${$share}{'path'} . "<BR>\n";
		print OUTFILE "<BR>\n";
	}
	print OUTFILE "</TABLE>";

	# Network Info
	print OUTFILE "<BR><BR></TD></TR><TR><TD>\n";
	print OUTFILE "<H2>Network Info<BR><HR></H2>\n";
	foreach $nic(keys %{$nics}){
		print OUTFILE "<B>$nics->{$nic}->{'Description'}</B><BR>DHCP Enabled: $nics->{$nic}->{'DHCPEnabled'}<BR>IP Address: $nics->{$nic}->{'IPAddress'}<BR>Subnet Mask: $nics->{$nic}->{'Subnet'}<BR>Gateway: $nics->{$nic}->{'Gateway'}<BR>Service: $nics->{$nic}->{'ServiceName'}<BR><BR>\n";
	}

	print OUTFILE "</TD></TR></TABLE></BODY></HTML>\n";

	close OUTFILE;
}

############################################################################

sub printInfo2{
	open (OS, ">>Operating System.csv");
	open (PROCS, ">>Processors.csv");
	open (BIOS, ">>BIOS.csv");
	open (MEMORY, ">>Memory.csv");
	open (DRIVES, ">>Drives.csv");
	open (SOFTWARE, ">>Software.csv");
	open (SERVICES, ">>Services.csv");
	open (NICS, ">>Nics.csv");
		
	# OS Info
	print OS "$client,$OS,$OSType,$build,$servicepack\n";

	# Processor Info
	for($i = 1;$HWInfo{'PROCESSOR_'.$i.'_SPEED'};$i++){
		print PROCS "$client,$i," . hex($HWInfo{'PROCESSOR_'.$i.'_SPEED'}) . "," . $HWInfo{'PROCESSOR_'.$i.'_VENDOR'} . "," . $HWInfo{'PROCESSOR_'.$i.'_TYPE'} . "\n";
	}

	# BIOS Info
	print BIOS "$client,$HWInfo{'BIOS_DATE'},$HWInfo{'BIOS_VER'}\n";

	# Memory Info
	print MEMORY "$client,$mem\n";

	# Drive Info
	foreach $drive(@drives){
		unless(${$drive}{'SPACE'} < 0.01){
			print DRIVES "$client,$drive,${$drive}{'CAPACITY'},${$drive}{'SPACE'}\n";
		}
	}

	# Software Info
	foreach $soft(sort values %softInfo){
		unless(!$soft){
			print SOFTWARE "$client,$soft\n";
		}
	}

	# Services
	foreach $service(@servlist){
		print SERVICES "$client,$services->{$service}->{'NAME'},$services->{$service}->{'STATUS'}\n";
	}

	# Network Info
	foreach $nic(keys %{$nics}){
		print NICS "$client,$nics->{$nic}->{'Description'},DHCP Enabled,$nics->{$nic}->{'DHCPEnabled'},IP Address,$nics->{$nic}->{'IPAddress'},Subnet Mask,$nics->{$nic}->{'Subnet'},Gateway,$nics->{$nic}->{'Gateway'},Service,$nics->{$nic}->{'ServiceName'}\n";
	}

	close (OS);
	close (PROCS);
	close (BIOS);
	close (MEMORY);
	close (DRIVES);
	close (SOFTWARE);
	close (SERVICES);
	close (NICS);

}

############################################################################

sub cleanup{    #If you don't remove these values, there will be garbage in the next machine's data.
	
	undef @{ $Groups{$group} };
	undef @tempgroups;
	%Shares = ();
	%Users = ();
	%tempUsers = ();
	undef *OS;
	undef *build;
	undef *servicepack;
	undef *group;
	undef *member;
	undef *mem;
	undef *tempGroups;
	undef *drives;
	undef *servlist;
	undef *hotfixes;
	undef *tempUsers;
	undef *Shares;
	undef *Users;
	undef *HWInfo;
	undef *softInfo;
	undef %{$nics};
	undef %Groups;
	undef @Groups;
	undef $group;
	undef @groupMembers;
	undef $backupclient;
	close OUTFILE;
}
