This will check for 6,6a, or hotfixes, and install hotfixes that are needed.
Hotfixes should be in a directory called 'hotfixes' in the same dir as the
script, and named after the Q article (i.e. Q248399.exe) The MD5
checksumming is disabled, too. Pretty much incomplete, but maybe useful.
Without any warranty, Its a few months out of date; someone took over and
integrated it into out NMS framework.
######################################################
# Hotfix Auditing and Installation Tool
# Chris Bell [EMAIL PROTECTED]
my $vernum=".77"; my $verdate="2.10.01";
######################################################
use Win32::EventLog;
use Win32::EventLog::Message;
use Win32::TieRegistry qw(KEY_READ);
use File::Copy;
#use Digest::MD5;
&Usage if not @ARGV;
ARG: while (@ARGV) {
my $arg=shift;
$arg=~s/\-//;
if ($arg=~/^l$/i) {
$slist=shift;
next ARG;
}
if ($arg=~/^s$/i) {
$svr=shift;
push @slist, $svr;
next ARG;
}
elsif ($arg=~/^i$/i) {
print "Fix Mode Enabled.\n";
$fix=1;
next ARG;
}
elsif ($arg=~/^m$/i) {
print "Show Missing Hotfixes Enabled.\n";
$showmissing=1;
next ARG;
}
elsif ($arg=~/^fd$/i) {
print "File Check (Date/Size) Enabled.\n";
$checkfiles=1;
$checkdate=1;
next ARG;
}
elsif ($arg=~/^fm$/i) {
print "File Check (MD5 Checksum) Enabled.\n";
$checkfiles=1;
$checkmd5=1;
next ARG;
}
elsif ($arg=~/^tw$/i) {
print "Web Server Scan Mode Enabled.\n";
$web=1;
next ARG;
}
elsif ($arg=~/^td$/i) {
print "Domain Controller Scan Mode Enabled.\n";
$dc=1;
next ARG;
}
elsif ($arg=~/^ts$/i) {
print "SQL Server Scan Mode Enabled.\n";
$sql=1;
next ARG;
}
elsif ($arg=~/^c$/i) {
print "Continuous Mode Enabled.\n";
$continue=1;
next ARG;
}
elsif ($arg=~/^6a$/i) {
print "sp6a Check Mode Enabled.\n";
$sp6acheck=1;
next ARG;
}
elsif ($arg=~/^q$/i) {
print "Quiet Mode Enabled.\n";
$quiet=1;
next ARG;
}
elsif ($arg=~/^f$/i) {
$logtofile=1;
$logfile=shift;
print "Logging to file $logfile.\n";
next ARG;
}
elsif ($arg=~/^(h|help)$/i) {
&Usage;
}
else {
print "Invalid option: $arg\n";
&Usage;
}
}
if (defined $slist) {
if (not -e $slist) {
print "Serverlist not found: $slist\n";
&Usage;
}
else {
open (SLIST,"<$slist") or die "Could not open server list ($slist): $!";
@slist=<SLIST>;
close SLIST;
}
}
if (not defined @slist) {
print "No Server list or single server defined: $slist\n\n";
&Usage;
}
my @hotfixes=();
if ($dc) {
@hotfixes=(
"Q243649",
"Q243835",
"Q244599", #"Q238934", # crypt32.dll is replaced by Q263305
"Q246045",
"Q246467",
"Q247869", #"Q245148", # Winlogon is replaced by Q264684
"Q248183",
"Q248399",
"Q249108",
"Q249973",
"Q257870",
"Q259622",
"Q259728",
"Q262694",
"Q263305",
"Q264684",
"Q266433",
"Q269049",
"Q269239",
"Q271652",
"Q274835",
"Q275567", # NEW "Q279336" #,"Q265714"
);
}
else {
@hotfixes=(
"Q243649",
"Q243835",
"Q244599", #"Q238934", # crypt32.dll is replaced by Q263305
"Q246045",
"Q246467",
"Q247869", #"Q245148", # Winlogon is replaced by Q264684
"Q248183",
"Q248399",
"Q249108",
"Q249973",
"Q257870",
"Q259622",
"Q259728",
"Q260205",
"Q262694",
"Q263305",
"Q264684",
"Q266433",
"Q269049",
"Q269239",
"Q271652",
"Q274835",
"Q275567", # NEW "Q279336" #,"Q265714"
);
}
print "Checking against " . scalar @hotfixes . " hotfixes in the list.\n";
my %fileinfo=(
"drivers\\afd.sys" => ["11/16/1999","66,448","4hUDCnxC26R8TOgiwTJtrQ"],
"drivers\\beep.sys" => ["10/29/1999","4,112","0vCoe9l9Y8xd9s/+CuG+AQ"],
#"bone.dll" => ["10/30/2000","10,000","E6Gf/s8Z03eGt0facNmSLw"],
#"browser.dll" => ["10/30/2000","18,192","qgrn+4emj04+Rtee9iftiw"],
"cmd.exe" => ["04/19/2000","208,144","mhV4eiD7xmE5kOSFKlnuFg"],
"crypt32.dll" => ["01/20/2000","371,472","2RpIOQpjYDpZT6aah15urg"],
"drivers\\floppy.sys" => ["10/29/1999","18,928","8Di9GjxvBBl8jtC5pZph1A"],
"inetsrv\\infocomm.dll" =>
["04/24/2000","185,760","llK0gGz3iVsrUi8a7o5vog"],
#"ipx.dll" => ["10/30/2000","42,768","wmShAtfUe3aQTC0MCygg0A"],
"jet500.dll" => ["10/13/1999","458,512","3qcYAzV2ZBzywr1BoRNxYQ"],
"kernel32.dll" => ["08/30/2000","375,056","3JugoBmuJv6tXRCuVPpgsg"],
#"lmmon.dll" => ["11/03/1999","12,560","NgZZer1YSkPFrLkd1NJN5Q"],
"localmon.dll" => ["11/03/1999","18,704","/S6jxiQd8OuwL0cv39wFsA"],
"localspl.dll" => ["11/03/1999","140,560","m5WM7UnIIKVqZPq0cOmD9A"],
#"lpdsvc.dll" => ["03/28/2000","23,312","RGbWbPtwigQseuERmbmmSw"],
#"lprhelp.dll" => ["11/03/1999","13,072","yMHVdqWY6XUY5kDFES0qEw"],
#"lprmon.dll" => ["11/03/1999","21,776","5wSBSivaVPXlKCpZAX2waA"],
"lsasrv.dll" => ["12/06/1999","155,408","MjSVyNg2Y6tW3Jy5LuTOig"],
"msaudite.dll" => ["09/26/2000","19,216","7ieAGB2ZIEYbe+tRUyGElg"],
"msgina.dll" => ["07/25/2000","124,176","0Nlx7S1T6ydcSAtdxlFVHg"],
#"ncp.dll" => ["10/30/2000","203,536","Yw20wOwJk98cMDg2sK+tqA"],
#"netbios.dll" => ["10/30/2000","21,280","4pDbABFGIZsj2cNKiwX6Yg"],
"drivers\\netbt.sys" => ["09/29/2000","124,688","sTeoZKeeYwd6hZj3SFNapg"],
"drivers\\netdtect.sys" =>
["10/29/1999","8,368","vIHEh5Mnx4np1N1mg1SiBw"],
#"nmapi.dll" => ["10/30/2000","63,968","RCxQoi0Yt6HQyUdiaom6UQ"],
#"nntp.dll" => ["10/30/2000","20,752","hrc281UASKLC4X1aInsF6w"],
#"ntkrnlmp.exe" => ["09/26/2000","956,352","O2GZ8DEnOVPB8xBOA5DT2A"],
"ntoskrnl.exe" => ["09/26/2000","935,936","TfDZ7o8ZzAli9zi6ilkh4Q"],
"drivers\\null.sys" => ["10/29/1999","2,800","ZwQUWQQFLfvUbF4jNFH2sg"],
"drivers\\parallel.sys" =>
["11/09/1999","14,960","zhUtBAQCevLuwggA2CjROg"],
"drivers\\parport.sys" =>
["10/29/1999","10,064","wohzLpXkrD6PD9zrsT9Inw"],
#"ppp.dll" => ["10/30/2000","63,760","YRcr8HXQbtKFu2Sd6vxEOg"],
"rdisk.exe" => ["01/02/2000","68,368","D5HW8s4j6b/EKuKFrohq+A"],
#"rdr.sys" => ["05/19/2000","265,712","d2mJkTX+1mvViw9k1tC5rQ"],
#"regacl40.exe" => ["06/23/2000","42,256","8wJNrTqwV6SIqyLgPsz7Gg"],
"riched20.dll" => ["12/23/1999","268,560","BTxeAYlR1sSxeOfgIpz6EA"],
"riched32.dll" => ["12/23/1999","173,328","DRAnvqhwXYifeJdYSJWbcw"],
"rpcrt4.dll" => ["06/02/2000","343,312","XY5SyZwIcOvSnjuZ3ntWg"],
"samsrv.dll" => ["12/06/1999","174,352","xyK06DcbaqEWJdWTqHwnbQ"],
"drivers\\scsiport.sys" =>
["10/29/1999","35,440","peXtzI7APayCmDmBxttSaQ"],
"shell32.dll" => ["06/07/2000","1,280,784","4J0VA3co+kZX5aRkbanooQ"],
#"smb.dll" => ["10/30/2000","168,208","E1+r5Q81ayOmsnBSBG6STw"],
"smss.exe" => ["09/11/2000","40,208","rRUhd4brDLM5ifX0bNbUdw"],
#"snmp.dll" => ["10/30/2000","16,656","N4La5cL24FULkGKtFycniw"],
"spoolss.dll" => ["11/03/1999","48,400","xGKaJK4/yxZKiegLCFfw4w"],
"spoolss.exe" => ["11/03/1999","39,184","RXe+V+3aZGrnR2BihtsEcw"],
"srvsvc.dll" => ["11/22/1999","99,600","jmw26sqFCPAP/ai4YptuoQ"],
"inetsrv\\ssinc.dll" => ["04/24/2000","38,256","jNpOn6CMeE5CAkyfcXFAAw"],
"inetsrv\\sspifilt.dll" =>
["04/24/2000","25,360","OytDpczwkr0ebbOwmUwU9A"],
"tcpcfg.dll" => ["06/23/2000","161,040","X5Qb62bc28LL0Rfj9Sb/YA"],
#"tcpip.dll" => ["10/30/2000","186,128","I1dh8nNnYq6OqB+K/fBnqg"],
"drivers\\tcpip.sys" => ["04/27/2000","174,512","Gpoi5MvyM+k0NRRf43tT0w"],
#"tds.dll" => ["10/30/2000","112,912","QZZerZ+bg1x6kDplaq5xMg"],
#"trail.dll" => ["10/30/2000","21,264","o79Cgm6LoKag+VkE6mAPqw"],
"userinit.exe" => ["07/25/2000","26,896","+nR7prb+91HbUJvC7YKYrw"],
#"vines.dll" => ["10/30/2000","26,896","UTZV5BuQ7AGlBtr1Q53FXw"],
"inetsrv\\w3svc.dll" => ["04/24/2000","228,496","vxJvai9V1lbDhlqaxMg2tg"],
"win32spl.dll" => ["11/03/1999","80,144","2TGf6il7YwqsHZkr9A458g"],
"winlogon.exe" => ["06/05/2000","192,784","mgg1dRCo728txrpaqm2EPg"],
"wshtcpip.dll" => ["10/29/1999","18,704","OcaCgxu0XorJpJgt6VWhA"]
);
if (($continue) and ($fix)) {
ErrPrint("You cannot fix and continue. That will make lots of jobs. Try
again.","ERROR",4);
}
START:;
SERVER: for my $server (@slist) {
chomp $server;
system("title HFCheck - Checking $server");
my $count=0;
my $ping=`ping $server -n 2`;
&ErrPrint("Connect Failed",$server,3,1,$quiet) unless ($ping=~/Reply
from/);
if ($sp6acheck) {
if (not my
$hfkey=$Registry->Connect($server,"LMachine\\Software\\Microsoft\\Windows
NT\\CurrentVersion\\Hotfix\\Q246009",{Access=>KEY_READ})) {
&ErrPrint("sp6a Not Installed",$server,1);
}
next SERVER if ($sp6acheck);
}
HOTFIX: for my $hotfix (@hotfixes) {
if (my
$hfkey=$Registry->Connect($server,"LMachine\\Software\\Microsoft\\Windows
NT\\CurrentVersion\\Hotfix\\$hotfix",{Access=>KEY_READ})) {
my $hfinstalled=$hfkey->GetValue("Installed");
$hfinstalled=~s/^0x0000000//;
if (not $hfinstalled) {
LogPrint("$hotfix,$hfinstalled",$server);
$$server{$hotfix}++;
}
else {
$count++;
}
}
else {
if ($showmissing) {
LogPrint("Needs $hotfix",$server,1);
&GenerateEvent("Hotfix",$server,$hotfix);
}
&CopyHotFix($server,$hotfix) or &ErrPrint("Could not copy
$hotfix",$server,2);
$$server{$hotfix}++;
}
}
my $hfcount=scalar @hotfixes;
if ($count != $hfcount) {
if (($count eq '22') and ($dc) and ($$server{'Q260205'})) {
LogPrint("OK",$server,1) if (not $quiet);
}
else {
LogPrint("ERROR: Hotfix count $count/$hfcount",$server,1);
}
}
else {
LogPrint("OK",$server,1) if (not $quiet);
}
if ($checkfiles) {
for my $file (sort keys %fileinfo) {
my $remfile="\\\\$server\\admin\$\\system32\\$file";
if (-e $remfile) {
if ($checkdate) {
my $filedir=`dir $remfile `;
if
($filedir=~/(\d{2}\/\d{2}\/\d{4})\s+(\d{2}:\d{2}(a|p))\s+(\d+\,\d+\,*\d*)\s+
((\w|\d)+\.(\w|\d)+)/) {
$filedate=$1;
$filesize=$4;
#LogPrint("$remfile,$filedate,$filesize",$server,1);
}
else {
ErrPrint("Could not get file info, regex mismatch:
$filedir",$server);
}
if ($filedate eq $fileinfo{$file}[0]) {
#LogPrint("$file date matches",$server,1);
if ($filesize eq $fileinfo{$file}[1]) {
#LogPrint("$file size matches",$server,1);
}
else {
LogPrint("$file != $fileinfo{$file}[1]
($filesize)",$server,1);
if(copy("files\\$file","\\\\$server\\admin\$\\system32\\$file"))
{&LogPrint("Copied $file",$server,1)}
else {
if(copy("files\\$file","\\\\$server\\admin\$\\hotfixes\\$file"))
{&LogPrint("Copied $file to temp",$server,1)}
else {&ErrPrint("Could not copy $file to temp",$server)}
}
}
}
else {
LogPrint("$file != $fileinfo{$file}[0] ($filedate)",$server,1);
if(copy("files\\$file","\\\\$server\\admin\$\\system32\\$file"))
{&LogPrint("Copied $file",$server,1)}
else {
if(copy("files\\$file","\\\\$server\\admin\$\\hotfixes\\$file")) {
&LogPrint("Copied $file to temp",$server,1);
if (not -e "\\\\$server\\admin\$\\hotfixes\\inuse.exe") {
if
(copy("files\\inuse.exe","\\\\$server\\admin\$\\hotfixes\\inuse.exe")) {
&LogPrint("Copied inuse.exe to temp",$server,1);
}
else {&ErrPrint("Could not copy inuse.exe to
temp",$server)}
}
}
else {&ErrPrint("Could not copy $file to temp",$server)}
}
}
}
elsif ($checkmd5) {
my $filecontents;
{
open FH, $remfile;
local $/=undef;
binmode(FH);
$filecontents=<FH>;
}
$checksum=Digest::MD5::md5_base64($filecontents);
if ($checksum eq $fileinfo{$file}[2]) {
LogPrint("checksum match for $file",$server,1);
}
else {
LogPrint("checksum MISMATCH for $file: $checksum",$server,1);
#if(copy("hotfixes\\files\\$file","\\\\$server\\admin\$\\system32\\$file"))
{&LogPrint("Copied $file",$server,1)}
#else {&ErrPrint("Could not copy $file",$server)}
}
}
else {ErrPrint("Checkfile enabled but no type.. should never
happen",$server,2)}
}
else {
LogPrint("Could not find $file",$server);
}
}
}
&InstallHotFix($server) if $fix;
}
if ($continue) {
print "\n";
goto START;
}
sub CopyHotFix {
my $server=shift;
my $hotfix=shift;
if (not -e "\\\\$server\\c\$\\boot.ini") {
&ErrPrint("Could not connect to share: $^E",$server,3,1);
}
if (not -e "\\\\$server\\admin\$\\hotfixes") {
if (not mkdir("\\\\$server\\admin\$\\hotfixes",755)) {
&ErrPrint("Could not make hotfix directory: $^E",$server,3);
}
}
$hotfix=$hotfix . "i.exe";
if (not -e "\\\\$server\\admin\$\\hotfixes\\$hotfix") {
if (-e "hotfixes\\$hotfix") {
copy("hotfixes\\$hotfix","\\\\$server\\admin\$\\hotfixes\\$hotfix") or
&ErrPrint("Could not copy $hotfix",$server,2);
&LogPrint("Copied $hotfix",$server);
}
else {&ErrPrint("Could not find local hotfix $hotfix",$server,2)}
}
return 1;
}
sub InstallHotFix {
my $server=shift;
my $switch=0;
if (-e "hotfix.cmd") {
unlink "hotfix.cmd" or &ErrPrint("Could not unlink hotfix batch file:
$!",$server,3);
}
for my $hotfix (sort keys %$server) {
if ($$server{$hotfix}) {
#LogPrint("Needs $hotfix",$server,1);
open(HF,">>hotfix$server.cmd") or &ErrPrint("Could not open hotfix
batch file: $!",$server,3);
print HF "\%SYSTEMROOT\%\\hotfixes\\" . $hotfix . "i.exe -z -q -m\n";
close HF;
$switch=1;
#die "check the batch";
}
}
if (-e "hotfix.cmd") {
copy("hotfix.cmd","\\\\$server\\admin\$\\hotfixes\\hotfix.cmd") or
&ErrPrint("Could not copy hotfix.cmd",$server,2);
&LogPrint("Copied hotfix.cmd",$server);
unlink "hotfix.cmd" or &ErrPrint("Could not unlink hotfix batch file:
$!",$server,3);
}
if ($switch) {
my $timeat=&GetTime($server);
my $atjobstr="at \\\\$server $timeat cmd /c
\^\%SYSTEMROOT\^\%\\hotfixes\\hotfix.cmd";
LogPrint($atjobstr,$server);
my $atjob=`$atjobstr`;
if ($atjob=~/Added/) {LogPrint("atjob set at $timeat",$server,1)}
else {print "failed\n"}
}
}
sub GetTime {
my $server=shift;
my $timerem=`net time \\\\$server 2>&1`;
if ($timerem=~/Current time at \\\\$server is \d+\/\d+\/\d+ ((\d+):(\d+))
(AM|PM)/) {
$hour=$2;
$min=$3;
$ampm=$4;
}
$min++;
$min++;
if (($ampm eq 'PM') and ($hour < 12)) {$hour+=12;}
if ($min > 59) {
$min-=60;
$hour++;
}
if ($hour > 23) {$hour-=24}
if (length($min)==1) {$min="0".$min}
my $attime="$hour:$min";
return $attime;
}
sub GetDomain {
my $server=shift;
my $netdom=`netdom query \\\\$server 2>&1`;
if ($netdom=~/is a (member|domain controller) of (.*)\./) {
$domain=$2;
}
else {print "Could not determine domain for $server\n"}
return $domain;
}
sub ErrPrint {
my $msg=shift;
my $server=shift;
my $errlvl=shift;
my $quieterr=shift;
if ($logtofile) {
open (LOG, ">>$logfile") or die "Could not open $logfile for writing:
$!";
print LOG "$server: $msg\n" unless $quieterr;
close LOG;
}
print "$server: $msg\n" unless $quieterr;
if ($errlvl==2) {
next HOTFIX;
}
elsif ($errlvl==3) {
next SERVER;
}
elsif ($errlvl==4) {
exit(0);
}
}
sub GenerateEvent {
my $msg=shift;
my $server=shift;
my $hf=shift;
LogPrint("Generating an event for $server",$server);
Win32::EventLog::Message::RegisterSource( 'System', 'HotFix
Checker',$server );
$event = Win32::EventLog->new( 'HotFix Checker',$server ) or
&ErrPrint("Could not post error to event log",$server,2);
$event->Report(
{
EventID => 70000,
Strings => "*** An important hotfix is missing from the server
($hf). *** Please install the hotfix as soon as possible. ***",
EventType => EVENTLOG_ERROR_TYPE,
}
);
}
sub LogPrint {
my $msg=shift;
my $server=shift;
my $verby;
if ($logtofile) {
open (LOG, ">>$logfile") or die "Could not open $logfile for writing:
$!";
print LOG "$server: $msg\n";
close LOG;
}
print "$server: $msg\n";
}
sub Usage {
print <<EOF;
HFCheck version $vernum modified $verdate
Usage: hfcheck.pl <-l or -s> <options>
-l Serverlist with on server per line
-s Single Server (bare servername w/o the \\\\)
-fd Checks file dates and sizes for hotfix files
-i Installs any hotfixes that are not present
-td Domain Controller Mode (doesn't do the IIS fixes
-tw Web Server Mode (default)
-m Show the actual missing hotfixes instead of the x/x
-c Continuous Mode (for looping querys to see install progress
-q Quiet Mode
-h This crap
Without any options, hfcheck access the registry of the systems
in the list (specified by -l) and checks for installed hotfixes. By
adding the -fd option, hfcheck will compare file size/dates of all
related hotfix files (that are applicable).
The -i option automatically installs any required hotfixes not seen in the
registry.
Email bugs to cbell\@interland.com
EOF
exit(0);
}
> -----Original Message-----
> From: David Rigaudiere [mailto:[EMAIL PROTECTED]]
> Sent: Friday, September 28, 2001 8:18 AM
> To: [EMAIL PROTECTED];
> [EMAIL PROTECTED]
> Subject: Re: Querying Service Pack
>
>
> > Has anyone found a way to tell if a server has SP6 or SP6a on it?
>
> You could check the content of the following key.
>
> [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows
> NT\CurrentVersion\CSDVersion]
>
>
> Regards
> David
>
> --
> David "Sniper" Rigaudiere
> http://paris.mongueurs.net The Paris Perl Mongers
> http://www.perlmonks.org Join the Monastery
> http://sourceforge.net/projects/ncms NCMS project manager
>
>
>
> _______________________________________________
> Perl-Win32-Admin mailing list
> [EMAIL PROTECTED]
> http://listserv.ActiveState.com/mailman/listinfo/perl-win32-admin
>
_______________________________________________
Perl-Win32-Admin mailing list
[EMAIL PROTECTED]
http://listserv.ActiveState.com/mailman/listinfo/perl-win32-admin