#!Perl
use strict;
use Win32::TieRegistry(Delimiter=>"/");
# I have an environmental variable set with computernames
# so I utilize that...
# my $PC = "MYPC";
my $PC = $ENV{COMPUTERNAME};
# Get the Installed software
my %Uninstall = %{ $Registry->{"//$PC/HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows/CurrentVersion/Uninstall"} };
my $Outfile;
open $Outfile, ">$PC.csv" or
die "Unable to open $PC.csv\n";
foreach my $Keys ( sort keys %Uninstall )
{
print $Outfile join(',', &escape($Uninstall{$Keys}->{'/Publisher'}),
&escape($Uninstall{$Keys}->{'/DisplayVersion'}),
&escape($Uninstall{$Keys}->{'/InstallDate'}),
&escape($Uninstall{$Keys}->{'/DisplayName'}),
&escape($Keys))."\n";
}
sub escape
{
my $entry = shift;
$entry =~ s/,//g;
$entry =~ s/\///g;
return $entry;
}
#!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.";
;
################
## 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/Microsoft/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 listed ##
## 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}->{'/Publisher'}),
&escape($Uninstall{$Keys}->{'/DisplayVersion'}),
&escape($Uninstall{$Keys}->{'/InstallDate'}),
&escape($Uninstall{$Keys}->{'/DisplayName'}),
&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.";
;
die "**** User interruption at $PC ****\n"
}
## EOF ##
How to make use of this program in Fedoro core linux. should I need to Install any separate modules for this.
perlmonks.org content © perlmonks.org and jesuashok, tcf03
prlmnks.org © 2006 edmund von der burg (eccles & toad)
v 0.03