#!/usr/bin/perl -w # Louis Abel use strict; # Check for version of dmidecode my $dmi_test = `dmidecode -q 2>/dev/null; echo \$?`; chomp($dmi_test); our $dmi_ver = "rhel8"; our $dmidecode_cmd = "dmidecode -q"; if( $dmi_test eq "1" ) { $dmi_ver = "rhel4"; $dmidecode_cmd = "dmidecode"; } # Figure out number of cores per cpu my $c_cpuinfo = `grep -c processor /proc/cpuinfo`; chomp($c_cpuinfo); my $c_dmidecode = `$dmidecode_cmd | grep -c 'Processor Information'`; chomp($c_dmidecode); # Figure out hyperthreaded cores my $htt; my $lscpu_test = `lscpu 2>/dev/null; echo \$?`; chomp($lscpu_test); if( $lscpu_test eq "127" ) { $htt = "Cannot Detect Threads"; } else { $htt = `lscpu | awk -F':' '/Thread/ {print \$2}'`; chomp($htt); } $htt =~ s/^\s+|\s+$//g; my $cores; if( $c_cpuinfo eq $c_dmidecode ) { $cores = "single core"; } elsif ( $c_cpuinfo > $c_dmidecode ) { my $num_cores = $c_cpuinfo / $c_dmidecode / $htt; $cores = "$num_cores cores"; } else { $cores = "failed to determine number of cores"; } # Parse dmidecode output our %manufacturer; our %cpu; our %memory; our %network; open( FH, "$dmidecode_cmd |") or die "Couldn't run $dmidecode_cmd: $!\n\n"; my ($section, $dim, $dim_size); my $dims_used = 0; my $dims_total = 0; my $eths_section = 0; my $eths_total = 0; while( my $line = ) { chomp($line); # Store section information if( $line =~ /^\S+/ ) { $section = $line; } # Print Bios Information if( $section eq "BIOS Information" || $section =~ /Handle 0x0000/ ) { if( $line =~ /^\s+Version:\s+(.+)\s*$/ ) { $manufacturer{bios} = $1; } } # Print System Information if( $section eq "System Information" || $section =~ /Handle 0x0100/ ) { if( $line =~ /^\s+Manufacturer:\s+(.+)\s*$/ ) { if( $1 =~ /Dell Computer Corporation/ ) { $manufacturer{make} = "Dell Inc."; } else { $manufacturer{make} = $1; } } if( $line =~ /^\s+Product Name:\s+(.+)\s*$/ ) { my $tmp = $1; $tmp =~ s/\s+$//g; $manufacturer{model} = $tmp; } if( $line =~ /^\s+Serial Number:\s+(.+)\s*$/ ) { $manufacturer{serial} = $1; } } # Print Chassis Information if( $section eq "Chassis Information" || $section =~ /Handle 0x0300/ ) { if( $line =~ /^\s+Type:\s+(.+)\s*$/ ) { $manufacturer{chassis_type} = $1; } if( $line =~ /^\s+Height:\s+(.+)\s*$/ ) { $manufacturer{chassis_height} = $1; } } # Print Processor Information if( $section eq "Processor Information" || $section =~ /Handle 0x040/ ) { if( $line =~ /^\s+Version:\s+(.+)\s*$/ ) { my $cpu_model = $1; if( $cpu_model =~ /Not Specified/ ) { $cpu_model = `cat /proc/cpuinfo | grep 'model name' | awk -F: {'print \$2'} | head -n 1`; chomp( $cpu_model ); $cpu_model =~ s/^\s*//g; } $cpu_model =~ s/\s+/ /g; $cpu{physical} = $c_dmidecode; $cpu{virtual} = $c_cpuinfo; $cpu{model} = "$cpu_model ($cores) (Threads: $htt)"; } if( $line =~ /^\s+Speed:\s+(.+)\s*$/ ) { $cpu{speed} = $1; } } # Print Physical Memory Array if( $section eq "Physical Memory Array" || $section =~ /Handle 0x1000/ ) { if( $line =~ /^\s+Error Correction Type:\s+(.+)\s*$/ ) { $memory{error} = $1; } if( $line =~ /^\s+Maximum Capacity:\s+(.+)\s*$/ ) { $memory{max} = $1; } if( $line =~ /^\s+Number Of Devices:\s+(.+)\s*$/ ) { $memory{count} = $1; } } # Print Memory Device if( $section eq "Memory Device" || $section =~ /Handle 0x110/ ) { if( $line =~ /^\s+Locator:\s+(.+)\s*$/ ) { $dim = $1; $dim =~ s/\s+//g; $dims_total++} if( $line =~ /^\s+Size:\s+(.+)\s*$/ ) { $dim_size = $1; } if( $line =~ /^\s+Speed:\s+(.+)\s*$/ ) { next if( $dim_size =~ /No Module Installed/ ); $memory{$dims_total}{location} = $dim; $memory{$dims_total}{size} = $dim_size; $memory{$dims_total}{speed} = $1; $dims_used++; } if( $line =~ /^\s+Type:\s+(.+)\s*$/ ) { $memory{type} = $1; } } # Print Ethernet Devices $network{total} = 0; if( $section =~ /^On Board Device/ || $section =~ /Handle 0x0A00/ || $section =~ /^Onboard Device/ ) { if( $line =~ /^\s+Type:\s+Ethernet\s*$/ ) { $eths_section = 1; $eths_total++; $network{total} = $eths_total; } next if( $eths_section == 0 ); if( $line =~ /^\s+Status:\s+(.+)\s*$/ ) { $network{$eths_total}{status} = $1; } if( $line =~ /^\s+Description:\s+(.+)\s*$/ ) { $network{$eths_total}{desc} = $1; } } } close(FH); # Clean up missing data $manufacturer{chassis_height} = "" unless( defined($manufacturer{chassis_height}) ); $memory{used} = $dims_total; #Print Data print "Make: $manufacturer{make}\n"; print "Model: $manufacturer{model}\n"; print "Serial: $manufacturer{serial}\n"; print "Bios Rev: $manufacturer{bios}\n"; print "Chassis Type: $manufacturer{chassis_type}\n"; print "Chassis Height: $manufacturer{chassis_height}\n"; print "$cpu{physical} x $cpu{model}\n"; print_memory_info(); print_network_info(); #### Functions #### sub print_memory_info { my ($maxsize, $max_unit) = $memory{max} =~ /^\s*(\d+)\s*(\w+)\s*$/; my $dim_count = $memory{count}; my $max_per_dim = $maxsize / $dim_count; my $size_error = ""; my $speed_error = ""; my $common_size; my $common_speed; for( my $i = 1; $i < $dims_used + 1; $i++ ) { my $size = $memory{$i}{size} || 0; my $speed = $memory{$i}{speed} || 0; if( defined($common_size) && $common_size ne $size ) { $size_error = 1; } else { $common_size = $size; } if( defined($common_speed) && $common_speed ne $speed ) { $speed_error = 2; } else { $common_speed = $speed; } } my ($mem_size, $mem_unit) = $common_size =~ /^\s*(\d+)\s*(\w+)\s*$/; my $total_mem_unit = "MB"; if( $mem_unit eq "MB" ) { $total_mem_unit = "GB"; } my $mem_total = ($mem_size * $dims_used) * 1024 ; if( $common_size =~ /(\d+\.\d{2})\d+/ ) { $common_size = $1; } if( $mem_size >= 1024 ) { my $gb_size = $mem_size / 1024; $common_size = "$gb_size GB"; } print "$common_size @ $common_speed x $dims_used = $mem_total $total_mem_unit"; if( $size_error || $speed_error ) { print " $size_error$speed_error"; } print "\n"; if( $max_per_dim =~ /(\d+\.\d{2})\d+/ ) { $max_per_dim = $1; } print "$max_per_dim $max_unit x $dim_count dims = $maxsize $max_unit maximum capacity\n"; print "$memory{type}\n$memory{error}\n"; } sub print_network_info { my $num_devices = $network{total}; for( my $i=1; $i < $num_devices + 1; $i++ ) { print "$network{$i}{desc} [$network{$i}{status}]\n"; } }