inventory.pl
tcf03
created: 2005-12-22 15:57:18
#!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;
}

Re: inventory.pl
created: 2005-12-28 09:38:43
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.";
;


################
## 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 ##
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
Re^2: inventory.pl
created: 2005-12-28 10:35:18
Hi,

How to make use of this program in Fedoro core linux. should I need to Install any separate modules for this.

"Keep pouring your ideas"
Re^3: inventory.pl
created: 2005-12-28 10:59:48
Do you want to do an inventory on a linux box? or windows machines from linux?

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

perlmonks.org content © perlmonks.org and jesuashok, tcf03

prlmnks.org © 2006 edmund von der burg (eccles & toad)

v 0.03