#!/usr/bin/perl # Check Warranty v0.5 # # Checks for warranty expiry for a list of hosts # # Copyright (c) 2009, Michael Persson (mickep76@mac.com) # All rights reserved. use strict; use warnings; use LWP::Simple; use DateTime; use DateTime::Format::Strptime; my %hp_pn = ( 'HP xw4600 Workstation' => 'PW480ET' ); my %hp_loc = ( # '10.1.1.*' => 'CH', # '10.1.2.*' => 'US', 'default' => 'CH' ); # Get hosts if(! @ARGV && -t STDIN) { die <<__USAGE__; usage: check_warranty [file] Will take a list of hosts from either STDIN or a file. It will resolve the hosts and then try to access them using SSH to extract manufacturer, serial number and product name using dmidecode. It will then access the manufacturers support page to determine the warranty of the host. Currently it works with IBM, HP and DELL. Using it on HP has some shortcomings because of their support page. It requires you to specify country and product number, neither is possbile to extract from a host in any automated faschion. To work around this issue there is a convertion table for HP product name to product number and country will need to be specified either per subnet or one default location. __USAGE__ } my @hosts = <>; print qq("host","brand","serialno","prodname","prodno","prodtype","expdate","nodays"\n); # Go through all hosts foreach(@hosts) { chomp(); if(/^#/) { next } if(! has_access($_)) { printf STDERR "Can't access host $_\n" } else { get_warranty($_) } }; # Check if user has access to host using public keys instead of password # If you have password on your private key please use ssh-agent for automation sub has_access { my $host = shift; system("ssh root\@$host -o PasswordAuthentication=no true >/dev/null 2>&1"); if($?) { return 0 } return 1 } # Get warranty expiry for host sub get_warranty { my $host = shift; my @outp = `ssh root\@$host "dmidecode"`; if($?) { printf STDERR "Failed to execute dmidecode on $host\n"; return; } my ($brand, $sn, $pname); my $match = 0; foreach(@outp) { if(/System Information/) { $match = 1 } elsif($match && /Manufacturer: (.*)\n/) { $brand = $1 } elsif($match && /Product Name: (.*)\n/) { $pname = $1 } elsif($match && /Serial Number: (.*)\n/) { $sn = $1; last; } } my $date; my $pn = '-'; my $type = '-'; if($brand =~ /Hewlett-Packard/i || $brand =~ /HP/i) { $brand = 'HP'; if(! defined($hp_pn{$pname})) { printf STDERR "Product Name \"$pname\" not in lookup table for HP\n"; return; } $pn = $hp_pn{$pname}; my $ip; map { if(/Address: +([\d\.]+)/) { $ip = $1 } } `nslookup $host`; if($?) { printf STDERR "Failed to execute nslookup\n"; return; } my $loc = $hp_loc{'default'}; map { if($ip =~ /$_/) { $loc = $hp_loc{$_} } } keys %hp_loc; my $url = "http://www11.itrc.hp.com/service/ewarranty/warrantyResults.do?country=$loc&productNumber=$pn&serialNumber1=$sn"; die "Could not get $url\n" unless defined(my $content = get $url); my ($expdate) = $content =~ /End Date.*?(\d\d \w\w\w \d\d\d\d)/s; my $format = DateTime::Format::Strptime->new(pattern => '%d %b %Y'); $date = $format->parse_datetime($expdate); } elsif($brand =~ /IBM/i) { $brand = 'IBM'; $pname =~ /\-\[(\d\d\d\d)/; $type = $1; my $url = "http://www-947.ibm.com/systems/support/supportsite.wss/warranty?action=warranty&brandind=5000008&Submit=Submit&type=$type&serial=$sn"; die "Could not get $url\n" unless defined(my $content = get $url); my ($expdate) = $content =~ /Expiration date.*?(\d\d\d\d-\d\d-\d\d)/s; my $format = DateTime::Format::Strptime->new(pattern => '%Y-%m-%d'); $date = $format->parse_datetime($expdate); } elsif($brand =~ /DELL/i) { $brand = 'DELL'; my $url = "http://support.dell.com/support/topics/global.aspx/support/my_systems_info/details?c=us&l=en&s=gen&~ck=anavml&ServiceTag=$sn"; die "Could not get $url\n" unless defined(my $content = get $url); my ($expdate) = $content =~ /Start Date.*\d+\/\d+\/\d\d\d\d.*\>(\d+\/\d+\/\d\d\d\d)/s; my $format = DateTime::Format::Strptime->new(pattern => '%m/%d/%Y'); $date = $format->parse_datetime($expdate); } if(defined($date)) { printf qq("$host","$brand","$sn","$pname","$pn","$type","%s",%d\n"), $date->strftime('%Y-%m-%d'), $date->delta_days(DateTime->now)->in_units('days') } else { print qq("$host","$brand","$sn","$pname","$pn","$type","-","-"\n) } }