And an updated version...
#!c:\perl\bin\perl
# Inventory.pl
#
use strict;
use Win32::TieRegistry(Delimiter=>"/");
use Net::Ping;
################################
## Declare some variables... ##
################################
my (%pcstatus, @PCS);
###########################################################
## Populate %pcstatus with last known query return value ##
## 0 = last query successful ##
## 1 = last query failed ##
###########################################################
dbmopen (%pcstatus, "current", 0666);
################################################
## invs is where we will put our cvs files... ##
################################################
mkdir "invs" or die "unable to make directory invs: $!\n" unless ( -d
+"invs" );
##################################################
## If pcnames.txt exists we want to skip the ##
## Auto discovery process for pcs in the domain ##
##################################################
unless( -f "pcnames.txt" )
{
getActiveMachines();
}
#########################################
## If pcnames.txt exists populate @PCS ##
## with its contents ##
#########################################
if ( -f "pcnames.txt" )
{
my $namesfile;
open $namesfile, "pcnames.txt" or
die "Unable to open \"pcnames.txt\" $!\n";
for (<$namesfile>)
{
chomp;
push @PCS, $_
}
}
###################
## How many PCS? ##
###################
my $PCNUM = scalar(@PCS);
#################################################
## How many successful queries have completed? ##
#################################################
my $ProgressCount = 0;
####################
## Status message ##
####################
print "Getting info for $PCNUM PCs\n\n";
#####################################
## Query each PC for its inventory ##
#####################################
getinfo($_) for (@PCS);
###############################
## Log to the status db ##
###############################
dbmclose(%pcstatus);
#######################################
## Let the user know we are finished ##
#######################################
print "Finished!\nProcessed $ProgressCount of $PCNUM\nPress [ENTER] to
+ quit.";
<stdin>;
################
## Local Subs ##
################
###########
sub getinfo
###########
{
my $PC = shift;
##################################################################
+#
## Set the status to 1 for each PC that does not exist in the db #
+#
##################################################################
+#
if ( ! defined $pcstatus{$PC} ) { $pcstatus{$PC} = 1 }
##################################################################
+###
## Do some error checking - if the last time this file ran
+ ##
## it exited w/ a good status and the file exists we can continue
+ ##
## and not worry about it this time...
+ ##
##################################################################
+###
if ( -e "invs/$PC.csv" && $pcstatus{$PC} == 0 )
{
$ProgressCount++;
print "$PC already processed skipping\n";
print "Processed $ProgressCount of $PCNUM\n\n";
next;
}
#########################
## Die cleanly upon ^C ##
#########################
$SIG{INT} = sub { diecleanly($PC) };
###################################
## is the PC actually available? ##
###################################
print "Pinging $PC\n";
my $p = Net::Ping->new();
unless ( $p->ping($PC) )
{
print "Unable to ping $PC\n\n";
$pcstatus{$PC} = 1;
next;
}
$p->close();
####################
## Status Message ##
####################
print "Getting OS type for $PC\n";
##########################
## Get the machine type ##
##########################
my $WINVER = $Registry->{"//$PC/HKEY_LOCAL_MACHINE/SOFTWARE/Mic
+rosoft/Windows NT/CurrentVersion/ProductName"};
###################################
# We need the windows version... ##
###################################
unless ($WINVER)
{
print "Unknown host type for $PC (possibly MAC or Unix)\n\n";
$pcstatus{$PC} = 1;
next;
}
####################
## Status message ##
####################
print "host is $WINVER\n";
####################################################
## Declare $Outfile - this will be the *.csv file ##
####################################################
my $Outfile;
open $Outfile, ">invs/$PC.csv" or
die "Unable to open $PC.csv\n\n";
####################
## Status Message ##
####################
print "Getting Software info for $PC\n";
##################################################################
+########
## This is the registry hive where all the installed software is l
+isted ##
## If we can access it we need to move on
+ ##
##################################################################
+########
unless ( $Registry->{"//$PC/HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/
+Windows/CurrentVersion/Uninstall"} )
{
print "Unable to get software information for $PC\n\n";
$pcstatus{$PC} = 1;
next;
}
###########################
## Get the software info ##
###########################
my %Uninstall = %{ $Registry->{"//$PC/HKEY_LOCAL_MACHINE/SOFTWARE/
+Microsoft/Windows/CurrentVersion/Uninstall"} };
###############################################################
## Sort throught the hive and pull out only the info we need ##
###############################################################
foreach my $Keys ( sort keys %Uninstall )
{
print $Outfile join(',', &escape($Uninstall{$Keys}->{'/Publish
+er'}),
&escape($Uninstall{$Keys}->{'/Display
+Version'}),
&escape($Uninstall{$Keys}->{'/Install
+Date'}),
&escape($Uninstall{$Keys}->{'/Display
+Name'}),
&escape($Keys))."\n";
}
print $Outfile "Microsoft,$WINVER,,$WINVER,$WINVER,\n";
##############
## Success! ##
##############
$pcstatus{$PC} = 0;
$ProgressCount++;
####################
## Status message ##
####################
print "Processed $ProgressCount of $PCNUM\n";
print "\n";
}
##########
sub escape
##########
{
###############################################
## Garbage collection on registry entries... ##
###############################################
my $entry = shift;
$entry =~ s/,//g;
$entry =~ s/\///g;
return $entry;
}
#####################
sub getActiveMachines
#####################
{
my @machines = qx/net view/;
for ( @machines )
{
next unless ( /^\\\\/ );
s/\\\\//;
my ( $name, @garbage) = split /\s+/ , $_;
push (@PCS, $name);
}
}
##############
sub diecleanly
##############
{
my $PC = shift;
$pcstatus{$PC} = 1;
###############################
## Log to the status db ##
###############################
dbmclose(%pcstatus);
print STDOUT "\n\nProcessed $ProgressCount of $PCNUM\n";
print "Press [ENTER] to quit.";
<stdin>;
die "**** User interruption at $PC ****\n"
}
## EOF ##
Ted
--
"That which we persist in doing becomes easier, not that the task itself has become easier, but that our ability to perform it has improved."
--Ralph Waldo Emerson
|