Subversion Repositories camp_sysinfo_client (old)

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 rodolico 1
#! /usr/bin/perl -w
2
 
3
# sysinfo.pl
4
# Author: R. W. Rodolico
5
# Operating System: Win32
6
# Primary client portion of sysinfo system. Will collect information about its current
7
# host and create a report containing the information. This report can then be processed
8
# by process_sysinfo.pl on the collection computer.
9
# output file consists of a key/value pair, with the key in square brackets, example:
10
#  [tag]value
11
# where tag is the name of the function we are looking at (hostname, report date, cpu type)
12
# and value is the associated value.
13
# Also has multi line key/values, which are in the form
14
#   [tag]
15
#   value1
16
#   value2
17
#   [another tag (or end of file)]
18
# where value1 and value2 are considered attributes of tag. This is used where there are multiple
19
# values for a function, such as for installed packages, IP Addresses, hardware lists, and
20
# disk partitions.
21
 
22
#use strict;
23
#use warnings;
24
#no warnings qw(uninitialized);
25
use Win32::SystemInfo;
26
use Win32::DriveInfo;
27
#Optional:  Change the delimiter to '/' to eliminate all of the extra backslashes
28
use Win32::TieRegistry (Delimiter =>  "/");
29
use Mail::Sendmail;
30
 
31
# Following are global variables overridden if configuration file exists
32
my $APPLICATION_ROOT;
33
my $client_name;
34
my $CUSTOM_PACKAGE_FINDER ;
35
my @directoriesToWatch;
36
# only required if reports are sent from process_sysinfo.pl. Not the norm.
37
my $iMailResults = 1; # if 0 (false), ignore following variables
38
my $mailTo;
39
my $mailCC;
40
my $mailBCC;
41
my $mailServer;
42
my $mailServerPort;
43
my $mailFrom;
44
my $mailSubject;
45
 
46
my $VERSION = '1.3.3 win32';
47
 
48
sub getSystemTime {
49
   my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
50
                                                localtime(time);
51
   return sprintf('%4d%02d%02d%02d%02d%02d',$year+1900,$mon+1,$mday,$hour,$min,$sec);
52
}
53
 
54
sub loadConfigurationFile {
55
   my $configuration_file = shift;
56
   unless ( $configuration_file ) { # They didn't give us a configuration filename
57
      # figure out the configuration filename as the base file name, with .conf on the end
58
      use File::Basename;
59
      use Cwd qw(realpath);
60
      my $path = realpath($0); # get my real path
61
      my($filename, $directories, $suffix) = fileparse($path,('.pl')); # break filename apart
62
      $configuration_file = $directories . $filename . '.conf'; # add the .conf
63
   }
64
   open CONFFILE, "<$configuration_file" or die "Can not open configuration file $configuration_file";
65
   my $confFileContents = join( '', <CONFFILE> );
66
   close CONFFILE;
67
   return $confFileContents;
68
}
69
 
70
sub cleanUpString {
71
   my $value = shift;
72
   if ($value) {
73
      $value =~ s/[^[:print:]]+//g;
74
   } else {
75
      $value = '';
76
   }
77
   return $value;
78
}
79
 
80
sub buildNetworkLine {
81
   my ($connection,$ip,$subnet,$gateway,$domain) = @_;
82
   $connection = &cleanUpString($connection);
83
   $ip = &cleanUpString($ip);
84
   $subnet = &cleanUpString($subnet);
85
   $gateway = &cleanUpString($gateway);
86
   $domain = &cleanUpString($domain);
87
   my $line = "$connection\t$ip\t$subnet\t$gateway\t$domain";
88
   return $line;
89
}
90
sub getNetworkInformation {
91
   my $ipInfo =  `ipconfig`;
92
   #print $ipInfo;
93
   my @ipInfo = split( "\n",$ipInfo );
94
   chomp @ipInfo;
95
   my @info = ();
96
   my $connection = '';
97
   my $ip = '';
98
   my $domain = '';
99
   my $subnet_mask = '';
100
   my $gateway = '';
101
   while (my $line = shift @ipInfo) {
102
      if ( $line =~ m/ethernet adapter.*connection +(\d+)/i ) {
103
         if ($connection) {
104
            push @info,&buildNetworkLine($connection,$ip,$subnet_mask,$gateway,$domain);
105
         }
106
         $connection = $1;
107
         $ip = '';
108
         $domain = '';
109
         $subnet_mask = '';
110
         $gateway = '';
111
      } elsif ( $line =~ m/dns suffix.+\: *(.*)/i ) {
112
         $domain = $1;
113
      } elsif ( $line =~ m/ip address.+\: *(.*)/i ) {
114
         $ip = $1;
115
      } elsif ( $line =~ m/subnet mask.+\: *(.*)/i ) {
116
         $subnet_mask = $1;
117
      } elsif ( $line =~ m/default gateway.+\: *(.*)/i ) {
118
         $gateway = $1;
119
      }
120
   }
121
   push @info,&buildNetworkLine($connection,$ip,$subnet_mask,$gateway,$domain);
122
   return "[Network Information]\n" . join( "\n",@info ) . "\n";
123
}
124
 
