Jan et al-
Jan, I have this to you as well as the list because I have noticed your
name on a LARGE number of sites talking about WIN32::OLE and the packages
within it.
I keep getting errors saying that no matter WHAT i have, range (xy) or
Cells (y,x) that Range and Cells errors out as not being a function.
Could you explain to me what is wrong with my headers and or script? I
need to gather information on a large number of systems on a weekly basis
and populate an Excel spread sheet and this would help GREATLY if i could
get it working. when I made something quick and dirty using perl to create
a CSV that was able to give me what i needed to tweak the sorting and
pulling information out, so if you need to get something else to show me
the errors and explain that is ok.
let me know if you would like me to find a host to link psinfo onto. I
believe it is freeware
Thank you in advance,
-Josh
-----code follows-----
#! /usr/bin/perl
use strict;
use warnings;
use Getopt::Long; # used in getting unix-style options
use Win32::OLE qw(in with); # use base OLE
use Win32::OLE::Const 'Microsoft Excel'; # use OLE/Excel
$Win32::OLE::Warn = 3; # die on errors...
use Win32::OLE::Enum;
use Win32::OLE::Variant;
################################################################################
# Purpose:
# This script catalogues the psinfo information on systems, including
patches
# and software. This is sent to an excel spread sheet for easy comparison.
This
# is done to keep on top of what software/patches do not have negative
impacts
# upon SeaChange(tm) systems
#
# This should be kept as both a script and an executable. The executable
should
# be made by the last person to revise the script. The Active State Perl
PDK has
# been used.
#
# Created: 03/02/2006
# Original Author: Josh Perlmutter
# Maintainers:
# Last Revised: 03/09/2006
# Copyright SeaChange International (tm)
################################################################################
my(@comps);
my($comp, $date);
# standard options/revision information variables
# verbose line is 79 chars long w/2 \t
# base to use to add options: -<option>\t\t<use>
my($help, $usage, $verb, $qrev, $rev, $revdat, $modules, $log, $err);
$modules="\tnone as of now\n\n"; $help=0; $qrev=0; $err=0;
$rev="0.0.4"; $revdat="03/09/2006"; $verb=0; $log='';
$usage = <<EOD;
\tFile: $0\tVersion: $rev\tReleased: $revdat\n
This is the $0 file.\n
The options for this file are:
-help This help screen only (overrides all other
options)
-log File to log to (appends if the file exists)
-version List Version and exit (overrides everything but
-help)
-verbose Turn on verbose (useful for debugging errors; call
twice
for extra output)
usage ([] denotes optional argument {} denotes default value
{} denotes option set of which your choice of one is
required):
$0 [-help] [-version] [-verbose]
to debug try: $0 -verb -verb > debug_log.txt\n
EOD
# short explanation of variables:
######
# this section deals with options. it looks for unix-style options passed.
that
# is, <script> -option [value]
# now get the options
GetOptions ('help'=>\$help, 'verbose+'=>\$verb, 'version'=>\$qrev,
'log:s'=>\$log, 'computers:s' => \$comp);
###########################
# arguments ARE required
unless($help || $qrev ||
($log)){
my $necessary = <<EOD;
You must supply at least 1 parameter(s) to run this program. It
needs:
-log log file to log actions to (appends if existing)
Turning on help
EOD
print $necessary;
$help++;
}
#
# now put the options to use...
#
# show usage and exit if asked for
die $usage if $help;
# report version and exit
die "\tFile: $0\tVersion: $rev\tReleased: $revdat\n" if $qrev;
####################################################
## this is a standardized reporting subroutine #####
## it takes a line and a flag for verbose and #####
## reports to a universal file handle (and screen) #
####################################################
sub rep{
# this assumes two passed values,
# first a message
# second a flag for verbose (screen printing)
my $time=localtime().' | ';
print LOG "$time $_[0]\n";
if($_[1]){ print STDOUT "$time $_[0]\n"; }
}
sub getinfo(){
#############################################################################
## this grabs the system information for reporting at the begining of
logs ##
#############################################################################
my $nname=`hostname`; chomp($nname);
my $nos=`ver`; $nos =~ s/\W*(\w.*\])\s.*/$1/;
my $nip=`ipconfig`; $nip =~ s/\D+([\d\.]{7,15})[\D\d]*/$1/;
my $info= <<EOD;
Program Information:
Script: $0
Last Updated: $revdat Version $rev
System Information:
Node Name: $nname
Node OS: $nos
Node IP: $nip
EOD
return $info;
}
sub dbg{
# this is a debugging subroutine that prints things to screen if the
# verbosity level is high enough
my $item=$_[1];
my $dbgpt=$_[0];
while(1){
print "Debug Point: $dbgpt\nItem value:\n$item
\n\t\tShall I continue? (y or n)\n\n";
if(<STDIN> =~ m/^n$/i){ die "\t\t\tyou chose to leave at $dbgpt\n\n";
}
elsif(<STDIN> =~ m/^y$/i){ print "Continuing to next point\n\n"; last;
}
else{ print "response not understood\n"; }
}
}
# start the log
open LOG, ">>$log" or die "cannot open log file";
&rep(&getinfo,$verb);
############################ Below is non-templeted
############################
# make the computer list an array
@comps=split ',', $comp;
# get the date
my @rdate=split ' ', localtime();
$date=$rdate[4].'-'.$rdate[1].'-'.$rdate[2];
if($verb>1){ &rep("$date\n",$verb); }
# set up OLE interaction
# get an active Excel or create a new one
my $Excel = Win32::OLE -> GetActiveObject('Excel.Application')
|| Win32::OLE -> new('Excel.Application', 'Quit');
my $labrep=`cd`;
chomp($labrep);
if (substr($labrep, -1) ne '\\'){ $labrep.='/'; }
$labrep.="Lab_Report_$date.xls";
# does the file exit?
if(-e "$labrep"){
#we are just adding to it, so open it
my $report = $Excel->Workbooks->Open("$labrep");
my $ws = $report -> Worksheets(1);
my $ldate = localtime();
&rep("Examining information gathered from lab computers @ $ldate\n",
$verb);
# start row counter
my $row=2;
# set row counter to continue at the end of what's there
my $ncell = $ws -> Range("A$row") -> {'Value'};
while($ncell =~ m/\w+/i){
$row++; # increment row & V- grab next row's data -V
$ncell = $ws -> Range("A$row") -> {'Value'};
}
#####
# for each node we need to get the information
# and parse it into the excel file
####
foreach my $node (@comps){
# a sub routine defined later in the script is used for simplicity
&populate($node,$row,$ws);
# end the loop increasing the row number
$row++;
}
}else{
# we have to create it, including make the first row
$Excel -> {'Visible'} = 1;
$Excel -> { 'SheetsInNewWorkBook' } = 1;
my $workbook = $Excel -> Workbooks -> Add();
my $ws = $workbook -> Worksheets(1);
$ws -> { 'Name' } = "Lab Report $date";
# set first row titles
$ws -> Range("A1") -> ('Value') = "Node";
$ws -> Cells(1, "B") -> ('Value') = "NAV";
$ws -> Cells(1, "C") -> ('Value') = "Alarms";
$ws -> Cells(1, "D") -> ('Value') = "SNMP";
$ws -> Cells(1, "E") -> ('Value') = "Uptime";
$ws -> Cells(1, "F") -> ('Value') = "Kernel Version";
$ws -> Cells(1, "G") -> ('Value') = "Product Type";
$ws -> Cells(1, "H") -> ('Value') = "Product Version";
$ws -> Cells(1, "I") -> ('Value') = "Service Pack";
$ws -> Cells(1, "J") -> ('Value') = "Kernel Build Number";
$ws -> Cells(1, "K") -> ('Value') = "Registered Organization";
$ws -> Cells(1, "L") -> ('Value') = "Registered Owner";
$ws -> Cells(1, "M") -> ('Value') = "Install Date";
$ws -> Cells(1, "N") -> ('Value') = "Activation Status";
$ws -> Cells(1, "O") -> ('Value') = "IE Version";
$ws -> Cells(1, "P") -> ('Value') = "System Root";
$ws -> Cells(1, "Q") -> ('Value') = "Processors";
$ws -> Cells(1, "R") -> ('Value') = "Processor Speed";
$ws -> Cells(1, "S") -> ('Value') = "Processor Type";
$ws -> Cells(1, "T") -> ('Value') = "Physical Memory";
$ws -> Cells(1, "U") -> ('Value') = "Installed OS Hotfixes";
$ws -> Cells(1, "V") -> ('Value') = "Other Applications";
my $ldate = localtime();
&rep("Examining information gathered from lab computers @ $ldate\n",
$verb);
# start row counter
my $row=2;
foreach my $node (@comps){
# for each node we check the information returned
# a sub routine defined later in the script is used for simplicity
&populate($node,$row,$ws);
# end the loop increasing the row number
$row++;
}
$workbook -> SaveAs($labrep); # save active sheet
}
# save and exit
$Excel -> Workbooks -> Save(); # save file
$Excel -> Workbooks -> Quit(); # leave excel
my $et=locatime();
&rep("program completed at $et.",$verb); # wrap up log
close LOG; # close log
sub populate{
# this is a subroutine to populate cells in a microsoft excel
spreadsheet
# this particular one is made for the compinfo.pl script/executable but
# shuold be easily modified for other scripts
# this routine does ONE row at a time
my $node=$_[0]; # node who's info sheet needs to be picked apart
my $row=$_[1]; # row to add info too
my $ws=$_[2]; # worksheet link
my $err=0; # error marker
# this expects the following row set up:
# A -> Node; B -> NAV; C -> Alarms; D -> SNMP; E -> Uptime;
# F -> Kernel Version; G -> Product Type; H -> Product Version;
# I -> Service Pack; J -> Kernel Build Number; K -> Registered
Organization;
# L -> Registered Owner; M -> Install Date; N -> Activation Status;
# O -> IE Version; P -> System Root; Q -> Processors; R -> Processor
Speed;
# S -> Processor Type; T -> Physical Memory; U -> Installed OS Hotfixes;
# V -> Other Applications;
# set the first cell since that's always going to be the same
$ws -> Cells($row, "A") -> ('Value') = "$node";
my $cmd = "psinfo -h -s \\\\$node";
my @examine = split "\n", `$cmd`;
# noting which couldnt be connected to...
if($examine[6] =~ m/The network path was not found./i ){
$ws -> Cells($row, "B") -> ('Value') = "The network path was not
found.";
}else{
# we need to run through the information to put into the rows
# drop what's before what we need
while (!($examine[0] =~ m/Uptime.*/i)){ shift(@examine); }
while (!($examine[0] =~ m/OS Hot Fix.*/i)){
# now go through a series of if/elsif sections for the rest
# hot fixes and programs will be handled slightly differently though
if($examine[0] =~ m/Uptime:\s+(\w.*)/i){
$ws -> Cells($row, "E") -> ('Value') = "$1";
}elsif($examine[0] =~ m/Kernel version:\s+(\w.*)/i){
$ws -> Cells($row, "F") -> ('Value') = "$1";
}elsif($examine[0] =~ m/Product type:\s+(\w.*)/i){
$ws -> Cells($row, "G") -> ('Value') = "$1";
}elsif($examine[0] =~ m/Product version:\s+(\w.*)/i){
$ws -> Cells($row, "H") -> ('Value') = "$1";
}elsif($examine[0] =~ m/Service pack:\s+(\w.*)/i){
$ws -> Cells($row, "I") -> ('Value') = "$1";
}elsif($examine[0] =~ m/Kernel build number:\s+(\w.*)/i){
$ws -> Cells($row, "J") -> ('Value') = "$1";
}elsif($examine[0] =~ m/Registered organization:\s+(\w.*)/i){
$ws -> Cells($row, "K") -> ('Value') = "$1";
}elsif($examine[0] =~ m/Registered owner:\s+(\w.*)/i){
$ws -> Cells($row, "L") -> ('Value') = "$1";
}elsif($examine[0] =~ m/Install date:\s+(\w.*)/i){
$ws -> Cells($row, "M") -> ('Value') = "$1";
}elsif($examine[0] =~ m/Activation status:\s+(\w.*)/i){
$ws -> Cells($row, "N") -> ('Value') = "$1";
}elsif($examine[0] =~ m/IE version:\s+(\w.*)/i){
$ws -> Cells($row, "O") -> ('Value') = "$1";
}elsif($examine[0] =~ m/System root:\s+(\w.*)/i){
$ws -> Cells($row, "P") -> ('Value') = "$1";
}elsif($examine[0] =~ m/Processors:\s+(\w.*)/i){
$ws -> Cells($row, "Q") -> ('Value') = "$1";
}elsif($examine[0] =~ m/Processor speed:\s+(\w.*)/i){
$ws -> Cells($row, "R") -> ('Value') = "$1";
}elsif($examine[0] =~ m/Processor type:\s+(\w.*)/i){
$ws -> Cells($row, "S") -> ('Value') = "$1";
}elsif($examine[0] =~ m/Physical memory:\s+(\w.*)/i){
$ws -> Cells($row, "T") -> ('Value') = "$1";
}
}
# remove the line starting "OS Hot Fix..."
shift(@examine);
# create a variable for holding the hotfixes
my $hotfixes="\"";
while (!($examine[0] =~ m/Applications.*/i)){
# while hot fixes need to be added. skip blank lines
if($examine[0] =~ m/\w/){
chomp($examine[0]);
$hotfixes .="$examine[0]\n";
}
}
# add the hotfixes
$ws -> Cells($row, "U") -> ('Value') = "$hotfixes";
# remove the line starting "Applications..."
shift(@examine);
my $apps='';
foreach my $app (@examine){
# the rest should all be applications to add
# so we're using a foreach to put them in
# only add lines that are not blank
# there are 3 special lines: NAV, Alarms, and SNMP
if($app =~ m/Symantec AntiVirus (\w+)/i){
$ws -> Cells($row, "B") -> ('Value') = "ver: $1";
}elsif($app =~ m/Alarm/i){
$ws -> Cells($row, "C") -> ('Value') = "Installed";
}elsif($app =~ m/SNMP Informant Agent \(([^\)]+)\) (\w.*)/i){
$ws -> Cells($row, "D") -> ('Value') = "$1 : $2";
}elsif($app =~ m/\s+(\w.*)/i){
$apps .= "$1\n";
}
}
# add the other applications
$ws -> Cells($row, "V") -> ('Value') = "$apps";
}
}
################################################################################
__END__
-----------------------------------------
PLEASE NOTE:
SeaChange International headquarters in Maynard, MA is moving!
Effective March 1, 2006, our new headquarters address will be:
SeaChange International
50 Nagog Park
Acton, MA 01720 USA
All telephone numbers remain the same:
Main Corporate Telephone: 978-897-0100
Customer Service Telephone: 978-897-7300
_______________________________________________
ActivePerl mailing list
[email protected]
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs