Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

inventory.pl

by tcf03 (Deacon)
on Dec 22, 2005 at 20:57 UTC ( [id://518630]=sourcecode: print w/replies, xml ) Need Help??
Category: Utilities
Author/Contact Info
Description: I mangled this script Hardware/Software Inventory to suit my own needs - it gets a list of installed software and outputs it into a comma delimited file. I have some other scripts that I use to parse the csv file.
#!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/Micr
+osoft/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}->{'/DisplayVers
+ion'}), 
                             &escape($Uninstall{$Keys}->{'/InstallDate
+'}), 
                             &escape($Uninstall{$Keys}->{'/DisplayName
+'}), 
                             &escape($Keys))."\n";
}

sub escape 
{
    my $entry = shift;
    $entry =~ s/,//g;
    $entry =~ s/\///g; 
    return $entry;
}
Replies are listed 'Best First'.
Re: inventory.pl
by tcf03 (Deacon) on Dec 28, 2005 at 14:38 UTC
    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
    A reply falls below the community's threshold of quality. You may see it by logging in.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: sourcecode [id://518630]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others perusing the Monastery: (7)
As of 2024-04-18 10:25 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found