125
 
126
sub getUptime {
127
   my $string = `net statistics server`;
128
#   my @string = split("\n",$string);
129
   my $hostName;
130
   my $lastReboot;
131
#   while ($string = shift @string) {
132
      if ($string =~ m/Server Statistics for \\\\(.*)/) {
133
         $hostName = $1;
134
      }
135
      if ($string =~ m/Statistics since(.*)/) {
136
         $lastReboot = $1;
137
      }
138
#   }
139
   return ($hostName,$lastReboot);
140
}
141
 
142
sub getSystemInformation {
143
   my @returnValue;
144
   # get memory info
145
   my %hash = (TotalPhys => 0);
146
   use warnings;
147
   no warnings qw(all);
148
   if (Win32::SystemInfo::MemoryStatus(%hash) ) {
149
      push @returnValue,'[memory]' . $hash{'TotalPhys'};
150
   }
151
   my %phash;
152
   Win32::SystemInfo::ProcessorInfo(%phash);
153
#   for (my $i = 0; $i < $phash{NumProcessors}; $i++) {
154
#   print "Speed of processor $i: " . $phash{"Processor$i"}{MHZ} . "MHz";
155
#   }
156
   push @returnValue,'[num_cpu]   ' . $phash{'NumProcessors'};
157
   push @returnValue,'[cpu_speed]' . $phash{"Processor0"}{'MHZ'};
158
   push @returnValue,'[cpu_type]' . $phash{"Processor0"}{'ProcessorName'} . '-' . $phash{"Processor0"}{'VendorIdentifier'};
159
   push @returnValue,'[cpu_sub]' . $phash{"Processor0"}{'Identifier'};
160
     #      for (my $i = 0; $i < $hash{NumProcessors}; $i++) {
161
      #         $outputData{"Processor $i"}{'Identifier'} = $hash{"Processor$i"}{'Identifier'};
162
      #         $outputData{"Processor $i"}{'Speed'} = $hash{"Processor$i"}{'MHZ'};
163
      #         $outputData{"Processor $i"}{'Vendor ID'} = $hash{"Processor$i"}{'VendorIdentifier'};
164
      #         $outputData{"Processor $i"}{'Name'} = $hash{"Processor$i"}{'ProcessorName'};
165
      #      }
166
#   } # if
167
   use warnings qw(all);
168
   #@returnValue .= '[kernel]' . qx(uname -r);
169
   my ($hostname,$lastReboot) = &getUptime;
170
   push @returnValue,"[hostname]$hostname";
171
 
172
   push @returnValue,"[boot]$lastReboot";
173
   return join( "\n",@returnValue) . "\n";
174
}
175
 
176
 
177
sub getDistributionInformation {
178
   my ($MajorVersion, $MinorVersion, $BuildNumber, $PlatformId, $BuildStr) = Win32::DriveInfo::GetVersionEx ( );
179
   my $returnValue = '';
180
   $returnValue .= "[os_name]Windows\n";
181
   $returnValue .= '[os_version]' . $MajorVersion . '.' . $MinorVersion . "\n";
182
   $returnValue .= '[distro_description]' . $PlatformId . "\n";
183
   $returnValue .= '[distro_release]' . $BuildNumber . "\n";
184
   $returnValue .= '[distro_codename]' . $BuildStr . "\n";
185
   return $returnValue;
186
}
187
 
188
sub getDrives {
189
   my @info;
190
   my $STANDARD_DRIVE_TYPE = 3; # standard hard drive partition, see Win32::DriveInfo documentation for more info
191
   my @drives = Win32::DriveInfo::DrivesInUse ( );
192
   foreach my $drive ( @drives ) {
193
      if ( Win32::DriveInfo::DriveType ( $drive ) == $STANDARD_DRIVE_TYPE ) {
194
         my ($SectorsPerCluster,
195
              $BytesPerSector,
196
              $NumberOfFreeClusters,
197
              $TotalNumberOfClusters,
198
              $FreeBytesAvailableToCaller,
199
              $TotalNumberOfBytes,
200
              $TotalNumberOfFreeBytes) = Win32::DriveInfo::DriveSpace($drive);
201
         my ($VolumeName,
202
               $VolumeSerialNumber,
203
               $MaximumComponentLength,
204
               $FileSystemName,
205
               @attr) = Win32::DriveInfo::VolumeInfo ( $drive );
206
         # convert to kilobytes
207
         $TotalNumberOfBytes /= 1024;
208
         $TotalNumberOfFreeBytes /= 1024;
209
         $usedSpace = $TotalNumberOfBytes - $TotalNumberOfFreeBytes;
210
         push @info,"$drive\t$FileSystemName\t$TotalNumberOfBytes\t$usedSpace";
211
      }
212
   }
213
   return "[Disk Info]\n" . join("\n",@info) . "\n";
214
}
215
 
