http://www.perlmonks.org?node_id=140376
Category: Win32 Stuff
Author/Contact Info DaveRoberts@iname.com
Description: This script is used to install and update a number of perl packages using the Perl Package Manager (PPM). The perl packages to be managed, and their repositaries, are defined within the script. When executed the script will report on the status of packages, and attempt to install any that are missing. If any packages have already been installed using the PPM a check will be made and these updated if a later revision is available. Packages not installed by PPM will not be upgraded. The script is useful for ensuring several perl installations have a base set of modules installed.
use Win32;
use PPM;
use Win32::TieRegistry ( Delimiter=>"/", ArrayValues=>1,
    SplitMultis => 1,  AllowLoad => 1,
    qw( :REG_ KEY_READ KEY_WRITE KEY_ALL_ACCESS ));
use Win32::Service;

use constant TRUE     => 1;
use constant FALSE     => 0;

my ($me)   = $0;
$me   =~ s/.*(\\|\/)([a-zA-Z0-9\.]+)$/$2/;
my ($banner) = <<"EOT";

**********************************************************************
+*********

$me 

**********************************************************************
+*********

EOT

print $banner;

my $ASppm   = "http://www.activestate.com/PPMPackages/5.6/";
my $ASppmpl = "http://www.activestate.com/PPMPackages/5.6plus/";

my $ROTHppm = "http://www.roth.net/perl/packages";
my %modules = (
  "Win32::Perms"        =>  $ROTHppm,
  "Win32::GUI"          =>  $ASppm, 
  "Win32::daemon"       =>  $ROTHppm,
  "Win32::AdminMisc"    =>  $ROTHppm,
  "Win32::TieRegistry"  =>  $ASppm,
  "Win32::Process"      =>  $ASppm,
  "Win32::Console"      =>  $ASppm,
  "Win32::NetResource"  =>  $ASppm,
  "Win32::FileSecurity" =>  $ASppm,
  "Win32::EventLog::Message" => $ROTHppm,
  "Getopt::Long"        =>  $ASppm,
  "LWP::UserAgent"      =>  $ASppm,
  "HTTP::Request"       =>  $ASppm,
  "HTTP::Response"      =>  $ASppm,
  "HTTP::Cookies"       =>  $ASppm,
  "HTTP::Headers"       =>  $ASppm,
  "Time::HiRes"         =>  $ASppm,
  "Time::Local"         =>  $ASppm,
  "Net::SMTP"           =>  $ASppm,
  "DB_File"             =>  $ASppm,
  "Win32::Perms"        =>  $ROTHppm,
  "GD"                  =>  $ASppm,
  "GD::Graph"           =>  $ASppmpl . "GDGraph.ppd",
  "Mail-Sendmail"       =>  $ASppmpl,
  );

foreach my $module (keys %modules) {
  my $package = $module;
  $package =~ s/::/-/g;
  my $location = $modules{$module};
  $location = Win32::ExpandEnvironmentStrings($location);
  printf "Module %-25s ",$module;

  my $code = "use $module;";
  eval "$code" ;
  if ( $@ ) {
    print "- to install\n";
    # Try to install....
    if ( $location =~ m/:([\\\/].).*\.ppd$/ ) {                      #
+ If $location identifiles a ppd file
      if(PPM::InstallPackage(package => "$location")) {  
        #use this form for installation
        print  "\t - installed OK\n";
      }else{
        printf "\t - install failed (%s)\n",$PPM::PPMERR;
        printf "                                        \tLocation %s\
+n", $location;
      }
    }else{                                               # otherwise u
+se this
      if(PPM::InstallPackage(package => "$package",
        location => "$location")) {
        print  "\t - installed OK\n";
      }else{
        printf "\t - install failed (%s)\n",$PPM::PPMERR;
        printf "                                        \tLocation %s\
+n", $location;
      }
    }
  }else{
    print "- installed - ";
    my $status = PPM::VerifyPackage(package => $package, upgrade => 0,
+ force => 0);
    if (defined $status) {
      if ($status eq "0") {
        print "module is up to date.\n";
      } else {
        my $status = PPM::VerifyPackage(package => $package,
          upgrade => 1, force => 0);
        if ( $status == 0 ) {
          print "upgraded ok\n";
        }else{
          print "failed to upgrade\n";
        }
      }
    }else{
      # Couldn't find a PPD to compare it with.
      print "$PPM::PPMERR\n";
      print "   (Location: $location)\n" 
        if ( $PPM::PPMERR =~ /Could not locate a PPD file/);
    }
  }
}