#!/usr/bin/perl -w use strict; use warnings; use Switch; use Net::Ping; use Term::ReadKey; # Site specific details are stored in this file require "/usr/local/sbin/wpkg-variables.pl"; # Version number my $version = "v0.1.2"; # Argument flags (set to true if flag is detected) my $arg_u = 0; # username my $arg_p = 0; # password my $arg_m = 0; # machine my $arg_s = 0; # status my $arg_r = 0; # report my $arg_h = 0; # help my $arg_v = 0; # version # Declaring the variables from the other file our ($user, $wpkg_reports); # Variables set by arguments my $arg_username = "administrator"; my $arg_password; my $arg_error; # Array for storing computer names my @computers; # Subroutines for arguments # Sets arg_username to user input and updates arg_u flag sub username { my $pos = shift; if ($ARGV[$pos + 1]) { $arg_u = 1; $arg_username = $ARGV[$pos + 1]; } else { $arg_error .= "Error: Missing Argument (username)\n" } } # Sets arg_password to user input and updates arg_p flag sub password { my $pos = shift; if ($ARGV[$pos + 1]) { $arg_p = 1; $arg_password = $ARGV[$pos + 1]; } else { $arg_error .= "Error: Missing Argument (password)\n" } } # Sets arg_password to user input and updates arg_p flag sub prompt { print "[wpkg-tools] password for ".$arg_username.": "; ReadMode('noecho'); # don't echo chomp($arg_password = ); ReadMode(0); # back to normal print "\n"; $arg_p = 1; } # Sets @computers to user input and updates arg_m flag sub machine { my $pos = shift; if ($ARGV[$pos + 1]) { $arg_m = 1; push(@computers, $ARGV[$pos + 1]); } else { $arg_error .= "Error: Missing Argument (machine)\n" } } # Updates arg_s flag sub status { $arg_s = 1; } # Updates arg_r flag sub report { $arg_r = 1; } # Prints out help information and sets arg_h flag sub help { $arg_h = 1; print "Usage: wpkg-tools [OPTION...]\n"; print "-u, --username Set a non-default username (password required)\n"; print "-p, --password Set a non-default password (string)\n"; print "-P, --prompt Set a non-default password (prompt)\n"; print "-m, --machine Only run command for one specific computer\n"; print "-r, --report Display latest wpkg report\n"; print "-s, --status Display current status of WPKG service\n"; print "-v, --version Display version of wpkg-tools\n"; print "--update Update to latest release of wpkg-tools\n"; print "-h, -?, --help Display help screen\n"; exit 0; } sub version { $arg_v = 1; print "Version ".$version."\n"; exit 0; } sub update { my $gitData = `wget --quiet -O- "https://api.github.com/repos/Link2Twenty/wpkg-tools/releases/latest" | grep '"tag_name"'`; my $latestVersion = substr($gitData, 15, -3); if ($latestVersion eq $version) { print "wpkg-tools is already on the latest version (".$version.")\n"; exit 0; } else { print "wpkg-tools will be updated to version ".$latestVersion."\n"; system('wget --quiet https://raw.githubusercontent.com/Link2Twenty/wpkg-tools/'.$latestVersion.'/wpkg-tools -O /usr/local/sbin/wpkg-tools'); exit 0; } } # Find the longest computer name sub computerNames { my $max = -1; my $max_ref; for (@_) { if (length > $max) { $max = length; $max_ref = \$_; } } $$max_ref } # Hash of arguments my %Args = ( "-u" => "username", "--username" => "username", "-p" => "password", "--password" => "password", "-P" => "prompt", "--prompt" => "prompt", "-m" => "machine", "--machine" => "machine", "-s" => "status", "--status" => "status", "-r" => "report", "--report" => "report", "-h" => "help", "--help" => "help", "-?" => "help", "-v" => "version", "--version" => "version", "--update" => "update", ); # Run argument subroutines foreach my $argnum (0 .. $#ARGV) { if ($Args{$ARGV[$argnum]}) { switch ($Args{$ARGV[$argnum]}) { case "username" {username($argnum)} case "password" {password($argnum)} case "prompt" {prompt()} case "machine" {machine($argnum)} case "status" {status()} case "report" {report()} case "help" {help()} case "version" {version()} case "update" {update()} } } } # If there is an error print it and stop if ($arg_error) { print $arg_error; exit 22; } # If a report is requested get it, must be outside sub routine to allow machine to run after report. if ($arg_r) { my $filename = $arg_m ? $wpkg_reports.'/wpkg-'.uc($computers[0]).'.log' : $wpkg_reports.'/wpkg-*.log'; if( -e $filename || !$arg_m ) { system('awk -v date="$(date +"%Y-%m-%d")" -f /opt/updates/scripts/wpkgreports.awk '.$filename.' | less'); } else { print "Error: No report found for the computer '".$computers[0]."'\n"; exit 2; } exit 0; } # Only run this if a username or password has been presented if ($arg_u || $arg_p) { if (!$arg_p) { prompt(); } $user = $arg_username."%".$arg_password; } # If a machine has not been manually set get the data from the directory if (!$arg_m) { # Open WPKG directory and put the names of the files in an array opendir my $dir, $wpkg_reports or die "Cannot open directory: $!"; my @files = readdir $dir; closedir $dir; # Strip wpkg- and .log from file names and put new string in computer names array foreach my $file (@files) { if ( $file =~ m/wpkg/ ) { push(@computers, substr($file, 5, -4)); } } } # Store the length of the longest name my $nameLength = length(computerNames(@computers)); # Create ping object my $p = Net::Ping->new("icmp"); # For each loop running over computer names foreach my $computer (@computers) { print $computer; print " " x ($nameLength - length($computer)); print "\t"; # Check to see if computer responds to ping if( !$p->ping($computer, 2) ) { print "Ping request timed out\n"; next; } # Check user credentials are correct my $credentialCheck = `net rpc info -I $computer -U $user 2>&1`; if (index($credentialCheck, "NT_STATUS_LOGON_FAILURE") != -1) { print "Supplied user credientals are incorrect\n"; next; } # Check user for Access Denied if (index($credentialCheck, "NT_STATUS_ACCESS_DENIED") != -1) { print "Supplied user is not admin\n"; next; } # Check if service is in the service list my $serviceExists = `net rpc service list -I $computer -U $user | grep "WpkgService"`; if (!$serviceExists) { print "WpkgService is not installed!\n"; next; } # Check current service status my $serviceTest = `net rpc service status WpkgService -I $computer -U $user`; if (index($serviceTest, "running") != -1) { if ($arg_s) { print "WpkgService is running" } else { print "WpkgService is already running" } } else { if ($arg_s) { print "WpkgService is stopped" } else { my $serviceStart = `net rpc service start WpkgService -I $computer -U $user 2>&1`; print "Successfully started WpkgService" } } print "\n" } # Close ping object $p->close();