# OSVer.pl - get Win32 Operating System Version

use strict;
use Win32;
use Win32::TieRegistry;
use Getopt::Long;
use FindBin qw($Script);

my $VERSION = '1.00';

my %OS = (
	'Type'    => undef,
	'SP'      => undef,
	'Build'   => undef,
	'Ver'     => undef,
	'Computer'=> undef,
);
my %KEYS = (
	'swPath'  => "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion",
	'sysPath' => "SYSTEM\\CurrentControlSet\\Control\\ProductOptions",
);
my %WINVER = (
	'3.51' => '3.51',
	'4.0'  => '4.0',
	'5.0'  => '2000',
	'5.1'  => 'XP',
	'5.2'  => '2003',
	'ServerNT' => 'Server',
	'WinNT'	   => 'Professional',
);


# if user entered help switch, display the Help and exit
my $help;
GetOptions( "help|h|?" => \$help );
Help() and exit(0) if defined $help;


# get the computer name from the command line or use current computer
$OS{'Computer'} = $ARGV[0] || Win32::NodeName();


# connect to registry
my $connect = $Registry->Connect($OS{'Computer'}, "LMachine")
	|| ConnectionFail();
my $swKey   = $connect->Open($KEYS{'swPath'})
	|| ConnectionFail();
my $sysKey  = $connect->Open($KEYS{'sysPath'})
	|| ConnectionFail();


# get product type
my $tmpVal = $sysKey->GetValue("ProductType");
if ( exists $WINVER{$tmpVal} )
{
	$OS{'Type'} = $WINVER{$tmpVal};
}
else 
{ 
	die "Cannot determine the operating system type.\n";
}


# get build number
$OS{'Build'} = $swKey->GetValue("CurrentBuildNumber");


# get os version
$tmpVal = $swKey->GetValue("CurrentVersion");
if ( exists $WINVER{$tmpVal} ) 
{
	$OS{'Ver'} = $WINVER{$tmpVal};
}
else 
{
	die "Cannot determine the operating system version.\n";
}


# get service pack
$OS{'SP'} = $swKey->GetValue("CSDVersion");


print "\U$OS{Computer}\E is running:\n".
      " Microsoft Windows $OS{Ver} $OS{Type} (Build $OS{Build})";
print ", $OS{SP}" if defined $OS{'SP'};
exit(0);



# --- Functions ---
sub ConnectionFail
{
	die "Cannot connect to \U[$OS{Computer}]\E.\n".
		"Check your spelling; verify that the machine is not offline and\n".
		"that you have appropriate permissions to access this machine.\n";
}
sub Help
{
	print "\n$Script, v$VERSION - get Win32 Operating System Version \n", 
		  "by Lior P. Abitbol <labitbol\@cpan.org> \n\n",
		  "Usage: \n",
		  "  $Script [Options] Computer \n\n",
		  "Options: \n",
		  "  -[h]elp -- displays this screen \n\n",
		  "Summary: \n",
		  "  $Script takes a computer name of a Windows computer and returns \n",
		  "  the operating system version. \n\n",
		  "  The local computer name will be used if no computer name is specified.\n";
}


# pod documenation

=head1 NAME

OSVer.pl - get Win32 operating system version


=head1 README

The OSVer program retrieves operating system version, type, build and service
pack level of local or remote Windows-based computers.


=head1 DESCRIPTION

OSVer.pl takes a computer name of a Windows computer and returns
the operating system (OS) version.  The local computer name will be used if 
you do not specify a computer name on the command line.

The program retrieves OS information by connecting to the registry,
so you will need to have administrative permissions to the computer 
that you want to query.

The following illustrates an example of querying a computer named "mypc"
and the expected output:

  c:\osver.pl mypc

Output:
  
  MYPC is running:
   Microsoft Windows 2000 Professional (Build 2195), Service Pack 4

The program has been tested on
  Windows NT 4,
  Windows 2000,
  Windows 2003,
  Windows XP


=head1 PREREQUISITES

PERL 5.6.1 or greater

Modules required:	
	Win32
	Win32::TieRegistry
	Getopt::Long
	FindBin


=head1 COREQUISITES

None


=head1 OSNAMES

MSWin32


=head1 SCRIPT CATEGORIES

Win32
Win32/Utilities


=head1 COPYRIGHT

This program is free software; you can redistribute it and/or modify it under
the same terms as Perl.


=head1 AUTHOR

Lior P. Abitbol (labitbol@cpan.org).


=cut