216
sub getPackagesInstalled {
217
   use strict;
218
   use warnings;
219
   no warnings qw(uninitialized);
220
   #%apps will have a list of applications
221
   my @apps;
222
   #$softKey points to the Uninstall key that has
223
   #the Add/Remove Programs information
224
   my $softKey = $Registry-> {"HKEY_LOCAL_MACHINE/Software/Microsoft/Windows/CurrentVersion/Uninstall"};
225
   #Sort and iterate through the keys under Uninstall
226
   foreach(keys %{$softKey}){
227
      #Append the key and DisplayName to the Uninstall key
228
      #Set the result as a key in the %apps hash
229
      #This also removes any duplicate entries
230
      my $name = $softKey-> {"$_/DisplayName"};
231
      next unless $name;
232
      my $version = $softKey->{"$_/DisplayVersion"};
233
      unless ( $version ) {
234
         if ( $softKey->{"$_/VersionMajor"} ) {
235
            $version = $softKey->{"$_/VersionMajor"} . '.' .  $softKey->{"$_/VersionMinor"};
236
         } elsif ( $softKey->{"$_/InstallDate"} ) {
237
            $version = $softKey->{"$_/InstallDate"};
238
         } else {
239
            $version = 'UNK';
240
         }
241
      }
242
      push @apps, "$name\t$version";
243
   }
244
   return "[Packages Installed]\n" . join ("\n", @apps) . "\n";
245
}
246
 
247
sub getHardware {
248
   my @hardwareList;
249
   my $Registry;
250
   use Win32::TieRegistry 0.20 (
251
        TiedRef => \$Registry,  Delimiter => "/",  ArrayValues => 0,
252
        SplitMultis => 1,  AllowLoad => 1,
253
        qw( REG_SZ REG_EXPAND_SZ REG_DWORD REG_BINARY REG_MULTI_SZ
254
            KEY_READ ),
255
    );
256
   my $machKey= $Registry->Open( "HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Enum/PCI", {Access=>KEY_READ(),Delimiter=>"/"} )
257
      or  die "Can't open PCI key: $^E\n";
258
   foreach my $subkey ($machKey->SubKeyNames) {
259
      my $thisVendor = $machKey->Open($subkey);
260
      foreach my $device ($thisVendor->SubKeyNames) {
261
         my $thisDevice = $thisVendor->Open($device);
262
         push @hardwareList,$thisDevice->GetValue( "DeviceDesc" ) . "\t" . $thisDevice->GetValue( "LocationInformation" );
263
      }
264
   }
265
   return "[PCI Info]\n" . join("\n",@hardwareList) . "\n";
266
}
267
 
268
sub sendResults {
269
   $mail{'message'} = shift;
270
   if (sendmail %mail) {
271
      print "Mail sent OK.\n"
272
   } else {
273
     print "Error sending mail: $Mail::Sendmail::error \n"
274
   }
275
   print "\n\$Mail::Sendmail::log says:\n", $Mail::Sendmail::log;
276
}
277
 
278
 
279
my $result;
280
if (@ARGV) {
281
   $result = join("\n", @ARGV) . "\n\n";
282
}
283
 
284
eval( &loadConfigurationFile ); # load the configuration file
285
# parameters are assumed to override configuration file details. If we have parameters
286
# they are of the form varname=value, where value is the new value to assign to varname
287
# the command has a dollar sign prepended (for the variable) and a semi-colon appended
288
# to create a command that may be executed by eval. Thus, this must be a single line
289
# no embedded spaces parameter.
290
#while ($parameter = shift ) {
291
#   eval ( '$' . $parameter . ';');
292
#}
293
 
294
 
295
 
296
$result .= "[sysinfo version]$VERSION\n";
297
$result .= '[report date]' . &getSystemTime . "\n";
298
$result .= "[client name]$client_name\n";
299
$result .= &getDistributionInformation();
300
$result .= &getSystemInformation();
301
$result .= &getNetworkInformation();
302
$result .= &getDrives();
303
$result .= &getHardware();
304
$result .=  &getPackagesInstalled();
305
&sendResults($result);
306
exit 1;
307