Here follows an example script that does just this, showing lists sorted by
server type.
It looks a bit long, but this is mostly due to comments.
If you look at it more closely, it is in fact a simple piece of code
repeated for several
server types.
Could all be easily be rewritten as routine calls.
Large command prompt window display is required for readability of output :
buffer 110 chars min.
Display of workstations is REMed out.
As usual, watch out for text wrap.
Same script is attached as .TXT file for convenience.
<<Win32_Lanman_NetServerEnum.txt>>
#____ SCRIPT START _____
# Win32_Lanman_NetServerEnum.pl - Bruno Bellenger - 2000-2002
# NetServerEnum($server, $domain, $type, \@info)
# Lists all servers of the type SV_TYPE_NT that are visible
# in the domain testdomain. The command will be executed on \\\\$server.
# For more on server types see
# SPECIFY DOMAIN AS FIRST ARGUMENT.
if (@ARGV == 0) {
print <<EOM;
Syntax : $0 DOMAIN
EOM
exit;
}
# The following server types are defined for the NetServerEnum API :
# (=> Method: GetServerType)
# Symbolic Constant Value Description
# SV_TYPE_WORKSTATION &H0000000001 All LAN Manager workstations
# SV_TYPE_SERVER &H0000000002 All LAN Manager servers
# SV_TYPE_SQLSERVER &H0000000004 Any server running with
Microsoft SQL Server
# SV_TYPE_DOMAIN_CTRL &H0000000008 Primary Domain Controller
# SV_TYPE_DOMAIN_BAKCTRL &H0000000010 Backup Domain Controller
# SV_TYPE_TIMESOURCE &H0000000020 Server running the Timesource
service
# SV_TYPE_AFP &H0000000040 Apple File Protocol servers
# SV_TYPE_NOVELL &H0000000080 Novell Services
# SV_TYPE_DOMAIN_MEMBER &H0000000100 LAN Manager 2.x Domain Member
# SV_TYPE_PRINTQ_SERVER &H0000000200 Server sharing print queue
# SV_TYPE_DIALIN_SERVER &H0000000400 Server running dial-in (RAS)
service
# SV_TYPE_XENIX_SERVER &H0000000800 Xenix server
# SV_TYPE_NT &H0000001000 Windows NT/Windows 2000 (either
Workstation or Server)
# SV_TYPE_WFW &H0000002000 Server running Windows for
Workgroups
# SV_TYPE_SERVER_MFPN &H0000004000 Microsoft File and Print for
Netware
# SV_TYPE_SERVER_NT &H0000008000 Windows NT/Windows 2000
non-Domain Controller servers
# SV_TYPE_POTENTIAL_BROWSER &H0000010000 Server that can run the Browser
service
# SV_TYPE_BACKUP_BROWSER &H0000020000 Server running a Browser
service as backup
# SV_TYPE_MASTER_BROWSER &H0000040000 Server running the master
Browser service
# SV_TYPE_DOMAIN_MASTER &H0000080000 Server running the domain
master Browser
# SV_TYPE_SERVER_OSF &H0000100000 OSF (UNIX variant) server
# SV_TYPE_SERVER_VMS &H0000200000 Compaq VMS Server
# SV_TYPE_WINDOWS &H0000400000 Windows 95 or later
# SV_TYPE_DFS &H0000800000 DFS Server
# SV_TYPE_ALTERNATE_XPORT &H0020000000 Alternate type of export
# SV_TYPE_LOCAL_LIST_ONLY &H0040000000 Servers maintained by the
browser
# SV_TYPE_LOCAL_DOMAIN_ENUM &H0080000000 Primary Domain
# SV_TYPE_ALL &H00FFFFFFFF All servers
# SV_TYPE_LOCAL_LIST_ONLY Servers maintained by the browser. See the
following Remarks section.
# SV_TYPE_PRINT Servers sharing print queue
# SV_TYPE_DIALIN Servers running dial-in service
# SV_TYPE_MFPN Microsoft File and Print services for
Netware
# SV_TYPE_DOMAIN_ENUM Primary domains
# SV_TYPE_TERMINALSERVER Terminal Servers
# SV_TYPE_CLUSTER_NT Server clusters available in the domain
# SV_TYPE_CLUSTER_VS_NT Windows XP: Cluster virtual servers
available in the domain
# SV_TYPE_MFPN 0x00004000 Microsoft File and Print for
Netware
# SV_TYPE_SERVER_UNIX 0x00000800
# More info on :
# http://www.rxn.com/services/faq/smb/samba.brow_rev.txt
#=================================================
# SPECIFY THE TARGET DOMAIN AS FIRST ARGUMENT.
#=================================================
# RAW BASECODE :
# if(!Win32::Lanman::NetServerEnum("", "$domain", SV_TYPE_NT, \my @info)) {
# print "Sorry, something went wrong; error: ";
# # get the error code
# print Win32::Lanman::GetLastError();
# print " : $^E\n" ;
# exit 1;
# }
#
# foreach $server (@info) { @keys = keys %$server;
#
#
# foreach $key(@keys)
# {
# print "$key=${$server}{$key}\n";
# }
# }
use Win32::Lanman;
$domain = shift ;
# Get PDCs
print "\n\n\n PRIMARY DOMAIN CONTROLLERS : \n" ;
print "-" x 100, "\n" ;
my @PDC = () ;
if (!Win32::Lanman::NetServerEnum('', "$domain", SV_TYPE_DOMAIN_CTRL,
\@PDC)) {
print "Sorry, something went wrong; error: ";
# get the error code
print Win32::Lanman::GetLastError();
print " : $^E\n" ;
exit 1;
}
foreach (@PDC) {
print " $_->{name}", "." x (24 - length($_->{name})), " -> $_->{comment}\n";
}
# Get BDCs
print "\n\n\n DOMAIN BACKUP CONTROLLERS : \n" ;
print "-" x 100, "\n" ;
my @BDC = () ;
if (!Win32::Lanman::NetServerEnum('', "$domain", SV_TYPE_DOMAIN_BAKCTRL,
\@BDC)) {
print "Sorry, something went wrong; error: ";
# get the error code
print Win32::Lanman::GetLastError();
print " : $^E\n" ;
exit 1;
}
foreach (@BDC) {
print " $_->{name}", "." x (24 - length($_->{name})), " -> $_->{comment}\n";
}
# Get Member Servers
print "\n\n\n DOMAIN MEMBER SERVERS : \n" ;
print "-" x 100, "\n" ;
my @Servers = () ;
if (!Win32::Lanman::NetServerEnum('', "$domain", SV_TYPE_SERVER_NT,
\@SERVERS)) {
print "Sorry, something went wrong; error: ";
# get the error code
print Win32::Lanman::GetLastError();
print " : $^E\n" ;
exit 1;
}
foreach (@SERVERS) {
print " $_->{name}", "." x (24 - length($_->{name})), " -> $_->{comment}\n";
}
# Get list of servers running SQL server :
print "\n\n\n SERVERS RUNNING SQL SERVERS : \n" ;
print "-" x 100, "\n" ;
my @SQLservers = () ;
if (!Win32::Lanman::NetServerEnum('', "$domain", SV_TYPE_SQLSERVER,
\@SQLSERVERS)) {
print "Sorry, something went wrong; error: ";
# get the error code
print Win32::Lanman::GetLastError();
print " : $^E\n" ;
exit 1;
}
foreach (@SQLSERVERS) {
print " $_->{name}", "." x (24 - length($_->{name})), " -> $_->{comment}", "
" x (72 - length($_->{comment})), "[$_->{type}]\n";
}
print "-" x 100, "\n" ;
## Get Workstations
#print "\n\n\n NETWORK MACHINES => i.e ALL WORKSTATIONS (including all
servers too !): \n" ;
#print "-" x 100, "\n" ;
#my @Workstations = () ;
#if (!Win32::Lanman::NetServerEnum('', "$domain", SV_TYPE_WORKSTATION,
\@WORKSTATIONS)) {
# print "Sorry, something went wrong; error: ";
# # get the error code
# print Win32::Lanman::GetLastError();
# print " : $^E\n" ;
# exit 1;
#}
#foreach (@WORKSTATIONS) {
#print " $_->{name}", "." x (24 - length($_->{name})), " ->
$_->{comment}\n";
#}
# Get list of Domains :
print "\n\n\n LIST OF DOMAINS : \n" ;
print "-" x 100, "\n" ;
my @DOMAINS = () ;
if (!Win32::Lanman::NetServerEnum('', "$domain", SV_TYPE_DOMAIN_ENUM,
\@DOMAINS)) {
print "Sorry, something went wrong; error: ";
# get the error code
print Win32::Lanman::GetLastError();
print " : $^E\n" ;
exit 1;
}
foreach (@DOMAINS) {
print " $_->{name}", "." x (24 - length($_->{name})), " -> $_->{comment}\n";
}
print "-" x 100, "\n" ;
#____ SCRIPT END _____
_____________________________________________
Bruno Bellenger
Sr. Network/Systems Administrator
-----Original Message-----
From: Rosenkoetter, Ronald [SMTP:[EMAIL PROTECTED]]
Sent: Tuesday, October 22, 2002 12:49 AM
To: [EMAIL PROTECTED]
Subject: Discovering Servers on the Network
I've written a script that goes out and tells me how many servers
are running a particular service (for licensing purposes). I used to loop
through an allservers.txt file, but I've gotten tired of updating it as we
add new servers (plus it's possible I could miss a server or two).
Instead, I've rewritten my script to use the NetAdmin module to
generate a list of servers for me.
Win32::NetAdmin::GetServers('',$Domain,SV_TYPE_SERVER,\@List);
However, this returns all computers that are running the Server
service... which includes several thousand XP machines. None of the
workstations are running this particular service, so it doesn't skew my
results. The script works, but it takes a good hour or two to run (since I'm
hitting every workstation in the domain with a service query, I only run
this at night).
Is there anyway to return ONLY a list of actual Servers without
hitting each and every machine (to check OS version number for instance).
Where does GetServers get its information anyway?? From a Master Browser??
Any illumination would be most appreciated.
Ron Rosenkoetter
System Engineer
Server Administration & Management
# Win32_Lanman_NetServerEnum.pl - Bruno Bellenger - 2000-2002
# NetServerEnum($server, $domain, $type, \@info)
# Lists all servers of the type SV_TYPE_NT that are visible
# in the domain testdomain. The command will be executed on \\\\$server.
# For more on server types see
# SPECIFY DOMAIN AS FIRST ARGUMENT.
if (@ARGV == 0) {
print <<EOM;
Syntax : $0 DOMAIN
EOM
exit;
}
# The following server types are defined for the NetServerEnum API :
# (=> Method: GetServerType)
# Symbolic Constant Value Description
# SV_TYPE_WORKSTATION &H0000000001 All LAN Manager workstations
# SV_TYPE_SERVER &H0000000002 All LAN Manager servers
# SV_TYPE_SQLSERVER &H0000000004 Any server running with Microsoft SQL
Server
# SV_TYPE_DOMAIN_CTRL &H0000000008 Primary Domain Controller
# SV_TYPE_DOMAIN_BAKCTRL &H0000000010 Backup Domain Controller
# SV_TYPE_TIMESOURCE &H0000000020 Server running the Timesource service
# SV_TYPE_AFP &H0000000040 Apple File Protocol servers
# SV_TYPE_NOVELL &H0000000080 Novell Services
# SV_TYPE_DOMAIN_MEMBER &H0000000100 LAN Manager 2.x Domain Member
# SV_TYPE_PRINTQ_SERVER &H0000000200 Server sharing print queue
# SV_TYPE_DIALIN_SERVER &H0000000400 Server running dial-in (RAS) service
# SV_TYPE_XENIX_SERVER &H0000000800 Xenix server
# SV_TYPE_NT &H0000001000 Windows NT/Windows 2000 (either
Workstation or Server)
# SV_TYPE_WFW &H0000002000 Server running Windows for Workgroups
# SV_TYPE_SERVER_MFPN &H0000004000 Microsoft File and Print for Netware
# SV_TYPE_SERVER_NT &H0000008000 Windows NT/Windows 2000 non-Domain
Controller servers
# SV_TYPE_POTENTIAL_BROWSER &H0000010000 Server that can run the Browser service
# SV_TYPE_BACKUP_BROWSER &H0000020000 Server running a Browser service as
backup
# SV_TYPE_MASTER_BROWSER &H0000040000 Server running the master Browser service
# SV_TYPE_DOMAIN_MASTER &H0000080000 Server running the domain master Browser
# SV_TYPE_SERVER_OSF &H0000100000 OSF (UNIX variant) server
# SV_TYPE_SERVER_VMS &H0000200000 Compaq VMS Server
# SV_TYPE_WINDOWS &H0000400000 Windows 95 or later
# SV_TYPE_DFS &H0000800000 DFS Server
# SV_TYPE_ALTERNATE_XPORT &H0020000000 Alternate type of export
# SV_TYPE_LOCAL_LIST_ONLY &H0040000000 Servers maintained by the browser
# SV_TYPE_LOCAL_DOMAIN_ENUM &H0080000000 Primary Domain
# SV_TYPE_ALL &H00FFFFFFFF All servers
# SV_TYPE_LOCAL_LIST_ONLY Servers maintained by the browser. See the following
Remarks section.
# SV_TYPE_PRINT Servers sharing print queue
# SV_TYPE_DIALIN Servers running dial-in service
# SV_TYPE_MFPN Microsoft File and Print services for Netware
# SV_TYPE_DOMAIN_ENUM Primary domains
# SV_TYPE_TERMINALSERVER Terminal Servers
# SV_TYPE_CLUSTER_NT Server clusters available in the domain
# SV_TYPE_CLUSTER_VS_NT Windows XP: Cluster virtual servers available in the
domain
# SV_TYPE_MFPN 0x00004000 Microsoft File and Print for Netware
# SV_TYPE_SERVER_UNIX 0x00000800
# More info on :
# http://www.rxn.com/services/faq/smb/samba.brow_rev.txt
#=================================================
# SPECIFY THE TARGET DOMAIN AS FIRST ARGUMENT.
#=================================================
# RAW BASECODE :
# if(!Win32::Lanman::NetServerEnum("", "$domain", SV_TYPE_NT, \my @info)) {
# print "Sorry, something went wrong; error: ";
# # get the error code
# print Win32::Lanman::GetLastError();
# print " : $^E\n" ;
# exit 1;
# }
#
# foreach $server (@info) { @keys = keys %$server;
#
#
# foreach $key(@keys)
# {
# print "$key=${$server}{$key}\n";
# }
# }
use Win32::Lanman;
$domain = shift ;
# Get PDCs
print "\n\n\n PRIMARY DOMAIN CONTROLLERS : \n" ;
print "-" x 100, "\n" ;
my @PDC = () ;
if (!Win32::Lanman::NetServerEnum('', "$domain", SV_TYPE_DOMAIN_CTRL, \@PDC)) {
print "Sorry, something went wrong; error: ";
# get the error code
print Win32::Lanman::GetLastError();
print " : $^E\n" ;
exit 1;
}
foreach (@PDC) {
print " $_->{name}", "." x (24 - length($_->{name})), " -> $_->{comment}\n";
}
# Get BDCs
print "\n\n\n DOMAIN BACKUP CONTROLLERS : \n" ;
print "-" x 100, "\n" ;
my @BDC = () ;
if (!Win32::Lanman::NetServerEnum('', "$domain", SV_TYPE_DOMAIN_BAKCTRL, \@BDC)) {
print "Sorry, something went wrong; error: ";
# get the error code
print Win32::Lanman::GetLastError();
print " : $^E\n" ;
exit 1;
}
foreach (@BDC) {
print " $_->{name}", "." x (24 - length($_->{name})), " -> $_->{comment}\n";
}
# Get Member Servers
print "\n\n\n DOMAIN MEMBER SERVERS : \n" ;
print "-" x 100, "\n" ;
my @Servers = () ;
if (!Win32::Lanman::NetServerEnum('', "$domain", SV_TYPE_SERVER_NT, \@SERVERS)) {
print "Sorry, something went wrong; error: ";
# get the error code
print Win32::Lanman::GetLastError();
print " : $^E\n" ;
exit 1;
}
foreach (@SERVERS) {
print " $_->{name}", "." x (24 - length($_->{name})), " -> $_->{comment}\n";
}
# Get list of servers running SQL server :
print "\n\n\n SERVERS RUNNING SQL SERVERS : \n" ;
print "-" x 100, "\n" ;
my @SQLservers = () ;
if (!Win32::Lanman::NetServerEnum('', "$domain", SV_TYPE_SQLSERVER, \@SQLSERVERS)) {
print "Sorry, something went wrong; error: ";
# get the error code
print Win32::Lanman::GetLastError();
print " : $^E\n" ;
exit 1;
}
foreach (@SQLSERVERS) {
print " $_->{name}", "." x (24 - length($_->{name})), " -> $_->{comment}", " " x (72 -
length($_->{comment})), "[$_->{type}]\n";
}
print "-" x 100, "\n" ;
## Get Workstations
#print "\n\n\n NETWORK MACHINES => i.e ALL WORKSTATIONS (including all servers too !):
\n" ;
#print "-" x 100, "\n" ;
#my @Workstations = () ;
#if (!Win32::Lanman::NetServerEnum('', "$domain", SV_TYPE_WORKSTATION,
\@WORKSTATIONS)) {
# print "Sorry, something went wrong; error: ";
# # get the error code
# print Win32::Lanman::GetLastError();
# print " : $^E\n" ;
# exit 1;
#}
#foreach (@WORKSTATIONS) {
#print " $_->{name}", "." x (24 - length($_->{name})), " -> $_->{comment}\n";
#}
# Get list of Domains :
print "\n\n\n LIST OF DOMAINS : \n" ;
print "-" x 100, "\n" ;
my @DOMAINS = () ;
if (!Win32::Lanman::NetServerEnum('', "$domain", SV_TYPE_DOMAIN_ENUM, \@DOMAINS)) {
print "Sorry, something went wrong; error: ";
# get the error code
print Win32::Lanman::GetLastError();
print " : $^E\n" ;
exit 1;
}
foreach (@DOMAINS) {
print " $_->{name}", "." x (24 - length($_->{name})), " -> $_->{comment}\n";
}
print "-" x 100, "\n" ;